Bonjour,
Je cherche à mettre en place une simple règle de validation pour mon formulaire de recherche. Ce dernier apparaît sur toutes les pages de mon site. Pour cela, avec l'aide de la doc et des infos glannés ici et là :
Mon model :

<?php
    class Home extends AppModel {
        public $validate = array('search' => 'alphaNumeric');   
}
?>

Mon controller

function resultSearch(){

            if( $this->Service->validate())
            {      
                $search = $this->data['Search']['search'];
                $search_optim = preg_replace("#[^a-zÀÁÂÃÄÅàáâãäåÒÓÔÕÖØòóôõöøÈÉÊËèéêëÇçÌÍÎÏìíîïÙÚÛÜùúûüÿÑñ?0-9]#i","", $search);
                $this->set('search', $search);

                if(isset($search) && ($search != NULL))
                {
                    $search_results = $this->Service->query("SELECT * FROM services WHERE title LIKE '%$search_optim%' OR type LIKE '%$search_optim%'");
                    $nb_resultats = count($search_results);

                    $this->set('search_results', $search_results);
                    $this->set('nb_resultats', $nb_resultats);
                }
                else
                {
                    $this->Session->setFlash('Vous n\'avez rentré aucunes donnée !','error');
                }
            }
        }

Résultat, rien ne se passe lorque je rajoute```
if( $this->Home->validate())


Sans cela, la fonction marche comme je le souhaite.
Je penses que le problème viens du fait que mon model ne soit pas lié à une TABLE.
Une axe de réflexion svp ?
merci

13 réponses


Lartak
Réponse acceptée

C'est normal, c'est : public $validate et non public $validates, donc au passage, modifies comme-ceci :

public $validate = array(
    'search' => array(
        'rule' => 'email', 
        'required' => true, 
        'allowEmpty' => false
    )
);

Il est normal, que s'il ne trouve pas de fonction de validation, qu'il ne va pas l'appliquer. :)
Si possible, ajoutes la clé message et définis en un dans ta règle.

Pour utiliser le validate comme tu le fais, il me semble qu'il faut rajouter avant :

$this->Service->set($this->request->data);

http://book.cakephp.org/2.0/fr/models/data-validation/validating-data-from-the-controller.html

Bonjour.
D'après la fonction de recherche (resultSearch), la recherche s'effectue bien dans une table, donc, pourquoi ne pas mettre la règle de validation dans le modèle correspondant, c'est à dire le modèle Service pour commencer ?
Ensuite, pourquoi ne pas utiliser les structures de requêtes de CakePHP ?
La fonction est située dans quel controller ?
Il ne faut pas oublier que les règles de validation ne s'effectuent auomatiquement que lors d'enregistrement/sauvegarde en base de données et non sur une requête SELECT, il vaut donc déclencher la validation manuellement avec la méthode Validate.
Mais ça ne sert à rien de faire un :

$this->Service->validate()

Si les règles de validations ne sont pas définies dans le modèle Service, mais dans le modèle Home.

Je te recommande donc de placer la règle de validation dans le modèle concerné, c'est à dire dans le modèle Service, ensuite, dans la fonction de recherche situé dans le controller Services, mettre ceci :

$this->Service->set($this->request->data);
if ($this->Service->validates()) {
    /* Traitement si aucune erreur de validation */
} else {
    /* Sinon */
}

Pour résumer :

  1. Mettre les règles de validations dans le modèle concerné
  2. Remplacer $this->data par $this->request->data, car la première syntaxe n'est plus correcte depuis la version 2 de CakePHP
  3. La méthode de validation est validates et non validate, sans oublier que le modèle utilisé par la méthode doit comporter la/les règle(s) de validation(s)
  4. Ne pas oublier de passer les valeurs au modèle concerné avec la méthode set
  5. De préférence, utiliser la structure de requête SQL de CakePHP, surtout depuis un controller.

Exemple pour le n°5 :

$search_results = $this->Service->find('all', array(
    'conditions' => array(
        'OR' => array(
            'title LIKE' => '%' . $search_optim . '%', 
            'type LIKE' => '%' . $search_optim . '%'
        )
    )
));

Oui, j'ai vu cela. Et je suis sur cette voie depuis quelques temps maintenant : /
Voici mon controller Service

function resultSearch(){
            $this->Service->set($this->request->data);
            if ($this->Service->validates()) {
                var_dump('ok');
            } else {
                var_dump('error');
            }

et la règle de validation du model

class Service extends AppModel {    
        public $validates = array(
            'search' => 'email',
            'required'   => true,
        'allowEmpty' => false
    );
    }

Je fait exprés d'utiliser la règle 'email' pour les tests. Peut importe ce que j'envoie, le retour est toujours "ok" !!!

Peut-être cela viens de ma vue : en voici le code

<?php
            echo $this->Form->create('Search', array('url' => array(
            'controller' => 'Services',
            'action' => 'resultSearch'
            )));
            echo $this->Form->input('search', array('label' => false,'id'=>'search'));
            echo '<button><span class="icon-search"></span></button>';
            echo $this->Form->end();
?>

Merci encore

Remplaces :

$this->Form->create('Search'

Par :

$this->Form->create('Service'

Il est important de définir la bonne clé de modèle dans la méthode create du helper form.

Merci Lartak, je n'avais pas vu ton premier message. Pour ce qui est des structures SQL, elle ne sont vraiment pas simple je trouve à mettre en place, entre les UPDATE DELETE OR AND et compagnie mais je m'y met petit à petit.
Pour ce qui est de mon problème de formulaire recherche, au fil de la journée je suis arrivé à ce que vous venez de noter toi et Nohman. Cependant le HIC persiste...

Je n'ai pas changer le modèle , voici la fonction du controller :

function resultSearch(){

            $search = $this->data['Service']['search'];
            $search_optim = preg_replace("#[^a-zÀÁÂÃÄÅàáâãäåÒÓÔÕÖØòóôõöøÈÉÊËèéêëÇçÌÍÎÏìíîïÙÚÛÜùúûüÿÑñ?0-9]#i","", $search);
            $this->set('search', $search);
            $this->Service->set($this->request->data);

            if(isset($search) && ($search != NULL))
            {
                if ($this->Service->validates()) {
                    $search_results = $this->Service->find('all', array(
                    'conditions' => array(
                        'OR' => array(
                            'title LIKE' => '%' . $search_optim . '%', 
                            'type LIKE' => '%' . $search_optim . '%'
                        )
                        )
                    ));

                    $nb_resultats = count($search_results);

                    $this->set('search_results', $search_results);
                    $this->set('nb_resultats', $nb_resultats);
                        var_dump('ok');
                    } else {
                        var_dump('error');
                    }
            }
            else
            {
                $this->Session->setFlash('Vous n\'avez rentré aucunes donnée !','error');
            }

    }

Je pense que tu as oublié de modifier une ligne :

$search = $this->data['Service']['search'];

Par :

$search = $this->request->data['Service']['search'];

Quand tu dis que tu n'as pas changé le modèle, tu veux dire dans la méthode create du form helper ?
Si c'est le cas, tes données seront retournées avec $this->request->data['Search'] et non avec $this->request->data['Service'], ce qui va poser des problèmes à ton controller et ton modèle.

Le Model et les validations :

class Service extends AppModel {

        public $validates = array(
            'search' => 'email',
            'required'   => true,
        'allowEmpty' => false
    );  
    }

La vue :

<?php
            echo $this->Form->create('Service', array('url' => array(
            'controller' => 'Services',
            'action' => 'resultSearch'
            )));
            echo $this->Form->input('search', array('label' =>false,'id'=>'search'));
            echo '<button><span class="icon-search"></span></button>';
            echo $this->Form->end();
            ?>

Il me semble avoir apporté les modifications que tu recommandes.. Grr

Quel est ton problème exactement ?
La validation ne s'effectue pas du tout ?
As-tu installé le plugin DebugKit pour voir entre-autre s'il te retourne des erreurs de validations ou non ?

Je cherche à n'autoriser que les données alphaNuméric dans l'input de mon foirmulaire de recherche. Actuelement j'essai en testant la validation comme si c'était un émail. Cela ne marche pas puisque peut importe ce que je note, la fonction validates est tjs TRUE.

Sinon le debugkit ne me retourne aucune erreur.

Yep, merci Lartak.
Je vois cela et te fais le retour...Alala ces "S" alors...

Voici pour finir mon Model. C'était bien le 's' qui était de trop. Cela fonctionne à présent. Un grand merci à vous.
Pour le futur je chercherais à intégrer toute la logique de recherche dans un Component.
Merci encore
Bonne journée

<?php
    class Service extends AppModel {

        public $validate = array(
            'search' => array(
            'rule'=>'alphaNumeric',
            'required'   => true,
            'message'=>' Mon message d\'erreur !',
    ));

    }
?>