Svolgimento della Simulazione Tema d’esame CASA EDITRICE seconda prova di Informatica per l’indirizzo informatico degli Istituti Tecnici Industriali

Svolgimento della Simulazione Tema d’esame CASA EDITRICE seconda prova di Informatica per l’indirizzo informatico degli Istituti Tecnici Industriali

Soluzione Simulazione Tema d’esame 2015 Casa Editrice (59 download )

Testo

Una casa editrice desidera archiviare in un database le informazioni riguardanti gli abbonamenti alle riviste ed ai giornali pubblicati tra il 1995 ed il 2006.
Per ogni abbonato si richiede di memorizzare i dati anagrafici, per ogni abbonamento la data ed il periodo di validità (trimestrale, semestrale, annuale). Bisogna considerare che gli abbonati possono avere abbonamenti anche per più pubblicazioni.
Per ogni giornale o rivista occorre archiviare il titolo, la periodicità (quotidiano, settimanale, mensile, il prezzo dell’abbonamento e gli argomenti trattati.
Inoltre deve essere mantenuto un indice con i titoli dei principali articoli pubblicati ed a ciascun articolo deve essere associata la pubblicazione in cui è comparso.
Dopo aver realizzato lo schema concettuale, logico e fisico della base di dati si realizzino:

  • una pagina index.php contenente un form di login (username e password) ed un link a registrazione.php
  •  una pagina registrazione.php
  •  una pagina landing_page.php

L’utente accede a index.php. Se è già registrato effettua il login ed accede a landing_page.php. Se non è registrato effettua la registrazione e, se questa è andata a buon fine, viene reindirizzato a login.php

Nella landing_page (completa di CSS) inserire una barra laterale contenente 8 pulsanti corrispondenti alle seguenti 8 query:

  • Q1: Dato il titolo di una pubblicazione, ricercare gli articoli pubblicati in un determinato anno;
  • Q2: Dato il titolo di una pubblicazione, ricercare gli abbonati annuali;
  • Q3: Dato il nominativo di un abbonato, stabilire a quante riviste è abbonato;
  • Q4: Dato un argomento, elencare le pubblicazioni in cui è trattato;
  • Q5: Riportare per ogni pubblicazione il numero di abbonamenti;
  • Q6: Visualizzare i giornali con almeno 5000 abbonati annuali;
  • Q7: Dati i titoli di due pubblicazioni, visualizzarne gli abbonati comuni;
  • Q8: Dato il titolo di una pubblicazione, elencare le pubblicazioni che trattano i suoi stessi argomenti

La pressione di un pulsante deve consentire la visualizzazione del risultato della query. Fare attenzione ai casi in cui si richiede un form prima di visualizzare i risultati.

La landing_page deve avere un pulsante “Logout” che reindirizza alla pagina di login.php

Soluzione

Analisi della realtà di riferimento

Lo scopo di questa guida è quello di realizzare l’interfaccia Web che consente la visualizzazione dei dati e l’interazione con il database realizzando la parte backend in PHP e la parte frontend in HTM-CSS.

Nello specifico ci proponiamo di non sviluppare nel dettaglio lo schema concettuale e logico (ipotizzando di aver già provveduto) ma di concentrarci sullo schema fisico per la creazione delle tabelle del database e sull’interfaccia richiesta.

Creazione delle tabelle

Partiamo con la creazione del database e della prima tabella: pubblicazione:

  • far partire XAMPP
  • avviare Apache e MySQL
  • aprire l’interfaccia PHPMyAdmin
  • nella scheda SQL inseriamo il seguente codice che crea il database “consorzio” e crea la tabella “caseifici”:
CREATE DATABASE casaeditrice_Soluzione;

USE casaeditrice_Soluzione;

CREATE TABLE Pubblicazione (
    codPubblil INT PRIMARY KEY,  -- Codice identificativo della pubblicazione
    TitoloP VARCHAR(255),         -- Titolo della pubblicazione
    Periodicita ENUM('Quotidiano', 'Settimanale', 'Mensile'),  -- Periodicità come ENUM
    Tipo ENUM('Giornale', 'Rivista'),  -- Tipo come ENUM
    CostoMensile DECIMAL(10, 2),      -- Costo per abbonamento mensile
    CostoTrimestrale DECIMAL(10, 2),  -- Costo per abbonamento trimestrale
    CostoAnnuale DECIMAL(10, 2)       -- Costo per abbonamento annuale
);

Adesso possiamo popolare la tabella inserendo, ad esempio, 20 record:

INSERT INTO Pubblicazione (codPubblil, TitoloP, Periodicita, Tipo, CostoMensile, CostoTrimestrale, CostoAnnuale)
VALUES
(1, 'Giornale Nazionale', 'Quotidiano', 'Giornale', 5.00, 15.00, 50.00),
(2, 'Rivista Settimanale', 'Settimanale', 'Rivista', 7.00, 20.00, 70.00),
(3, 'La Stampa Oggi', 'Quotidiano', 'Giornale', 6.00, 18.00, 60.00),
(4, 'Mondo Rivista', 'Mensile', 'Rivista', 10.00, 25.00, 100.00),
(5, 'News Today', 'Quotidiano', 'Giornale', 4.00, 12.00, 40.00),
(6, 'Tecnologia Facile', 'Mensile', 'Rivista', 12.00, 30.00, 120.00),
(7, 'Sport in Diretta', 'Settimanale', 'Giornale', 3.50, 10.00, 35.00),
(8, 'Arte e Cultura', 'Mensile', 'Rivista', 11.00, 28.00, 110.00),
(9, 'Politica 24', 'Quotidiano', 'Giornale', 6.50, 17.00, 65.00),
(10, 'Viaggi e Destinazioni', 'Mensile', 'Rivista', 14.00, 35.00, 140.00),
(11, 'Giornale Economico', 'Quotidiano', 'Giornale', 8.00, 20.00, 80.00),
(12, 'Rivista di Moda', 'Settimanale', 'Rivista', 7.00, 18.00, 65.00),
(13, 'Giornale Locale', 'Quotidiano', 'Giornale', 4.00, 10.00, 40.00),
(14, 'Rivista Scientifico', 'Mensile', 'Rivista', 16.00, 40.00, 160.00),
(15, 'Cronaca e Notizie', 'Quotidiano', 'Giornale', 8.50, 22.00, 85.00),
(16, 'Auto e Motori', 'Settimanale', 'Rivista', 9.50, 26.00, 95.00),
(17, 'Giornale di Tecnologia', 'Quotidiano', 'Giornale', 5.50, 14.00, 55.00),
(18, 'Rivista di Cucina', 'Mensile', 'Rivista', 13.00, 32.00, 130.00),
(19, 'Politica Internazionale', 'Settimanale', 'Giornale', 9.00, 24.00, 90.00),
(20, 'Fotografia e Design', 'Mensile', 'Rivista', 14.50, 36.00, 145.00);

Proseguiamo con la creazione della tabella Articolo. Il testo dice di mantenere un indice per cui impostiamo un campo con un valore da 1 a 10, che l’archivio deve contenere articoli tra il 1995 e il 2006 e che deve essere legato al numero di pubblicazione quindi:

CREATE TABLE Articolo (
    codA INT PRIMARY KEY,                  -- Identificatore univoco dell'articolo
    titolo_articolo VARCHAR(255),           -- Titolo dell'articolo
    contenuto TEXT,                         -- Contenuto dell'articolo
    annoPubbl INT CHECK (annoPubbl BETWEEN 1995 AND 2006), -- Anno di pubblicazione tra 1995 e 2006
    indice INT CHECK (indice BETWEEN 1 AND 10),  -- Indice da 1 a 10
    codPubblil INT,                         -- Codice della pubblicazione (relazione con la tabella Pubblicazione)
    FOREIGN KEY (codPubblil) REFERENCES Pubblicazione(codPubblil)  -- Relazione con la pubblicazione
);

Procediamo ora a popolare la tabella in coerenza con quanto scritto nella tabella pullicazioni. Inseriamo 5 articoli per ogni pubblicazione (qui l’esempio per le prime 2 pubblicazioni):

-- Articoli per la pubblicazione 'Giornale Nazionale' (codPubblil = 1)
INSERT INTO Articolo (codA, titolo_articolo, contenuto, annoPubbl, indice, codPubblil)
VALUES
(1, 'Tecnologia del Futuro', 'Articolo sul futuro della tecnologia.', 1995, 10, 1),
(2, 'Innovazioni nel Digitale', 'Esplorazione delle ultime innovazioni digitali.', 1996, 9, 1),
(3, 'Intelligenza Artificiale', 'Approfondimento sull\'AI e le sue applicazioni future.', 1999, 8, 1),
(4, 'Il Futuro della Comunicazione', 'Come la comunicazione cambierà nei prossimi anni.', 2003, 7, 1),
(5, 'Cybersecurity', 'Sicurezza informatica nel futuro.', 2005, 6, 1);

-- Articoli per la pubblicazione 'Rivista Settimanale' (codPubblil = 2)
INSERT INTO Articolo (codA, titolo_articolo, contenuto, annoPubbl, indice, codPubblil)
VALUES
(6, 'Le Tendenze della Moda', 'Analisi delle tendenze della moda nel 1996.', 1996, 10, 2),
(7, 'Cultura Popolare', 'Studio sul cambiamento della cultura popolare.', 1997, 9, 2),
(8, 'Moda e Tecnologia', 'Come la tecnologia sta influenzando il mondo della moda.', 1999, 8, 2),
(9, 'Icone della Moda', 'Le icone della moda degli ultimi anni.', 2002, 7, 2),
(10, 'Moda e Stile', 'L\'importanza dello stile nella moda moderna.', 2005, 6, 2);

Ora procediamo alla creazione della tabella Argomento che conterrà tutti gli argomenti trattati. Se ogni argomento può essere trattato in uno o più articoli, e ogni argomento può essere associato a una sola pubblicazione (ma può apparire in più articoli all’interno di quella pubblicazione o anche in articoli di altre pubblicazioni), allora la relazione tra argomento, pubblicazione e articolo si stabilisce con la creazione di due tabelle: Agomento e Argomento_articolo

Procediamo con la creazione di Argomento:

CREATE TABLE Argomento (
    codArg INT PRIMARY KEY AUTO_INCREMENT,  -- Codice univoco per l'argomento
    descrizione VARCHAR(255) NOT NULL,      -- Descrizione dell'argomento
    codPubblil INT,                        -- Chiave esterna riferita alla pubblicazione
    CONSTRAINT fk_pubblil FOREIGN KEY (codPubblil) REFERENCES Pubblicazione(codPubblil)  -- Legame con la pubblicazione
);

E ora la tabella Argomento_articolo:

CREATE TABLE Argomento_Articolo (
    codArg INT,                             -- Chiave esterna riferita all'argomento
    codA INT,                               -- Chiave esterna riferita all'articolo
    PRIMARY KEY (codArg, codA),             -- Combinazione delle chiavi esterne come chiave primaria
    CONSTRAINT fk_argomento FOREIGN KEY (codArg) REFERENCES Argomento(codArg),  -- Legame con Argomento
    CONSTRAINT fk_articolo FOREIGN KEY (codA) REFERENCES Articolo(codA)  -- Legame con Articolo
);

Popoliamo ora le due tabelle. In basso un esempio:

-- Argomenti per la pubblicazione 'Sport e Attività Fisica' (codPubblil = 12)
INSERT INTO Argomento (descrizione, codPubblil)
VALUES
('Futuro del calcio', 12),
('Atletismo e fitness', 12),
('Sport e tecnologia', 12),
('Salute e performance', 12),
('Sport e crescita', 12),
('Sport estremi', 12),
('Fitness per tutti', 12),
('Allenamento mentale', 12),
('Psicologia sportiva', 12),
('Sport e nutrizione', 12);

-- Articoli per la pubblicazione 'Sport e Attività Fisica' (codPubblil = 12)
INSERT INTO Argomento_Articolo (codArg, codA)
VALUES
-- Articolo 56
(1, 56),  -- 'Futuro del calcio' in Articolo 56
(2, 56),  -- 'Atletismo e fitness' in Articolo 56

-- Articolo 57
(3, 57),  -- 'Sport e tecnologia' in Articolo 57
(4, 57),  -- 'Salute e performance' in Articolo 57

-- Articolo 58
(5, 58),  -- 'Sport e crescita' in Articolo 58
(6, 58),  -- 'Sport estremi' in Articolo 58

-- Articolo 59
(7, 59),  -- 'Fitness per tutti' in Articolo 59
(8, 59),  -- 'Allenamento mentale' in Articolo 59

-- Articolo 60
(9, 60),  -- 'Psicologia sportiva' in Articolo 60
(10, 60);  -- 'Sport e nutrizione' in Articolo 60

Creiamo ora la tabella Abbonato:

CREATE TABLE Abbonato (
    codAbb INT AUTO_INCREMENT PRIMARY KEY,          
    cognome VARCHAR(100) NOT NULL,                 
    nome VARCHAR(100) NOT NULL,                     
    data_di_nascita DATE,                           
    indirizzo VARCHAR(255),                         
    cap VARCHAR(10),                                
    citta VARCHAR(100),                             
    username VARCHAR(50) UNIQUE NOT NULL,           
    password VARCHAR(255) NOT NULL                  
    );

E la tabella Abbonamento. Abbonamento sarà collegata sia ad abbonato che a pubblicazione:

CREATE TABLE abbonamento2 (
    codAbbonamento INT AUTO_INCREMENT PRIMARY KEY,    
    codAbbonato INT,                                  
    codPubblil INT,                                 
    dataInizio DATE CHECK (dataInizio >= '1995-01-01' AND dataInizio <= '2006-12-31'),  -- dataInizio tra 1995-01-01 e 2006-12-31
    dataFine DATE CHECK (dataFine >= '1995-01-01' AND dataFine <= '2006-12-31' AND dataFine > dataInizio),  -- dataFine tra 1995-01-01 e 2006-12-31 e deve essere maggiore di dataInizio
    periodicita ENUM('Trimestrale', 'Semestrale', 'Annuale'),  -- Periodicità dell'abbonamento
    FOREIGN KEY (codAbbonato) REFERENCES Abbonato(codAbb),     -- Chiave esterna che fa riferimento alla tabella Abbonato
    FOREIGN KEY (codPubblil) REFERENCES Pubblicazione(codPubblil)  -- Chiave esterna che fa riferimento alla tabella Pubblicazione
);

popoliamo le due tabelle:

INSERT INTO Abbonato (cognome, nome, data_di_nascita, indirizzo, cap, citta, username, password)
VALUES 
('Rossi', 'Mario', '1985-05-10', 'Via Roma 12', '00100', 'Roma', 'mrossi', 'password123'),
('Bianchi', 'Lucia', '1990-08-20', 'Corso Italia 34', '20100', 'Milano', 'lbianchi', 'securePass2025'),
('Verdi', 'Giuseppe', '1980-02-15', 'Viale delle Alpi 5', '30100', 'Venezia', 'gverdi', '1234password'),
('Esposito', 'Anna', '1995-03-30', 'Via Milano 22', '50100', 'Firenze', 'anna.espo', 'mypassword5'),
('Neri', 'Francesco', '1978-11-11', 'Lungomare 8', '80100', 'Napoli', 'fneri', 'neripassword!'),
('Gialli', 'Elena', '1992-06-25', 'Piazza Dante 56', '70100', 'Bari', 'egialli', 'passwordelena01'),
('Lombardi', 'Marco', '1983-09-10', 'Via Torino 88', '90100', 'Palermo', 'mlombardi', 'securepass321'),
('Marino', 'Giovanni', '1993-01-15', 'Viale Europa 12', '80121', 'Napoli', 'gmarino', 'giovannipass'),
('Cucchi', 'Sara', '1987-07-12', 'Via delle Mura 16', '50123', 'Firenze', 'scucchi', 'sarapassword!'),
('Ferrari', 'Luca', '1982-04-30', 'Piazza San Marco 11', '70121', 'Bari', 'lferrari', 'lucapassw01');
INSERT INTO abbonamento2 (codAbbonato, codPubblil, dataInizio, dataFine, periodicita)
VALUES
(1, 7, '1995-03-01', '1995-05-31', 'Trimestrale'),
(2, 13, '1996-01-01', '1996-06-30', 'Semestrale'),
(3, 19, '1997-02-15', '1997-08-15', 'Annuale'),
(4, 5, '1995-05-10', '1995-07-31', 'Trimestrale'),
(5, 2, '1998-07-01', '1998-12-31', 'Semestrale'),
(6, 14, '1999-03-10', '1999-09-10', 'Annuale'),
(7, 16, '2000-04-05', '2000-09-30', 'Trimestrale'),
(8, 11, '2001-06-01', '2001-12-31', 'Semestrale'),
(9, 1, '2002-08-20', '2003-08-19', 'Annuale'),
(10, 8, '2003-05-10', '2003-11-10', 'Trimestrale'),
(1, 17, '2004-01-15', '2004-06-15', 'Semestrale'),
(2, 3, '2005-02-01', '2005-08-01', 'Annuale'),
(3, 18, '2006-07-10', '2006-12-31', 'Trimestrale'),
(4, 4, '2006-03-01', '2006-08-31', 'Semestrale'),
(5, 12, '1995-09-15', '1996-09-15', 'Annuale'),
(6, 6, '1999-01-01', '1999-06-01', 'Trimestrale'),
(7, 20, '2001-07-01', '2001-12-31', 'Semestrale'),
(8, 9, '2004-11-01', '2005-05-01', 'Annuale'),
(9, 10, '2002-12-01', '2003-11-30', 'Semestrale'),
(10, 15, '2005-06-01', '2005-12-31', 'Annuale');

Realizzazione delle pagine per il sistema informativo della casa editrice

A questo punto possiamo procedere con la realizzazione del codice che permette ad utenti ed amministratori di interagire con il sistema informativo del consorzio.

Facciamo alcune ipotesi:

  • Realizziamo tutto in locale con Apache e MySQL senza perdita di generalità
  • L’accesso all’applicazione (index.php) presenta un login form ed un pulsante “registra”. Se l’utente non è registrato deve registrarsi. Dopo la registrazione viene presentato un link al login. Se è registrato effettua il login e viene reindirizzato alla landing page.
  • La landing_page presenterà otto pulsanti su una sidebar a destra che rappresentano altrettante query (quelle del testo). Alla pressione dei pulsanti dovranno essere visibili i risultati delle query

Per quanto riguarda l’accesso all’area riservata si faccia riferimento alla guida: https://profgiagnotti.it/accesso-allarea-riservata-in-php/ ed al codice che può essere scaricato qui: https://profgiagnotti.it/download_page/download-tps/download-tps-quinto-anno/

Per cui, facendo le dovute modifiche sui nome ecc, avremo: index.php:

Copy
<?php
// Avviamo una sessione per mantenere informazioni come il nome utente o il ruolo.
session_start(); 

// Includiamo il file per la connessione al database
require_once "connessione.php"; 

if ($_SERVER["REQUEST_METHOD"] == "POST") { // Verifichiamo che il metodo della richiesta è POST e acquisiamo i dati di login inseriti dall'utente.
    $username = $_POST["username"]; 
    $password = $_POST["password"];   

    // Controlliamo se la connessione al database è valida, altrimenti terminiamo il processo.
    if (!$conn) { 
        die("Errore di connessione: " . mysqli_connect_error()); 
    }     

    // Controlliamo l'utente: query SQL per verificare se esiste un utente con il nome utente fornito.
    $sql = "SELECT codAbb, username, password FROM abbonato WHERE username = ?"; 

    // Prepariamo e associamo il parametro per evitare SQL injection.
    $stmt = mysqli_prepare($conn, $sql); 
    $stmt->bind_param( "s", $username); 

    // Eseguiamo la query e otteniamo il risultato.
    $stmt->execute(); 
    $result = $stmt->get_result();
    

    if ($row = $result->fetch_assoc()) { 
        if (password_verify($password, $row["password"])) { 
            // Verifichiamo che la password inserita dall'utente corrisponda alla password memorizzata
            $_SESSION["username"] = $row["username"];             
            // Redirigiamo alla landing page
            header("Location: landing_page.php");
            exit();                        
        } else { 
            // Messaggio di errore se la password non è corretta
            $error = "Password errata.";              
        } 
    } else { 
        // Messaggio di errore se il nome utente non esiste nel database
        $error = "Utente non trovato.";          
    }
    // Chiude lo statement e la connessione per evitare problemi di risorse.
    $stmt->close();
    $conn->close();     
}
?>
<!DOCTYPE html> 
<html lang="it"> 
<head> 
    <meta charset="UTF-8"> 
    <title>Login</title>     
    <!-- link al foglio di stile CSS per il design -->
    <link rel="stylesheet" href="stile.css"> 
</head> 
<body> 
    <div class="container"> 
        <h2>Login</h2> 
        <!-- Visualizza un messaggio di errore, se presente, in rosso -->
        <?php if (!empty($error)) echo "<p style='color: red;'>$error</p>"; ?> 
            <form method="POST" action=""> 
                <!-- Campo per inserire il nome utente -->
                <input type="text" id="username" name="username" placeholder="Inserisci il tuo username" required>           

                <br> 
                <!-- Campo per inserire la password -->
                <input type="password" id="password" name="password" placeholder="Inserisci la tua password" required>            

                <br> 
                <!-- Pulsante per inviare il form -->
                <button type="submit">Accedi</button> 
                
            </form> 
        <!-- Link per la pagina di registrazione -->
        <a href="registrazione.php" class="btn">Registrati</a>         
    </div> 
</body> 
</html>

Lo script registrazione.php:

Copy
<?php
// Importiamo il file per la connessione al database.
require 'connessione.php';

if ($_SERVER["REQUEST_METHOD"] == "POST") {//Verifichiamo che il metodo della richiesta è POST e acquisiamo i dati di registrazione inseriti dall'utente.
    $cognome = $_POST["cognome"];
    $nome = $_POST["nome"];
    $data_di_nascita = $_POST["data_di_nascita"];
    $indirizzo = $_POST["indirizzo"];
    $cap = $_POST["cap"];
    $citta = $_POST["citta"];
    $username = $_POST["username"];
    $password = password_hash($_POST["password"], PASSWORD_DEFAULT);// Hash della password per garantire una maggiore sicurezza. PASSWORD_DEFAULT utilizza l'algoritmo bcrypt  

    // Controlliamo se lo username è già in uso
    $checkUser = $conn->prepare("SELECT codAbb FROM abbonato WHERE username = ?");

    // Prepariamo la query per evitare SQL injection 
    $checkUser->bind_param("s", $username);

    //Eseguiamo la query e memorizziamo i risultati
    $checkUser->execute();
    $checkUser->store_result(); 

    if ($checkUser->num_rows > 0) {//Se lo username è già in uso
        // Notifichiamo all'utente che il nome utente è già stato scelto da qualcun altro.
        echo "Errore: Username già in uso.";        
    } else {
        // Inserimento nuovo utente
        // Prepariamo una query per inserire l'utente nel database e leghiamo i parametri: username, password e ruolo.
        $stmt = $conn->prepare("INSERT INTO abbonato (cognome, nome, data_di_nascita, indirizzo, cap, citta, username, password) VALUES (?, ?, ?, ?, ?, ?, ?, ?)");
        $stmt->bind_param("ssssssss", $cognome, $nome, $data_di_nascita, $indirizzo, $cap, $citta, $username, $password);        

        if ($stmt->execute()) {// Se la query è stata eseguita con successo, confermiamolo all'utente e forniamo un link al login.
            echo "Registrazione completata con successo! <a href='index.php'>Vai al login</a>";            
        } else {// Mostriamo un messaggio di errore specifico
            echo "Errore: " . $stmt->error;            
        }
        $stmt->close();// Chiudiamo lo statement per liberare risorse.
    }
    // Chiudiamo sia lo statement di verifica esistenza username che la connessione al database.
    $checkUser->close();
    $conn->close();    
}
?>
<!DOCTYPE html>
<html lang="it">
<head>
    <meta charset="UTF-8">
    <title>Registrazione</title>
    <!-- colleghiamo il foglio di stile per il design -->
    <link rel="stylesheet" href="stile.css">    
</head>
<body>
    <div class="container">
        <h2>Registrazione</h2>
        <form method="POST">
            <input type="text" name="cognome" placeholder="Inserisci il tuo cognome" required> 
            <br>
            <input type="text" name="nome" placeholder="Inserisci il tuo nome" required>     
            <br>
            <input type="date" name="data_di_nascita" placeholder="Inserisci la data di nascita" required> 
            <br>
            <input type="text" name="indirizzo" placeholder="Inserisci il tuo indirizzo" required> 
            <br>
            <input type="text" name="cap" placeholder="Inserisci il tuo CAP" required>     
            <br>
            <input type="text" name="citta" placeholder="Inserisci la città" required>     
            <br>
            <input type="text" name="username" placeholder="Inserisci uno username" required> 
            <br>
            <input type="password" name="password" placeholder="Inserisci una password" required>        

            <br>
            <!-- Pulsante per inviare il modulo -->
            <button type="submit">Registrati</button>       
        </form>

    </div>
</body>
</html>

Evitiamo di riportare anche gli script di connessione e logout perchè già proposti diverse volte e poichè non subiscono modifiche se non al nome del database.

Implementiamo ora la landing_page.php:

  • Facciamo partire la sessione ed effettuiamo la connessione al database (sezione A1 del codice)
  • Poichè alcune query richiedono un form memorizziamo i valori degli array associativi in alcune variabili che ci serviranno poi per eseguire le query. Inoltre dichiariamo una variabile $form che di volta in volta assumerà un valore diverso in base alla query scelta. Esempio: se si sceglie la query1 occorrerà visualizzare il form1 e quindi $form assumerà il valore query1_form (sezione A2 del codice)
  • Definiamo la logica per assegnare il valore a $form in base alle query scelte. Per le query 5 e 6 non occorrono form per cui $form assume il valore “execute_query”(sezione A3 del codice)
  • Scriviamo la logica per l’esecuzione delle query verificando la scelta con un case-switch (sezione A4 del codice)
  • Ora possiamo scrivere la logica che fa visualizzare una tabella con le colonne rappresentate dai campi derivati dall’esecuzione della specifica query (sezione A5 del codice)
  • Scriviamo Il codice HTML iniziando dalla sidebar: scriviamo il form che conterrà i pulsanti delle 4 query (sezione A6 del codice)
  • Subito dopo scriviamo il codice PHP integrato che definisce la visualizzazione dei form laddove necessari (sezione A7 del codice)
  • Chiudiamo con la parte relativa ai contenuti facendo visualizzare il titolo ed il significato delle query in modo che l’utente possa selezionare quella di proprio interesse.
  • Terminiamo tutto con gli script CSS per lo stile (i file sono contenuti nella sezione DOWNLOAD)

Di seguito il codice completo di landing_page.php:

Copy
<?php
session_start();

//----------------------Sezione A1------------------------//

// Connessione al database
$conn = new mysqli("localhost", "root", "", "casaeditrice_soluzione");
if ($conn->connect_error) {
    die("Connection failed: " . $conn->connect_error);
}

//------------------------Sezione A2-------------------//


// Inizializzazione variabili
$queryResult = '';
$queryScelta = $_POST["query"] ?? '';
$titoloP = $_POST['titoloP'] ?? '';
$anno = $_POST['annoPubbl'] ?? '';
$cognome = $_POST['cognome'] ?? '';
$nome = $_POST['nome'] ?? '';
$argomento = $_POST['argomento'] ?? '';
$titoloP1 = $_POST['titoloP1'] ?? '';
$titoloP2 = $_POST['titoloP2'] ?? '';
$form = '';

//-------------Sezione A3-------------//
if ($_SERVER["REQUEST_METHOD"] == "POST") {
    // Controllo quale query è stata selezionata e decido che form mostrare
    if ($queryScelta) {
        // Se la query è 'query1', mostra il form con il titoloPubbl e anno
        if ($queryScelta === 'query1') {
            $form = 'query1_form';
        }
        // Se la query è 'query2', mostra il form con il titoloPubbl
        elseif ($queryScelta === 'query2') {
            $form = 'query2_form';
        }
        // Se la query è 'query3', mostra il form con il nominativo abbonato
        elseif ($queryScelta === 'query3') {
            $form = 'query3_form';
        }
        // Se la query è 'query4', mostra il form per eseguire la query
        elseif ($queryScelta === 'query4') {
            $form = 'query4_form';
        }
        // Se la query è 'query5', non occorre il form
        elseif ($queryScelta === 'query5') {
            $form = 'execute_query';
        }
        // Se la query è 'query6', non occorre il form
        elseif ($queryScelta === 'query6') {
            $form = 'execute_query';
        }
        // Se la query è 'query7', mostra il form per i titoli di due pubblicazioni
        elseif ($queryScelta === 'query7') {
            $form = 'query7_form';
        }
        // Se la query è 'query8', mostra il form con il titoloPubbl
        elseif ($queryScelta === 'query8') {
            $form = 'query8_form';
        }
    }
}

//--------------A4----------------//
    switch ($queryScelta) {
        case 'query1':
            // Query 1: Dato il titolo di una pubblicazione, ricercare gli articoli pubblicati in un determinato anno
            $querySQL = "SELECT A.codA, A.titolo_articolo, A.annoPubbl
                        FROM Articolo A
                        JOIN Pubblicazione P ON A.codPubblil = P.codPubblil
                        WHERE P.TitoloP = ? AND A.annoPubbl = ?";
            break;
        case 'query2':
            // Query 2: Dato il titolo di una pubblicazione, ricercare gli abbonati annuali
            $querySQL = "SELECT A.cognome, A.nome 
                        FROM Abbonato A
                        JOIN Abbonamento B ON A.codAbb = B.codAbbonato
                        JOIN Pubblicazione P ON B.codPubblil = P.codPubblil
                        WHERE P.TitoloP = ? AND B.periodicita = 'Annuale'";
            break;
        case 'query3':
            // Query 3: Dato il nominativo di un abbonato, stabilire a quante riviste è abbonato
            $querySQL = "SELECT COUNT(DISTINCT P.codPubblil) AS numero_riviste
                        FROM Abbonato A
                        JOIN Abbonamento B ON A.codAbb = B.codAbbonato
                        JOIN Pubblicazione P ON B.codPubblil = P.codPubblil
                        WHERE A.cognome = ? AND A.nome = ?";
            break;
        case 'query4':
            // Query 4: Dato un argomento, elencare le pubblicazioni in cui è trattato
            $querySQL = "SELECT DISTINCT P.TitoloP
                        FROM Pubblicazione P
                        JOIN Argomento Ar ON P.codPubblil = Ar.codPubblil
                        WHERE Ar.descrizione = ?";
            break;
        case 'query5':
            // Query 5: Riportare per ogni pubblicazione il numero di abbonamenti
            $querySQL = "SELECT P.TitoloP, COUNT(B.codAbbonamento) AS numero_abbonamenti
                        FROM Pubblicazione P
                        LEFT JOIN Abbonamento B ON P.codPubblil = B.codPubblil
                        GROUP BY P.codPubblil";
            break;
        case 'query6':
            // Query 6: Visualizzare i giornali con almeno 2 abbonati annuali
            $querySQL = "SELECT P.TitoloP
                        FROM Pubblicazione P
                        JOIN Abbonamento B ON P.codPubblil = B.codPubblil
                        WHERE B.periodicita = 'Annuale'
                        GROUP BY P.codPubblil
                        HAVING COUNT(B.codAbbonamento) >= 2";
            break;
        case 'query7':
            // Query 7: Dati i titoli di due pubblicazioni, visualizzarne gli abbonati comuni
            $querySQL = "SELECT A.cognome, A.nome, A.username
                        FROM Abbonato A
                        JOIN Abbonamento B1 ON A.codAbb = B1.codAbbonato
                        JOIN Pubblicazione P1 ON B1.codPubblil = P1.codPubblil
                        JOIN Abbonamento B2 ON A.codAbb = B2.codAbbonato
                        JOIN Pubblicazione P2 ON B2.codPubblil = P2.codPubblil
                        WHERE P1.TitoloP = ? AND P2.TitoloP = ?
                        ";
            break;
        case 'query8':
            // Query 8: Dato il titolo di una pubblicazione, elencare le pubblicazioni che trattano i suoi stessi argomenti
            $querySQL = "SELECT DISTINCT P2.TitoloP
                        FROM Pubblicazione P1
                        JOIN Argomento Ar1 ON P1.codPubblil = Ar1.codPubblil
                        JOIN Argomento Ar2 ON Ar1.descrizione = Ar2.descrizione
                        JOIN Pubblicazione P2 ON Ar2.codPubblil = P2.codPubblil
                        WHERE P1.TitoloP = ? AND P2.TitoloP != P1.TitoloP";
            break;
    }

    //---------------A5----------------//
    if (isset($querySQL)) {
        $stmt = $conn->prepare($querySQL);
        if ($queryScelta == 'query1') {            
            $stmt->bind_param("ss", $titoloP, $anno);
        } elseif ($queryScelta == 'query2') {
            $stmt->bind_param("s", $titoloP);
        } elseif ($queryScelta === 'query3') {
            if(isset($_POST['abbonato'])){
                list($cognome, $nome) = explode(",", $_POST['abbonato']);
              }  // Separazione cognome e nome
            $stmt->bind_param("ss", $cognome,$nome);                   
        }elseif ($queryScelta === 'query4') {
            $stmt->bind_param("s", $argomento);                   
        }elseif ($queryScelta === 'query7') {  
            $stmt->bind_param("ss", $titoloP1, $titoloP2);                
        }elseif ($queryScelta === 'query8') {  
            $stmt->bind_param("s", $titoloP);                
        }

        $stmt->execute();
        $result = $stmt->get_result();

        if ($result->num_rows > 0) {
            $queryResult = '<table border="1"><tr>';
            while ($field = $result->fetch_field()) {
                $queryResult .= "<th>{$field->name}</th>";
            }
            $queryResult .= '</tr>';
            while ($row = $result->fetch_assoc()) {
                $queryResult .= '<tr>';
                foreach ($row as $column) {
                    $queryResult .= "<td>{$column}</td>";
                }
                $queryResult .= '</tr>';
            }
            $queryResult .= '</table>';
        } else {
            $queryResult = 'Nessun risultato trovato.';
        }
        $stmt->close();
    }



?>

<!---------------------A6------------------>
<!DOCTYPE html>
<html lang="it">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Casa Editrice</title>
    <link rel="stylesheet" href="stile2.css">
</head>
<body>
    <div class="sidebar">
        <form method="POST" action="landing_page.php">
            <button type="submit" name="query" value="query1">Query 1</button>
            <button type="submit" name="query" value="query2">Query 2</button>
            <button type="submit" name="query" value="query3">Query 3</button>
            <button type="submit" name="query" value="query4">Query 4</button>
            <button type="submit" name="query" value="query5">Query 5</button>
            <button type="submit" name="query" value="query6">Query 6</button>
            <button type="submit" name="query" value="query7">Query 7</button>
            <button type="submit" name="query" value="query8">Query 8</button>
        </form>
        
<!---------------A7----------------->        
<?php if ($form === 'query1_form'): ?>
    <h3>Seleziona un titolo di pubblicazione e anno:</h3>
    <form method="POST" action="landing_page.php">
        <input type="hidden" name="query" value="query1">
        <label for="titoloP">Titolo pubblicazione:</label>
        <select name="titoloP" id="titoloP">
            <?php
                // Recupera i titoli di pubblicazione dal database
                $result = $conn->query("SELECT TitoloP FROM Pubblicazione");
                while ($row = $result->fetch_assoc()) {
                    echo "<option value='" . $row['TitoloP'] . "'>" . $row['TitoloP'] . "</option>";
                }
            ?>
        </select>
        <br>
        <label for="annoPubbl">Anno:</label>
        <select name="annoPubbl" id="annoPubbl">
            <?php
                // Recupera gli anni disponibili dalle pubblicazioni
                $result = $conn->query("SELECT DISTINCT annoPubbl FROM Articolo");
                while ($row = $result->fetch_assoc()) {
                    echo "<option value='" . $row['annoPubbl'] . "'>" . $row['annoPubbl'] . "</option>";
                }
            ?>
        </select>
        <br>
        <button type="submit">Esegui</button>
    </form>
<?php endif; ?>

<?php if ($form === 'query2_form'): ?>
    <h3>Seleziona un titolo di pubblicazione:</h3>
    <form method="POST" action="landing_page.php">
        <input type="hidden" name="query" value="query2">
        <label for="titolo_pub">Titolo pubblicazione:</label>
        <select name="titoloP" id="titolo_pub">
            <?php
                // Recupera i titoli di pubblicazione dal database
                $result = $conn->query("SELECT TitoloP FROM Pubblicazione");
                while ($row = $result->fetch_assoc()) {
                    echo "<option value='" . $row['TitoloP'] . "'>" . $row['TitoloP'] . "</option>";
                }
            ?>
        </select>
        <br>
        <button type="submit">Esegui</button>
    </form>
<?php endif; ?>

<?php if ($form === 'query3_form'): ?>
    <h3>Seleziona il nominativo dell'abbonato:</h3>
    <form method="POST" action="landing_page.php">
        <input type="hidden" name="query" value="query3">
        <label for="cognome">Cognome:</label>
        <select name="abbonato" id="abbonato">
            <?php
                // Recupera i cognomi e i nomi degli abbonati combinati come "cognome nome"
                $result = $conn->query("SELECT DISTINCT cognome, nome FROM Abbonato");
                while ($row = $result->fetch_assoc()) {
                    $abbonatoDisplay = $row['cognome'] . ' ' . $row['nome'];  // Concatenazione del cognome e del nome
                    echo "<option value='" . $row['cognome'] . "," . $row['nome'] . "'>" . $abbonatoDisplay . "</option>";
                }
            ?>
        </select>
        <br>
        <button type="submit">Esegui</button>
    </form>
<?php endif; ?>

<?php if ($form === 'query4_form'): ?>
    <h3>Seleziona l'argomento:</h3>
    <form method="POST" action="landing_page.php">
        <input type="hidden" name="query" value="query4">
        <label for="argomento">Argomento:</label>
        <select name="argomento" id="argomento">
            <?php
                // Recupera i cognomi e i nomi degli abbonati combinati come "cognome nome"
                $result = $conn->query("SELECT descrizione FROM Argomento");
                while ($row = $result->fetch_assoc()) {
                    echo "<option value='" . $row['descrizione'] . "'>" . $row['descrizione'] . "</option>";
                }
            ?>
        </select>
        <br>
        <button type="submit">Esegui</button>
    </form>
<?php endif; ?>

<?php if ($form === 'query7_form'): ?>
    <h3>Seleziona i titoli di due pubblicazioni:</h3>
    <form method="POST" action="landing_page.php">
        <input type="hidden" name="query" value="query7">
        
        <label for="titoloP1">Titolo prima pubblicazione:</label>
        <select name="titoloP1" id="titoloP1">
            <?php
                // Recupera i titoli di pubblicazione dal database
                $result = $conn->query("SELECT TitoloP FROM Pubblicazione");
                while ($row = $result->fetch_assoc()) {
                    echo "<option value='" . $row['TitoloP'] . "'>" . $row['TitoloP'] . "</option>";
                }
            ?>
        </select>
        <br>

        <label for="titoloP2">Titolo seconda pubblicazione:</label>
        <select name="titoloP2" id="titoloP2">
            <?php
                // Recupera di nuovo i titoli di pubblicazione dal database
                $result = $conn->query("SELECT TitoloP FROM Pubblicazione");
                while ($row = $result->fetch_assoc()) {
                    echo "<option value='" . $row['TitoloP'] . "'>" . $row['TitoloP'] . "</option>";
                }
            ?>
        </select>
        <br>

        <button type="submit">Esegui</button>
    </form>
<?php endif; ?>

<?php if ($form === 'query8_form'): ?>
    <h3>Seleziona un titolo di pubblicazione:</h3>
    <form method="POST" action="landing_page.php">
        <input type="hidden" name="query" value="query8">
        
        <label for="titoloP">Titolo pubblicazione:</label>
        <select name="titoloP" id="titoloP">
            <?php
                // Recupera i titoli di pubblicazione dal database
                $result = $conn->query("SELECT TitoloP FROM Pubblicazione");
                while ($row = $result->fetch_assoc()) {
                    echo "<option value='" . $row['TitoloP'] . "'>" . $row['TitoloP'] . "</option>";
                }
            ?>
        </select>
        <br>

        <button type="submit">Esegui</button>
    </form>
<?php endif; ?>



    </div>

    <div class="content">
        <a href="logout.php" class="btn">LOGOUT</a>
        <h1>Benvenuto <?php echo htmlspecialchars($_SESSION["username"]); ?> nella home page della Casa Editrice!</h1>
        <h2>Seleziona una query per visualizzare i risultati</h2>
        <h3>Query 1: Dato il titolo di una pubblicazione, ricercare gli articoli pubblicati in un determinato anno.</h3>
        <h3>Query 2: Dato il titolo di una pubblicazione, ricercare gli abbonati annuali.</h3>
        <h3>Query 3: Dato il nominativo di un abbonato, stabilire a quante riviste è abbonato.</h3>
        <h3>Query 4: Dato un argomento, elencare le pubblicazioni in cui è trattato.</h3>
        <h3>Query 5: Riportare per ogni pubblicazione il numero di abbonamenti.</h3>
        <h3>Query 6: Visualizzare i giornali con almeno 5000 abbonati annuali.</h3>
        <h3>Query 7: Dati i titoli di due pubblicazioni, visualizzarne gli abbonati comuni.</h3>
        <h3>Query 8: Dato il titolo di una pubblicazione, elencare le pubblicazioni che trattano i suoi stessi argomenti.</h3>
        <!-- Visualizziamo il risultato della query -->
        <div>
            <?php echo $queryResult; ?>
        </div>
    </div>
</body>
</html>

Test dell’ applicazione

Nella sezione DOWNLOAD dedicata o all’inizio di questo articolo è possibile scaricare tutti i file per testare la soluzione proposta tra i quali anche casaeditrice_soluzione.sql per poterlo importare direttamente.

Digitare quindi localhost/[cartella]/index.php sulla barra degli indirizzi, cliccare su “registra” ed inserire i dati.

Premere “login” e loggarsi con le credenziali precedentemente scelte. Dovreste avere accesso alla landing_page:

testare le query. Qui in basso l’output di esempio della query 5:

Scarica il codice qui: https://profgiagnotti.it/download_page/download-temi-desame-svolti/ oppure all’inizio di questo articolo

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *