Filtrer les résultats sur le caractère NULL ou NOT NULL d'un champ dans Symfony

De e-glop
Révision datée du 7 juin 2010 à 12:29 par BeTa (discussion | contributions)
(diff) ← Version précédente | Voir la version actuelle (diff) | Version suivante → (diff)

Présentation de la problématique

Un module généré par :generate-admin dans Symfony ne propose pas la solution de filtrer sur le caractère NULL ou NOT NULL par défaut. Au mieux, un champ texte peut être marqué "vide", mais jamais "non-vide".

Ici l'exemple portera sur un champ FOREIGN KEY d'une table... dont on voudrait pouvoir trier les enregistrements liés à la table "étrangère" ou non... voire de ne rien filtrer du tout.

L'exemple porte sur un module doctrine:generate-admin, et ne s'applique pas forcément de la même manière à Propel.

Solution

Remplacer le widget présent

Ici il s'agit du widget adhesion_id :

$this->widgetSchema['adhesion_id'] = new sfWidgetFormChoice(array(
  'choices' => array('on' => 'Non','off' => 'Oui',  => 'N/A'),
  'expanded' => true,
));
$this->validatorSchema['adhesion_id'] = new sfValidatorString();

Créer une fonction spécifique pour générer la requête

Puisque le champ est une clé étrangère, la fonction visée sera donc addForeignKeyQuery(), mais vous pourrez avoir à chercher la vôtre dans la classe sfFormFilterDoctrine que l'on trouve ici : lib/vendor/symfony/lib/plugins/sfDoctrinePlugin/lib/form/sfFormFilterDoctrine.class.php.

Nous allons donc spécialiser la méthode dans la classe du FilterForm de notre composant, ici EntrepriseFormFilter (lib/filter/doctrine/EntrepriseFormFilter.class.php) pour le champ adhesion_id :

protected function addForeignKeyQuery(Doctrine_Query $query, $field, $value)
{
  $fieldName = $this->getFieldName($field);
  
  if ( $fieldName == 'adhesion_id' )
  {
    if ( $value == 'on' )
      $query->addWhere('r.' . $fieldName . ' IS NULL');
    else if ( $value == 'off' )
      $query->addWhere('r.' . $fieldName . ' IS NOT NULL');
  }
  else
    parent::addForeignKeyQuery($query,$field,$value);
}

Ainsi, le "tour" est joué. Nous avons bien un champ Adhésion qui apparaît comme un ensemble de "radio buttons" reprenant : Adhérent ? oui, non, N/A, ce que nous cherchions. CQFD.