Development

Documentation/it_IT/book/forms/02-Form-Validation

You must first sign up to be able to contribute.

Version 1 (modified by garak, 9 years ago)
non finita…

Validazione di form

Nel Capitolo 1 abbiamo imparato come creare e visualizzare una semplice form di contatto. In questo capitolo imparerai a gestire la validazione delle form.

Prima di iniziare

La form di contatto creata nel Capitolo 1 non è ancora pienamente funzionale. Che succede se un utente inserisce un indirizzo email non valido o un messaggio vuoto? In questi casi, ci piacerebbe mostrare dei messaggi di errore per chiedere all'utente di correggere i dati, come mostrato in figura 2-1.

Figura 2-1 - Mostrare i messaggi di errore

Mostrare i messaggi di errore

Ecco le regole di validazione da implementare per la form di contatto:

  • name : opzionale
  • email : obbligatoria, il valore deve essere un indirizzo email valido
  • subject: obbligatorio, il valore scelto deve essere compreso in una lista di valori
  • message: obbligatorio, la lunghezza del messaggio deve essere almeno di quattro caratteri

NOTE Perché abbiamo bisogno di validare il campo subject? Il tag <select> costringe già l'utente ad un elenco di valori predefiniti. Un utente medio può solo scegliere una delle opzioni mostrate, ma altri valori possono essere inviati usando degli strumenti come l'estensione Web Developer di Firefox, oppure simulando una richiesta con strumenti come curl o wget.

Il Listato 2-1 mostra il template che abbiamo usato nel Capitolo 1.

Listato 2-1 - Il template della form di contatto

// apps/frontend/modules/contact/templates/indexSucces.php
<form action="<?php echo url_for('contact/index') ?>" method="post">
  <table>
    <?php echo $form ?>
    <tr>
      <td colspan="2">
        <input type="submit" />
      </td>
    </tr>
  </table>
</form>

La Figura 2-2 evidenzia l'interazione tra applicazione e utente. Il primo passo è presentare la form all'utente. Quando l'utente invia la form, o i dati sono validi e l'utente viene rimandato alla pagina di ringraziamento, oppure i dati hanno dei valori non validi e la form viene mostrata di nuovo con i messaggi di errore.

Figura 2-2 - Interazione tra applicazione e utente

Interazione tra applicazione e utente

Validatori

Una form in symfony è fatta di campi. Ciascun campo può essere identificato da un nome univoco, come osservato nel Capitolo 1. Abbiamo connesso un widget ad ogni campo per poterlo mostrare all'utente, ora vediamo come possiamo applicare le regole di validazione a ciascun campo.

La classe sfValidatorBase

La validazione di ogni campo viene fatta da oggetti che ereditano dalla classe sfValidatorBase. Per poter validare la form di contatto, dobbiamo definire gli oggetti validatori per ognuno dei quattro campi: name, email, subject, e message. Il Listato 2-2 mostra l'implementazione di tali validatori nella classe form usando il metodo setValidators().

Listato 2-2 - Aggiungere validatori alla classe ContactForm

[php]
// lib/form/ContactForm.class.php
class ContactForm extends sfForm
{
  protected static $subjects = array('Subject A', 'Subject B', 'Subject C');

  public function configure()
  {
    $this->setWidgets(array(
      'name'    => new sfWidgetFormInput(),
      'email'   => new sfWidgetFormInput(),
      'subject' => new sfWidgetFormSelect(array('choices' => self::$subjects)),
      'message' => new sfWidgetFormTextarea(),
    ));
    $this->widgetSchema->setNameFormat('contact[%s]');

    $this->setValidators(array(
      'name'    => new sfValidatorString(array('required' => false)),
      'email'   => new sfValidatorEmail(),
      'subject' => new sfValidatorChoice(array('choices' => array_keys(self::$subjects))),
      'message' => new sfValidatorString(array('min_length' => 4)),
    ));
  }
}

Usiamo tre diversi validatori:

  • sfValidatorString: valida una stringa
  • sfValidatorEmail : valida un'email
  • sfValidatorChoice: valida un valore che proviene da una lista predefinita

Ogni validatore accetta una lista di opzioni come primo argomento. Come i widget, alcune di queste opzioni sono obbligatorie, altre sono opzionali. Per esempio, il validatore sfValidatorChoice accetta un parametro obbligatorio, choices. Ogni validatore può anche accettare le opzioni required e trim, definite di default nella classe sfValidatorBase:

Opzione Valore predefinito Descrizione
required true Specifica se il campo è obbligatorio
trim false Rimuove automaticamente gli spazi bianchi dall'inizio e dalla fine di una stringa prima che avvenga la validazione

Vediamo le opzioni disponibili per i validatori che abbiamo appena usato:

Validatore Opzioni obbligatorie Opzioni non obbligatorie
sfValidatorString max_length
min_length
sfValidatorEmail schema
sfValidatorChoice choices

Se provi ad inviare la form con valori non validi, non vedrai alcun cambiamento nel comportamento. Dobbiamo aggiornare il modulo contact per validare i valori inviati, come mostrato nel Listato 2-3.

Listato 2-3 - Implementare la validazione nel modulo contact

[php]
class contactActions extends sfActions
{
  public function executeIndex($request)
  {
    $this->form = new ContactForm();

    if ($request->isMethod('post'))
    {
      $this->form->bind($request->getParameter('contact'));
      if ($this->form->isValid())
      {
        $this->redirect('contact/thankyou?'.http_build_query($this->form->getValues()));
      }
    }
  }

  public function executeThankyou()
  {
  }
}

Il Listato 2-3 introduce molti nuovi concetti:

  • In caso di richiesta GET iniziale, la form è inizializzata e passata al template da mostrare all'utente. La form quindi è in uno stato iniziale:

     $this->form = new ContactForm();
    
  • Quando l'utente invia la form con una richiesta POST, il metodo bind() lega la form ai dati utente ed attiva il meccanismo di validazione. La form quindi cambia in uno stato vincolato.

    if ($request->isMethod('post'))
    {
       $this->form->bind($request->getParameter('contact'));
    
  • Una volta che la form è vincolata, è possibile verificare la sua validità usando il metodo isValid():

    • Se il valore restituito è true, la form è valida e l'utente può essere rimandato alla pagina di ringraziamento:

      if ($this->form->isValid()) { $this->redirect('contact/thankyou?'.http_build_query($this->form->getValues())); }

    • Altrimenti, il template indexSuccess viene mostrato come all'inizio. Il processo di validazione aggiunge dei messaggi di errore nella form, da mostrare all'utente.

NOTE Quando una form è in uno stato iniziale, il metodo isValid() restituisce sempre false ed il metodo getValues() restituirà sempre un'array vuota.

La Figura 2-3 mostra il codice che viene eseguito durante l'interazione tra applicazione e utente.

Figura 2-3 - Codice eseguito durante l'interazione tra applicazione e utente

Codice eseguito durante l'interazione tra applicazione e utente

Lo scopo dei validatori

Forse hai notato che durante la redirezione alla pagina di ringraziamento, non abbiamo usato $request->getParameter('contact'), ma $this->form->getValues(). Infatti, $request->getParameter('contact') restituisce i dati utente quando $this->form->getValues() restituisce i dati validati.

Se la form è valida, perché questi due comandi non sono identici? Ogni validatore in realtà ha due compiti: uno di validazione, ma anche uno di pulizia. Il metodo getValues() infatti restituisce i dati validati e puliti.

Il processo di pulizia ha due azioni principali: normalizzazione e conversione dei dati immessi.

Abbiamo già visto un caso di normalizzazione dei dati con l'opzione trim. Ma l'azione della normalizzazione è molto più importante ad esempio per un campo data. sfValidatorDate valida una data. Questo validatore accetta diversi formati in entrata (un timestamp, un formato basato su espressione regolare, ...). Invece di restituire semplicemente il valore immesso, lo converte di default nel formato Y-m-d H:i:s. Quindi, lo sviluppatore ha la garanzia di ottenere un formato stabile, quale che sia il formato immesso. Questo sistema offre molta flessibilità all'utente ed assicura coerenza allo sviluppatore.

Ora, consideriamo un'azione di conversione, come l'invio di un file. La validazione di un file può essere fatta usando sfValidatorFile. Una volta che il file è stato caricato, invece di restituire il nome del file, il validatore restituisce un oggetto sfValidatedFile, rendendo più facile gestire le informazioni sul file. Vedremo più avanti in questo capitolo come usare questo validatore.

TIP Il metodo getValues() restituisce un'array di tutti i dati validati e puliti. Ma se serve recuperare un solo valore, c'è anche il metodo getValue(): $email = $this->form->getValue('email').