<?php /* * Esercizio "Maratona" in PHP * * Testo dell'esercizio disponibile sul sito web dell'autore (www.andreacaravano.net) * * Ultima modifica: 30/06/2020 * * Descrizione: Possibile soluzione all'esercizio "Maratona" in PHP * N.B.: L'esercizio scaturisce dalla sola fantasia dell'autore e intende rappresentare una applicazione didattica. * I dettagli in esso contenuti potrebbero non essere corrispondenti alla realtà e intendono valutare le abilità nella gestione delle strutture dati proposte. */ $cognome = ""; $dataNascita = ""; $comune = ""; $nazione = ""; $tipologiaDocumento = ""; $identificativoDocumento = ""; $codiceFiscale = ""; $numeroTessera = ""; $categoria = ""; $strumentiElettronici = ""; $mail = ""; $pass = ""; function tornaCheckBox($vettCheckBox) { $ritorno = ""; foreach ($vettCheckBox as $elemento) { $ritorno .= $elemento; if (array_search($elemento, $vettCheckBox) != count($vettCheckBox) - 1) { $ritorno .= ", "; } } return $ritorno; } function stampaPassword($pass) { $ritorno = ""; for ($i = 0; $i < strlen($pass); $i++) { if ($i == 0 || $i == strlen($pass) - 1 || $i == strlen($pass) - 2 || $i == strlen($pass) - 3) { $ritorno .= $pass[$i]; } else $ritorno .= "*"; } return $ritorno; } function controlloServer() { global $cognome, $nome, $dataNascita, $comune, $nazione, $tipologiaDocumento, $identificativoDocumento, $codiceFiscale, $numeroTessera, $categoria, $strumentiElettronici, $mail, $pass, $esito, $continuaStampa; $continuaStampa = false; try { $cognome = $_REQUEST["cognome"]; $nome = $_REQUEST["nome"]; $dataNascita = $_REQUEST["data-nascita"]; $comune = $_REQUEST["comune"]; $nazione = $_REQUEST["nazione"]; $tipologiaDocumento = $_REQUEST["tipologia-documento"]; $identificativoDocumento = $_REQUEST["identificativo-documento"]; $codiceFiscale = $_REQUEST["codice-fiscale"]; $numeroTessera = $_REQUEST["numero-tessera"]; $categoria = $_REQUEST["categoria"]; $strumentiElettronici = $_REQUEST["strumenti-elettronici"]; $mail = $_REQUEST["mail"]; $pass = $_REQUEST["pass"]; $regexDataNascita = "/^[0-9]{4}[-]{1}[0-9]{2}[-]{1}[0-9]{2}$/"; $regexIdentificativoDocumento = "/^[A-Za-z]{2}[0-9]{1,}$/"; $regexCodiceFiscale = "/^[A-Z]{6}[0-9]{2}[A-Z]{1}[0-9]{2}[A-Z]{1}[0-9]{3}[A-Z]{1}$/"; $regexNumeroTessera = "/^[0-9]{9}129$/"; $regexMail = "/^[a-z0-9._-]{1,}@[a-z0-9.-]{3,}\\.[a-z]{2,}$/"; $regexCategoriaAtleta = "/^[1-7]$/"; $contaErrori = 0; if (strlen($cognome) < 1 || strlen($cognome) > 150) { $vettErrori[$contaErrori] = "cognome"; $contaErrori++; } if (strlen($nome) < 1 || strlen($nome) > 100) { $vettErrori[$contaErrori] = "nome"; $contaErrori++; } if (preg_match($regexDataNascita, $dataNascita) == false) { $vettErrori[$contaErrori] = "Data di nascita"; $contaErrori++; } if (strlen($comune) < 2) { $vettErrori[$contaErrori] = "Comune di nascita"; $contaErrori++; } if (strlen($nazione) < 3) { $vettErrori[$contaErrori] = "Nazione di nascita"; $contaErrori++; } if (isset($tipologiaDocumento) == false || ($tipologiaDocumento == "Carta d'identità" || $tipologiaDocumento == "Patente di guida") == false) { $vettErrori[$contaErrori] = "Tipologia documento"; $contaErrori++; } if (preg_match($regexIdentificativoDocumento, $identificativoDocumento) == false) { $vettErrori[$contaErrori] = "Identificativo del documento"; $contaErrori++; } if (preg_match($regexCodiceFiscale, $codiceFiscale) == false || strlen($codiceFiscale) != 16) { $vettErrori[$contaErrori] = "Codice Fiscale"; $contaErrori++; } if (preg_match($regexNumeroTessera, $numeroTessera) == false || strlen($numeroTessera) != 12) { $vettErrori[$contaErrori] = "Numero tessera"; $contaErrori++; } if (isset($categoria) == false || preg_match($regexCategoriaAtleta, $categoria) == false) { $vettErrori[$contaErrori] = "Categoria atleta"; $contaErrori++; } if (count($strumentiElettronici) == 0 || (array_search("Fascia di rilevazione delle cardio-frequenze", $strumentiElettronici) >= 0 || array_search("Contapassi", $strumentiElettronici) >= 0 || array_search("Sensori di rilevazione dei grassi e calorie consumate", $strumentiElettronici) >= 0) == false) { $vettErrori[$contaErrori] = "Strumenti elettronici"; $contaErrori++; } if (preg_match($regexMail, $mail) == false || strlen($mail) < 8) { $vettErrori[$contaErrori] = "E-mail"; $contaErrori++; } if (strlen($pass) < 10 || strlen($pass) > 80) { $vettErrori[$contaErrori] = "Password"; $contaErrori++; } if ($contaErrori > 0) { $continuaStampa = false; $esito = "<span style='color: #FF7070; font-weight: bold;'>Rilevati errori nei campi: "; for ($i = 0; $i < $contaErrori; $i++) { $esito .= $vettErrori[$i]; if ($i != $contaErrori - 1) $esito .= ", "; } $esito .= "!</span>"; } else { $continuaStampa = true; $esito = "<span style='color: #339966; font-weight: bold;'>Registrazione conclusa con successo. Riepilogo dati:</span>"; } } catch (Exception $e) { $continuaStampa = false; $esito = "<span style='color: #FF7070; font-weight: bold;'>Errore di elaborazione dei dati. Si prega di riprovare, verificando di aver fornito tutti i dati richiesti.</span>"; } return $esito; } if (isset($_POST["submit"]) /* Alternativa: !empty($_REQUEST) */) { if ((isset($_REQUEST["cognome"]) && isset($_REQUEST["nome"]) && isset($_REQUEST["data-nascita"]) && isset($_REQUEST["comune"]) && isset($_REQUEST["nazione"]) && isset($_REQUEST["tipologia-documento"]) && isset($_REQUEST["identificativo-documento"]) && isset($_REQUEST["codice-fiscale"]) && isset($_REQUEST["numero-tessera"]) && isset($_REQUEST["categoria"]) && isset($_REQUEST["strumenti-elettronici"]) && isset($_REQUEST["mail"]) && isset($_REQUEST["pass"])) == false) { $continuaStampa = false; $esito = "<span style='color: #FF7070; font-weight: bold;'>ATTENZIONE! Non sono stati compilati alcuni campi o non è stato possibile ricavarne i valori. Riprovare.</span>"; } else $continuaStampa = true; ?> <!DOCTYPE html> <html lang="it"> <head> <meta charset="UTF-8"> <title> Registrazione alla maratona </title> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous"> <style> td { width: 50%; } th { text-align: right; } </style> </head> <body> <main role="main" class="container" style="padding-top: 30px;"> <h1 style="padding-bottom: 30px; text-align: center;"> Ricevuta di registrazione </h1> <table class="table table-striped table-bordered table-hover"> <caption> Ricevuta di registrazione </caption> <thead> <tr> <td colspan="2"> <?php if ($continuaStampa == false) echo $esito; else { echo controlloServer(); } ?> </td> </tr> </thead> <tbody> <?php if ($continuaStampa) { ?> <tr> <th> <label> Cognome: </label> </th> <td> <?php echo $cognome; ?> </td> </tr> <tr> <th> <label> Nome: </label> </th> <td> <?php echo $nome; ?> </td> </tr> <tr> <th> <label> Data di nascita: </label> </th> <td> <?php $dataNascita = explode("-", $dataNascita); $dataNascita = $dataNascita[2] . "/" . $dataNascita[1] . "/" . $dataNascita[0]; echo $dataNascita; ?> </td> </tr> <tr> <th> <label> Comune di nascita: </label> </th> <td> <?php echo $comune; ?> </td> </tr> <tr> <th> <label> Nazione di nascita: </label> </th> <td> <?php echo $nazione; ?> </td> </tr> <tr> <th> <label> Tipologia di documento: </label> </th> <td> <?php echo $tipologiaDocumento; ?> </td> </tr> <tr> <th> <label> Identificativo del documento: </label> </th> <td> <?php echo $identificativoDocumento; ?> </td> </tr> <tr> <th> <label> Codice Fiscale: </label> </th> <td> <?php echo $codiceFiscale; ?> </td> </tr> <tr> <th> <label> Numero di tessera: </label> </th> <td> <?php echo $numeroTessera; ?> </td> </tr> <tr> <th> <label> Categoria di appartenenza: </label> </th> <td> <?php echo $categoria . "<sup>a</sup> categoria"; ?> </td> </tr> <tr> <th> <label> Giornata della gara: </label> </th> <td> <?php switch ($categoria) { case 1: $giornata = "19 maggio"; break; case 2: $giornata = "18 maggio"; break; case 3: $giornata = "15 maggio"; break; case 4: $giornata = "14 maggio"; break; case 5: $giornata = "13 maggio"; break; case 6: $giornata = "12 maggio"; break; case 7: $giornata = "11 maggio"; break; default: $giornata = "Errore nella determinazione della giornata di gara."; break; } echo $giornata; ?> </td> </tr> <tr> <th> <label> Numero di maglia (provvisorio): </label> </th> <td> <?php srand(); echo rand(100, 900); ?> </td> </tr> <tr> <th> <label> Strumenti elettronici addizionali </label> </th> <td> <?php echo tornaCheckBox($strumentiElettronici); ?> </td> </tr> <tr> <th> <label> Indirizzo e-mail: </label> </th> <td> <?php echo $mail; ?> </td> </tr> <tr> <th> <label> Password: </label> </th> <td> <?php echo stampaPassword($pass); ?> </td> </tr> <tr> <th> <label> Codice univoco di prenotazione: </label> </th> <td> <?php /* Passi dell'algoritmo: 1. Trasformazione del cognome nelle corrispondenti codifiche decimali ASCII Standard (solo se stampabili, dunque esclusi spazi, caratteri speciali e non stampabili). 2. Trasformazione del nome nelle corrispondenti codifiche decimali ASCII Standard (solo se stampabili, dunque esclusi spazi, caratteri speciali e non stampabili). 3. Trasformazione della data di nascita nel corrispettivo formato concatenato GGMMAAAA. 4. Estrapolazione delle prime 9 cifre del numero di tessera */ $codiceUnivoco = ""; for ($i = 0; $i < strlen($cognome); $i++) { if (ctype_print($cognome[$i])) { $codiceUnivoco .= ord($cognome[$i]); } } $codiceUnivoco .= "-"; for ($i = 0; $i < strlen($nome); $i++) { if (ctype_print($nome[$i])) { $codiceUnivoco .= ord($nome[$i]); } } $codiceUnivoco .= "-"; $codiceUnivoco .= str_replace("/", "", $dataNascita);; $codiceUnivoco .= "-"; $codiceUnivoco .= substr($numeroTessera, 0, 9); echo $codiceUnivoco; ?> </td> </tr> <tr> <th> <label> Data e orario correnti: </label> </th> <td> <?php echo date("d/m/Y - H:i:s") ?> </td> </tr> <?php } ?> </tbody> </table> </main> <script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script> <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script> <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script> </body> </html> <?php if (strlen($esito) != 0) return; } else { ?> <!DOCTYPE html> <html lang="it"> <head> <meta charset="UTF-8"> <title> Registrazione alla maratona </title> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous"> <style> td { width: 50%; } th { text-align: right; } </style> <script type="text/javascript"> function controlloClient() { try { var cognome = document.modulo.cognome.value; var nome = document.modulo.nome.value; var dataNascita = document.getElementById("data-nascita").value; var comuneNascita = document.modulo.comune.value; var nazioneNascita = document.modulo.nazione.value; var tipologiaDocumento = tornaRadioCheckbox(document.getElementsByName("tipologia-documento")); var identificativoDocumento = document.getElementById("identificativo-documento").value; var codiceFiscale = document.getElementById("codice-fiscale").value; var numeroTessera = document.getElementById("numero-tessera").value; var categoriaAtleta = tornaSelect(document.modulo.categoria); var strumentiElettronici = tornaRadioCheckbox(document.getElementsByName("strumenti-elettronici[]")); var mail = document.modulo.mail.value; var pass = document.modulo.pass.value; var regexDataNascita = new RegExp("^[0-9]{4}[-]{1}[0-9]{2}[-]{1}[0-9]{2}$"); var regexIdentificativoDocumento = new RegExp("^[A-Za-z]{2}[0-9]{1,}$"); var regexCodiceFiscale = new RegExp("^[A-Z]{6}[0-9]{2}[A-Z]{1}[0-9]{2}[A-Z]{1}[0-9]{3}[A-Z]{1}$"); var regexNumeroTessera = new RegExp("^[0-9]{9}129$"); var regexMail = new RegExp("^[a-z0-9._-]{1,}@[a-z0-9.-]{3,}\\.[a-z]{2,}$"); var regexCategoriaAtleta = new RegExp("^[1-7]$"); var contaErrori = 0; if (cognome.length < 1 || cognome.length > 150) { alert("Errore sul campo cognome!"); document.modulo.cognome.focus(); contaErrori++; } if (nome.length < 1 || nome.length > 100) { alert("Errore sul campo nome!"); document.modulo.nome.focus(); contaErrori++; } if (regexDataNascita.test(dataNascita) == false) { alert("Errore sul campo Data di nascita!"); document.getElementById("data-nascita").focus(); contaErrori++; } if (comuneNascita.length < 2) { alert("Errore sul campo Comune di nascita!"); document.modulo.comune.focus(); contaErrori++; } if (nazioneNascita.length < 3) { alert("Errore sul campo Nazione di nascita!"); document.modulo.nazione.focus(); contaErrori++; } if (tipologiaDocumento.length == 0 || (tipologiaDocumento == "Carta d'identità" || tipologiaDocumento == "Patente di guida") == false) { alert("Errore sul campo Tipologia documento!"); contaErrori++; } if (regexIdentificativoDocumento.test(identificativoDocumento) == false || identificativoDocumento.length > 15) { alert("Errore sul campo Identificativo del documento!"); document.getElementById("identificativo-documento").focus(); contaErrori++; } if (regexCodiceFiscale.test(codiceFiscale) == false || codiceFiscale.length != 16) { alert("Errore sul campo Codice Fiscale!"); document.getElementById("codice-fiscale").focus(); contaErrori++; } if (regexNumeroTessera.test(numeroTessera) == false || numeroTessera.length != 12) { alert("Errore sul campo Numero tessera!"); document.getElementById("numero-tessera").focus(); contaErrori++; } if (categoriaAtleta.length == 0 || regexCategoriaAtleta.test(categoriaAtleta) == false) { alert("Errore sul campo Categoria atleta!"); contaErrori++; } if (strumentiElettronici.length == 0 || (strumentiElettronici.includes("Fascia di rilevazione delle cardio-frequenze") || strumentiElettronici.includes("Contapassi") || strumentiElettronici.includes("Sensori di rilevazione dei grassi e calorie consumate")) == false) { alert("Errore sul campo Strumenti elettronici!"); contaErrori++; } if (regexMail.test(mail) == false || mail.length < 8) { alert("Errore sul campo E-mail!"); document.modulo.mail.focus(); contaErrori++; } if (pass.length < 10 || pass.length > 80) { alert("Errore sul campo Password!"); document.modulo.pass.focus(); contaErrori++; } console.log("Identificati " + contaErrori + " errori."); if (contaErrori > 0) { return false; } } catch (ERR) { console.warn("Eccezione non gestita: " + ERR); return false; } } function tornaRadioCheckbox(elemento) { var ritorno = ""; var contaSelezionati = 0; for (var j = 0; j < elemento.length; j++) { if (elemento[j].checked) { contaSelezionati++; } } var contaRitornati = 0; for (var i = 0; i < elemento.length; i++) { if (elemento[i].checked) { ritorno += elemento[i].value; contaRitornati++; if (contaSelezionati != contaRitornati) ritorno += ", "; } } return ritorno; } function tornaSelect(elemento) { return elemento.options[elemento.selectedIndex].value; } </script> </head> <body> <main role="main" class="container" style="padding-top: 30px;"> <h1 style="padding-bottom: 30px; text-align: center;"> Modulo di registrazione alla maratona </h1> <form id="modulo" name="modulo" action="<?php echo $_SERVER["PHP_SELF"] ?>" method="POST" onsubmit="return controlloClient();"> <div class="form-group"> <table class="table table-striped table-bordered table-hover"> <caption> Modulo di registrazione </caption> <tbody> <tr> <th> <label for="cognome"> Cognome: </label> </th> <td> <input type="text" id="cognome" name="cognome" minlength="1" maxlength="150" size="80" required/> </td> </tr> <tr> <th> <label for="nome"> Nome: </label> </th> <td> <input type="text" id="nome" name="nome" minlength="1" maxlength="100" size="60" required/> </td> </tr> <tr> <th> <label for="data-nascita"> Data di nascita: </label> </th> <td> <input type="date" id="data-nascita" name="data-nascita" pattern="^[0-9]{4}[-]{1}[0-9]{2}[-]{1}[0-9]{2}$" required/> </td> </tr> <tr> <th> <label for="comune"> Comune di nascita: </label> </th> <td> <input type="text" id="comune" name="comune" minlength="2" required/> </td> </tr> <tr> <th> <label for="nazione"> Nazione di nascita: </label> </th> <td> <input type="text" id="nazione" name="nazione" minlength="3" required/> </td> </tr> <tr> <th> <label> Tipologia di documento: </label> </th> <td> <input type="radio" id="carta-identita" name="tipologia-documento" value="Carta d'identità" checked/> <label for="carta-identita"> Carta d'identià </label> <br/> <input type="radio" id="patente" name="tipologia-documento" value="Patente di guida"/> <label for="patente"> Patente di guida </label> </td> </tr> <tr> <th> <label for="identificativo-documento"> Identificativo del documento: </label> </th> <td> <input type="text" id="identificativo-documento" name="identificativo-documento" maxlength="15" pattern="^[A-Za-z]{2}[0-9]{1,}$" required/> </td> </tr> <tr> <th> <label for="codice-fiscale"> Codice Fiscale: </label> </th> <td> <input type="text" id="codice-fiscale" name="codice-fiscale" minlength="16" maxlength="16" size="16" pattern="^[A-Z]{6}[0-9]{2}[A-Z]{1}[0-9]{2}[A-Z]{1}[0-9]{3}[A-Z]{1}$" required /> </td> </tr> <tr> <th> <label for="numero-tessera"> Numero di tessera: </label> </th> <td> <input type="number" id="numero-tessera" name="numero-tessera" minlength="12" maxlength="12" size="12" pattern="^[0-9]{9}129$" required/> </td> </tr> <tr> <th> <label for="categoria"> Categoria di appartenenza: </label> </th> <td> <select id="categoria" name="categoria"> <?php for ($i = 1; $i <= 7; $i++) { echo "<option value='" . $i . "'" . (($i == 1) ? " selected='selected'" : "") . ">" . $i . "° categoria</option>"; } ?> </select> </td> </tr> <tr> <th> <label> Strumenti elettronici addizionali </label> </th> <td> <input type="checkbox" id="fascia-cardio" name="strumenti-elettronici[]" value="Fascia di rilevazione delle cardio-frequenze"/> <label for="fascia-cardio"> Fascia di rilevazione delle cardio-frequenze </label> <br/> <input type="checkbox" id="contapassi" name="strumenti-elettronici[]" value="Contapassi"/> <label for="contapassi"> Contapassi </label> <br/> <input type="checkbox" id="sensori-grassi-calorie" name="strumenti-elettronici[]" value="Sensori di rilevazione dei grassi e calorie consumate"/> <label for="sensori-grassi-calorie"> Sensori di rilevazione dei grassi e calorie consumate </label> </td> </tr> <tr> <th> <label for="mail"> Indirizzo e-mail: </label> </th> <td> <input type="email" id="mail" name="mail" minlength="8" pattern="^[a-z0-9._-]{1,}@[a-z0-9.-]{3,}\.[a-z]{2,}$" required/> </td> </tr> <tr> <th> <label for="pass"> Password: </label> </th> <td> <input type="password" id="pass" name="pass" minlength="10" maxlength="80" required/> </td> </tr> <tr> <td style="text-align: right;"> <input type="submit" name="submit" class="btn btn-primary" value="Conferma invio dati"/> </td> <td> <input type="reset" class="btn btn-secondary" value="Azzera i campi del modulo"/> </td> </tr> </tbody> </table> </div> </form> </main> <script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script> <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script> <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script> </body> </html> <?php } ?>