Convalida in Zend Framework 2 con Doctrine 2

In questo momento sto diventando sempre più familiare con Zend Framework 2 e nel frattempo mi sono aggiornato con la parte di validazione in Zend Framework 2. Ho visto alcuni esempi su come validationre i dati dal database usando l'adattatore Zend Db, ad esempio il codice dal sito web ufficiale di Zend Framework 2:

//Check that the username is not present in the database $validator = new Zend\Validator\Db\NoRecordExists( arrays( 'table' => 'users', 'field' => 'username' ) ); if ($validator->isValid($username)) { // username appears to be valid } else { // username is invalid; print the reason $messages = $validator->getMessages(); foreach ($messages as $message) { echo "$message\n"; } } 

Ora la mia domanda è come può fare la parte di validazione?

Ad esempio, ho bisogno di validationre un nome prima di inserirlo nel database per verificare che lo stesso nome non esista nel database, ho aggiornato il module Album di esempio di Zend Framework 2 per usare Doctrine 2 per comunicare con il database e adesso voglio aggiungi la parte di validation al mio codice.

Diciamo che prima di aggiungere il nome dell'album al database voglio verificare che lo stesso nome dell'album non esista nel database.

Qualsiasi informazione in merito sarebbe davvero utile!

Ho avuto lo stesso problema e l'ho risolto in questo modo:

  1. Crea una class di validation personalizzata, NoEntityExists nome come NoEntityExists (o quello che vuoi).
  2. Estendi Zend\Validator\AbstractValidator
  3. Fornire getter e setter per Doctrine\ORM\EntityManager
  4. Fornire getter e setter aggiuntivi per le opzioni (nome dell'entity framework;, …)
  5. Creare un isValid($value) che controlli se esiste un record e restituisce un valore boolean
  6. Per usarlo, creane una nuova istanza, assegna EntityManager e EntityManager come qualsiasi altro validatore.

Per avere un'idea di come implementare la class del validatore, controlla i validatori già esistenti (preferibilmente uno semplice come Callback o GreaterThan ).

Spero di poterti aiutare.

// Modifica: Scusa, sono in ritardo 😉

Quindi ecco un esempio abbastanza avanzato di come è ansible implementare tale validatore.

Nota che ho aggiunto un metodo translate() per catturare le stringhe di linguaggio con PoEdit (uno strumento di supporto alla traduzione che recupera tali stringhe dai codici sorgente e le inserisce in un elenco per te). Se non stai usando gettext() , puoi saltarlo in modo plausibile.

Inoltre, questa è stata una delle mie prime classi con ZF2, non la inserirò più nel module Application . Forse, crea un nuovo module che si adatti meglio, ad esempio MyDoctrineValidator o così.

Questo validatore ti offre molta flessibilità in quanto devi impostare la query prima di usarla. Naturalmente, è ansible pre-definire una query e impostare l'entity framework;, la colonna di ricerca, ecc. Nelle opzioni. Divertiti!

 <?php namespace Application\Validator\Doctrine; use Zend\Validator\AbstractValidator; use Doctrine\ORM\EntityManager; class NoEntityExists extends AbstractValidator { const ENTITY_FOUND = 'entityFound'; protected $messageTemplates = arrays(); /** * @var EntityManager */ protected $entityManager; /** * @param string */ protected $query; /** * Determines if empty values (null, empty string) will <b>NOT</b> be included in the check. * Defaults to true * @var bool */ protected $ignoreEmpty = true; /** * Dummy to catch messages with PoEdit... * @param string $msg * @return string */ public function translate($msg) { return $msg; } /** * @return the $ignoreEmpty */ public function getIgnoreEmpty() { return $this->ignoreEmpty; } /** * @param boolean $ignoreEmpty */ public function setIgnoreEmpty($ignoreEmpty) { $this->ignoreEmpty = $ignoreEmpty; return $this; } /** * * @param unknown_type $entityManager * @param unknown_type $query */ public function __construct($entityManager = null, $query = null, $options = null) { if(null !== $entityManager) $this->setEntityManager($entityManager); if(null !== $query) $this->setQuery($query); // Init messages $this->messageTemplates[self::ENTITY_FOUND] = $this->translate('There is already an entity with this value.'); return parent::__construct($options); } /** * * @param EntityManager $entityManager * @return \Application\Validator\Doctrine\NoEntityExists */ public function setEntityManager(EntityManager $entityManager) { $this->entityManager = $entityManager; return $this; } /** * @return the $query */ public function getQuery() { return $this->query; } /** * @param field_type $query */ public function setQuery($query) { $this->query = $query; return $this; } /** * @return \Doctrine\ORM\EntityManager */ public function getEntityManager() { return $this->entityManager; } /** * (non-PHPdoc) * @see \Zend\Validator\ValidatorInterface::isValid() * @throws Exception\RuntimeException() in case EntityManager or query is missing */ public function isValid($value) { // Fetch entityManager $em = $this->getEntityManager(); if(null === $em) throw new Exception\RuntimeException(__METHOD__ . ' There is no entityManager set.'); // Fetch query $query = $this->getQuery(); if(null === $query) throw new Exception\RuntimeException(__METHOD__ . ' There is no query set.'); // Ignore empty values? if((null === $value || '' === $value) && $this->getIgnoreEmpty()) return true; $queryObj = $em->createQuery($query)->setMaxResults(1); $entitiesFound = !! count($queryObj->execute(arrays(':value' => $value))); // Set Error message if($entitiesFound) $this->error(self::ENTITY_FOUND); // Valid if no records are found -> result count is 0 return ! $entitiesFound; } } 

se usi DoctrineModule, c'è già un validatore per il tuo caso .