Toutes les données saisies par un utilisateur dans un formulaire web doivent être contrôlées.

 

Le Zend Framework fourni des outils permettant de filtrer et valider ces données. 

Mais nouvelle version du framework en propose une gestion complètement différente de ce à quoi nous avait habitué ZF1.

  • Dans la première version, les données étaient saisies et validées par le formulaire avant d'être affectées à notre entité métier.
  • Dorénavant, les données sont saisies par le formulaire et validées par l'entité.

 

Cette nouvelle architecture se veut beaucoup plus proche de la logique MVC, les données et leurs filtres/validateurs sont concentrés dans une même classe: notre entité.

Nous allons voir comment mettre en place ces contrôles dans l'entité, dans un formulaire et utiliser le tout dans notre contrôleur.

L'entité métier

Notre classe devra implémenter InputFilterAwareInterface.

Cette interface nous oblige à définir deux méthodes:

  • public function setInputFilter(InputFilterInterface $inputFilter);
  • public function getInputFilter()

Voici un exemple sur une classe vide:

use Zend\InputFilter\Factory as InputFactory;
use Zend\InputFilter\InputFilter;
use Zend\InputFilter\InputFilterAwareInterface;
use Zend\InputFilter\InputFilterInterface;

/**
 * Classe exemple d'implémentation de InputFilterAwareInterface
 * 
 * @author Bidoum
 */
class maClasse implements InputFilterAwareInterface
{
	/**
	 * @var InputFilter
	 */
	private $_inputFilter;

	// [...]
	
	/**
	 * Définit les filtres
	 * Non utilisé
	 * @param InputFilterInterface $inputFilter
	 * @throws \Exception
	 */
	public function setInputFilter(InputFilterInterface $inputFilter)
	{
		throw new \Exception("Not used");
	}
	
	/**
	 * Obtient les filtres de contenu
	 * @return \Zend\InputFilter\InputFilter
	 */
	public function getInputFilter()
	{
		if (!$this->_inputFilter) {
			$inputFilter = new InputFilter();
			$factory     = new InputFactory();
			
			//@todo Implémenter les filtres
			
			$this->_inputFilter = $inputFilter;
		}
		
		return $this->_inputFilter;
	}	
}

 Les filtres et validateurs pourront être définis au tag indiqué par @todo

Le formulaire

Notre formulaire doit normalement déjà hériter de Zend\Form\Form, lui même implémentant Zend\Form\FormInterface et donc définissant les deux méthodes vues plus haut:

  • public function setInputFilter(InputFilterInterface $inputFilter);
  • public function getInputFilter()

Il n'y a donc rien à ajouter dans le formulaire.

use Zend\Form\Form;

class monForm extends Form
{
	
}

 Le contrôleur

Voici un exemple commenté.

Si je reçois des données, j'affecte à mon formulaire les filtres et validateurs de mon entité ainsi que les données reçues. Le traitement ne doit continuer que si tout est valide.

use Zend\Mvc\Controller\AbstractActionController;

/**
 * Contrôleur exemple d'utilisation des InputFilter
 * 
 * @author Bidoum
 */
class IndexController extends AbstractActionController
{
	/**
	 * Action de création ou modification de maClasse
	 * @return \Zend\Http\Response|\Zend\View\Model\ViewModel
	 */
	public function editAction()
	{
		// Mon formulaire
		$form = new monForm();
		// Ma classe
		$class = new maClasse();
		
		// Les données éventuellement reçues
		$request = $this->getRequest();
		
		if($request->isPost()){
			// C'est une soumission de formulaire
			
			// J'affecte à mon formulaire les InputFilter de ma classe et les données reçues
			$form->setInputFilter(	$class->getInputFilter());
			$form->setData(			$request->getPost());
			
			if($form->isValid()){
				// Les données reçues passent la validation
				
				//@todo Sauvegarder en BDD
			}
		
		}else{ // isPost() = false
			// C'est une création ou modification
		}
		
		return new ViewModel(array(
			'form' => $form
		));
	}
}

Quelques exemples

Des filtres et validateurs, à insérer dans notre entité

Un entier, obligatoire

$inputFilter->add($factory->createInput(array(
	'name'     => 'id',
	'required' => true,
	'filters'  => array(
		array('name' => 'Int'),
	),
)));

 Un pseudo entre 1 et 25 caractères

$inputFilter->add($factory->createInput(array(
	'name'     => 'pseudo',
	'required' => true,
	'filters'  => array(
		array('name' => 'StripTags'),
		array('name' => 'StringTrim'),
	),
	'validators' => array(
		array(
			'name'    => 'StringLength',
			'options' => array(
				'encoding' => 'UTF-8',
				'min'      => 1,
				'max'      => 25,
			),
		),
	),
)));