J'ai donc découvert une façon simple qui est de faire une méthode spéciale pour le champ concerné, qui consiste donc pour un champ "price" de crée la fonction addPriceColumnQuery($query, $field, $value) et qui devra retourner la requête ($query), ainsi de suite... mais ici je ne vous parlerai pas de cette manière de faire, après quelque recherche avec votre ami Google vous trouverez des articles pour ça (enfin si il y a une demande un article peut être possible...)
Le problème pour ceci est qu'il faudrait répéter l'opération pour tous les champs auxquels on voudrait appliquer cette modification, donc nous allons nous pencher sur une autre solution.

I discovered an easy way to do it by creating a specific method for a given field. For exemple for the price field we can create an addPriceColumnQuery($query, $field, $value) which add some selection criteria to the $query and return it. But I won't speak about this manner of doing. You can find some tips about this by searching on Google. (But perhaps I could write a post about it if someone need it.)
If we created a method for a field we need to do the same thing for each field on which we need to apply the change. So let's see another issue.

L'idée serait de renseigner dans notre champ l'opérateur voulu suivi de sa valeur, avec la possibilité d'utiliser les opérateurs suivant: "<", ">", "<=", ">=" et dans le cas où l'on ne saisie pas d'opérateur on utilise "=". On pourrai donc par exemple saisir: >200.

The idea would be to create something to allow us to write in the field the operator with the value. We could use the following operators: "<", ">", "<=", ">=" , and in the case of no operator we will use "=". So for exemple we could fill the field value with: >200.

Donc en fouillant d'avantage on remarque que les champs sont "typés" (voir BaseXXXFormFilter::getFields()) par exemple le champ prix est typé "Number" et que pour filtrer ce champ on fait appel à la fonction addNumberQuery dans sfFormFilterDoctrine.
Donc l'idée est de créer alors un nouveau type: "NumberOperator", de créer la fonction addNumberOperatorQuery qui sera appelé par Symfony lors du filtrage.

''So if we look at BaseXXXFormFilter we can see a getFields() method. This method describe the type for each field of the filter class. For exemple my price field has a "Number" type and so to filter this field symfony will automaticly call the addNumberQuery() method from the sfFormFilterDoctrine class.
So here the idea is to create a new type "NumberOperator" with an addNumberOperatorQuery() mehod and use this to filter the price field.''

Pour ceci on écrit notre fonction dans la classe BaseFormFilterDoctrine et on remercie Doctrine d'avoir pensé à cette classe ;)

To do this we add addNumberOperatorQuery() in BaseFormFilterDoctrine and we say thanks to Doctrine to generate this class ;)

/**
 * Project filter form base class.
 */
abstract class BaseFormFilterDoctrine extends sfFormFilterDoctrine
{
  const TYPE_NUMBER_OPERATOR = 'NumberOperator';

  public function setup()
  {
  }

  public function addNumberOperatorQuery(Doctrine_Query $query, $field, $values)
  {
    $fieldName = $this->getFieldName($field);
    $fields = $this->getFields();
    $type = $fields[$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'])
    {
      if(preg_match('/^(=|<=|>=|<|>)(.+)/', trim($values["text"]), $matches))
      {
        $query->addWhere('r.' . $fieldName . ' '.$matches[1].' ?', trim($matches[2]));
      }
      else
      {
        // Call the default function
        if(!method_exists($this, $method = sprintf('add%sQuery', $type)))
        {
          throw new LogicException(sprintf('Unable to filter for the "%s" type.', $type));
        }
        $query = $this->$method($query, $field, $values);
      }
    }
    return $query;
  }
}

Ensuite dans notre classe de filtre il faut modifier le type de notre champ et changer le validateur, un nouveau le cas échéant pour pouvoir aller avec notre nouvelle fonction crée auparavant.

Then in our filter class we need to change the field's type and also change the validator, a new one in this case just to check that the field value is something like operator+value.

/**
 * Product filter form.
 */
class ProductFormFilter extends BaseContactFormFilter
{
  public function configure()
  {
    //...
    // we use the new validator
    $this->validatorSchema['price'] = new sfValidatorSchemaFilter('text', new myValidatorNumberOperator(array('required' => false)));
    //...
  }

  public function getFields()
  {
    $fields = parent::getFields();

    $fields['price'] = BaseFormFilterDoctrine::TYPE_NUMBER_OPERATOR; // change the field type
    return $fields;
  }
}

Et notre nouveau validateur:
And so the new validator:

class myValidatorNumberOperator extends sfValidatorNumber
{
  protected function configure($options = array(), $messages = array())
  {
    $this->setMessage('invalid', '"%value%" is not a number "operator" (accepted symbols: "", "=", "<=", ">=", "<", ">").');
  }

  protected function doClean($value)
  {
    $compareSymbol = '';
    if(preg_match('/^(=|<=|>=|<|>)(.+)/', trim($value), $matches))
    {
      $compareSymbol = $matches[1];
      $numberValue   = $matches[2];
    }
    else
    {
      $numberValue = $value;
    }

    try {
      $cleanNumber = parent::doClean($numberValue);
    }
    catch (sfValidatorError $e) {
      throw new sfValidatorError($this, 'invalid', array('value' => $value));
    }

    return $compareSymbol.$cleanNumber;
  }
}

Ensuite pour pouvoir filtrer un prix il suffit de renseigner dans notre filtre pour un prix supérieur ou égal à 200 par exemple : ">=200".

Now to filter the price filed you can use values such as: ">=200".

Et en faisant cet article j'ai eu une autre idée faire un filtre qui filtrerai également une valeur suivant deux critères, explications rechercher par exemple un prix supérieur à 100 et inférieur à 300 : "100<x<300" à vos claviers ;)

Traduced by eNk`