Filtres case-unsensitive dans Symfony : Différence entre versions

De e-glop
m
 
Ligne 53 : Ligne 53 :
 
         $query->addWhere('r.' . $fieldName . ' ILIKE ?', '%' . $values['text'] . '%');
 
         $query->addWhere('r.' . $fieldName . ' ILIKE ?', '%' . $values['text'] . '%');
 
       }
 
       }
 +
    }
 +
  }
 +
 +
== Aller plus loin : l'accentuation ==
 +
 +
Si vous souhaitez également ne pas tenir compte de l'accentuation, voici la méthode '''->addTextQuery()''' que vous pouvez avoir :
 +
 +
  public function addTextQuery(Doctrine_Query $query, $field, $values)
 +
  {
 +
    $fieldName = $this->getFieldName($field);
 +
   
 +
    if (is_array($values) && isset($values['is_empty']) && $values['is_empty'])
 +
    {
 +
      $query->addWhere(sprintf('(%s.%s IS NULL OR %1$s.%2$s = ?)', $query->getRootAlias(), $fieldName), array(''));
 +
    }
 +
    else if (is_array($values) && isset($values['text']) && '' != $values['text'])
 +
    {
 +
      $query->addWhere(
 +
        sprintf("LOWER(translate(%s.%s,
 +
            'ŠŒŽšœžŸ¥µÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýÿ',
 +
            'SOZsozYYuAAAAAAACEEEEIIIIDNOOOOOOUUUUYsaaaaaaaceeeeiiiionoooooouuuuyy')
 +
          ) LIKE LOWER(?)", $query->getRootAlias(), $fieldName),
 +
        '%'.iconv('UTF-8', 'ASCII//TRANSLIT', $values['text']).'%'
 +
      );
 
     }
 
     }
 
   }
 
   }

Version actuelle datée du 11 janvier 2011 à 17:16

Problématique

 Environnement : Symfony 1.2 - sfDoctrinePlugin
 Contexte : modules doctrine:generate-admin
 Problème : filtres sensibles à la casse (case-sensitive)
 Objectif : rendre les filtres insensibles à la casse (case-unsensitive)

Analyse

Toutes les classes issues de sfFormFilter héritent de la classe BaseFormFilter modifiable dans chaque projet. Dans le cas de Doctrine, sfFormFilterDoctrine et BaseFormFilterDoctrine. Cette classe "Base" se trouve ici :

 lib/filter/doctrine/BaseFormFilterDoctrine.class.php

La méthode en cause est celle qui traite des champs texte. La ligne incriminée est la ligne 209 du fichier symfony/lib/plugins/sfDoctrinePlugin/lib/form/sfFormFilterDoctrine.class.php :

 $query->addWhere('r.' . $fieldName . ' LIKE ?', '%' . $values['text'] . '%');

Une solution serait donc de surcharger la méthode en question afin de faire un ILIKE à la place du LIKE.

Solution

Surcharger la méthode addTextQuery() de la classe sfFormFilterDoctrine dans la classe BaseFormFilterDoctrine. Voici donc à quoi ressemblera votre classe si vous n'avez pas fait d'autres modifications :

 # lib/filter/doctrine/BaseFormFilterDoctrine.class.php
 /**
  * Project filter form base class.
  *
  * @packagefilters
  *
  * @versionSVN: $Id: sfDoctrineFormFilterBaseTemplate.php 11675 2008-09-19 15:21:38Z fabien $
  */
 abstract class BaseFormFilterDoctrine extends sfFormFilterDoctrine
 {
   public function setup()
   {
   }
 
   // totally inspirated from lib/vendor/symfony/lib/plugins/sfDoctrinePlugin/lib/form/sfFormFilterDoctrine.class.php
   // function addTextQuery()
   // line modified : 209
   // be careful on symfony updates to update this method if there are changes
   protected function addTextQuery(Doctrine_Query $query, $field, $values)
   {
     $fieldName = $this->getFieldName($field);
     
     if (is_array($values) && isset($values['is_empty']) && $values['is_empty'])
     {
       $query->addWhere('r.' . $fieldName . ' IS NULL');
     }
     else if (is_array($values) && isset($values['text']) && $values['text'])
     {
       // Here is the change, with "ILIKE" instead of "LIKE"
       $query->addWhere('r.' . $fieldName . ' ILIKE ?', '%' . $values['text'] . '%');
     }
   }
 }

Aller plus loin : l'accentuation

Si vous souhaitez également ne pas tenir compte de l'accentuation, voici la méthode ->addTextQuery() que vous pouvez avoir :

 public function addTextQuery(Doctrine_Query $query, $field, $values)
 {
   $fieldName = $this->getFieldName($field);
   
   if (is_array($values) && isset($values['is_empty']) && $values['is_empty'])
   {
     $query->addWhere(sprintf('(%s.%s IS NULL OR %1$s.%2$s = ?)', $query->getRootAlias(), $fieldName), array());
   }
   else if (is_array($values) && isset($values['text']) &&  != $values['text'])
   {
     $query->addWhere(
       sprintf("LOWER(translate(%s.%s,
           'ŠŒŽšœžŸ¥µÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýÿ',
           'SOZsozYYuAAAAAAACEEEEIIIIDNOOOOOOUUUUYsaaaaaaaceeeeiiiionoooooouuuuyy')
         ) LIKE LOWER(?)", $query->getRootAlias(), $fieldName),
       '%'.iconv('UTF-8', 'ASCII//TRANSLIT', $values['text']).'%'
     );
   }
 }

In English

http://snippets.symfony-project.org/snippet/344