Bonjour à tous,

Voila quelques temps que j'ai suivi la série de tutos "Créer un site web de A à Z" en PHP.
Cela m'a beaucoup aidé pour mon projet mais je bloque désormais sur une chose depuis pas mal de temps maintenant.

J'ai créé un formulaire d'inscription dans lequel l'utilisateur doit renseigner un pseudo et une adresse mail.
Mon soucis vient de la validation de ce formulaire. J'aimerais qu'il y ait un message d'erreur lorsque le pseudo est déjà existant en bdd, quand le format est invalide ... et de même pour l'adresse mail.

J'ai jeté un oeil sur les tutos "Créer un site web avec CakePHP" et j'ai vu que cela se gérait très facilement (avec des required = true...). J'ai donc essayer de comprendre la fonctions validates() de CakePHP mais je dois avouer que j'ai du mal. Et je ne veux pas utiliser CakePHP pour le moment.

Du coup je m'en remet à vous pour m'aiguiller un peu dans la bonne direction car je ne sais pas du tout comment m'y prendre.
En tout cas merci de m'avoir lu.

11 réponses


Moi aussi j'ai voulu la même chose et donc dans le model tu crée une variable comme ceci:

public $validate = array(
    'username' => array(
           'required' => true
    )
);

Puis dans ta page model.php tu test si $this->validate est existant puis la tu fais un traitement avec des foreach pour parcourir ton tableau.

Moi je me suis arrêté ici pour l'instant donc je pourrais pas trop t'aider sur le reste mais ça fonctionne chez moi du moins moi j'ai modifié la structure MVC de Grafikart pour ajouter un AppModel et un AppController.

Je peux te dire que après CakePhp il test si required est à true et si la règle est ok puis il test le empty si c'est ok puis après il font tout les autre traitement.

Mais j'ai pas encore découvert comment il renvoi les erreurs au helpers Form pour les afficher.

gwena
Auteur

Je te remercie djtec de m'aider. Bon je vais déjà me pencher sur ce que tu me conseilles. Je t'en remercie.
Si quelqu'un a d'autres idées je suis preneur ;)

Pour te donner encore une autre idée voici le validate que je fais:

public $validate = array(
        'add' => array( // Action add membre
            'title' => array(
                'rule' => array(
                    'allowEmpty' => true,
                    'required' => true
                )
            ),
            'date' => array( // Là le type se définit automatiquement en datetime
                'rule' => array(
                    'required' => true
                )
            ),
            'duration' => array(
                'rule' => array(
                    'type' => 'numeric', // Là je vérifie si la variable est numérique
                    'required' => true
                )
            )
        ),

        'admin' => array( // Si préfix admin alors panneau d'admin
            'add' => array( // Action add admin
                'title' => array(
                    'rule' => array(
                        'required' => true
                    )
                )
            )
        )
    );

Avec mon validate ça me permet de faire des validates différent pour un membre ou sur le panneau d'admin et aussi de faire différent validates suivant l'action ou est le formulaire.

Voilà si cela peut t'aider à faire ce que tu désire.

gwena
Auteur

Voila c'est un peu ce que j'avais en tête un moment donné mais le truc c'est que j'ai du mal à modifier la fonction validates() du model.php en conséquence...
Va falloir mettre les mains dans le cambouie ;)

Oui déjà il faut passer la variable request au model pour pouvoir voir si on est sur admin puis faire une fonction _validate() puis lui envoyer le tableau des rules pour faire le traitement au début du save.

Le truc le plus chiant ça va être d'envoyer les erreurs au helper form, j'ai regardé un peu celui de cake et si j'ai bien compris il appel le model dans le helper pour voir si y a des erreurs dans le validate mais pour moi cette partie est encore un peu flou.

Moi je pense continuer ça se soir donc ça t'as besoin d'aide ou que tu trouve une solution dit le moi :)

gwena
Auteur

dac je te tiens au courant si j'ai du nouveau.
Merci de ton aide c'est cool

Salut gwena je viens au nouvelle pour savoir ou tu en es ???

gwena
Auteur

Salut djtec.
Et bien pour le moment je suis toujours bloqué mais j'avance peut-être un peu.
Mes validations situées dans mon model ('User' ici) se présentent sous cette forme désormais :

<?php
class User extends Model
{
    var $validate = array(
        'signup' => array(
            'username' => array(
                array(
                    'rule' => 'notEmpty',
                    'message' => 'Vous devez saisir un pseudo'
                ),
                array(
                    'rule' => '([a-z0-9\-]+)',
                    'message' => 'Format pseudo invalide'
                )   
            ),
            'email' => array(
                array(
                    'rule' => 'notEmpty',
                    'message' => 'Vous devez saisir une adresse mail'
                ),
                array(
                    'rule' => '([a-z0-9\-]+)',
                    'message' => 'Format mail invalide'
                )   
            )
        ),
        'login' => array(
            'username' => array(
                array(
                    'rule' => 'notEmpty',
                    'message' => 'Vous devez saisir un pseudo'
                ),
                array(
                    'rule' => '([a-z0-9\-]+)',
                    'message' => 'Format pseudo invalide'
                )   
            ),
            'password' => array(
                array(
                    'rule' => 'notEmpty',
                    'message' => 'Vous devez saisir un mot de passe'
                ),
                array(
                    'rule' => '([a-z0-9\-]+)',
                    'message' => 'Mot de passe invalide'
                )
            )
        )
    );
}

Et dans la fonction validates() de Model.php (dans le core), j'ai décidé qu'il fallait renseigner l'action dans les paramètres.
Ca donne ça donc :

/**
* Permet de valider des données
* @param $data données à valider 
**/
function validates($data, $action){
...
}

Et maintenant lorsque je veux lui faire appelle pour le traitement d'un formulaire, je fais comme ceci :

/**
* Permet à un utilisateur de créer son compte
**/
function signup()
{
    ...
    if($this->request->data)
    {
        $data = $this->request->data;
        $this->loadModel('User');
        if($this->User->validates($data, 'signup'))
        {
            ...
        }
        else
        {
            $this->Session->setFlash('Merci de corriger vos informations', 'error');
        }
    }
}

Mais pour l'instant je n'ai toujours pas réussi à faire fonctionner le script avec cette méthode. Je dois dire que je patoge pas mal ^^.
Je sais pas si tu vois un peu ce que je veux faire ? Dis-moi si tu crois que je suis sur la bonne voie ou si je me plante complètement. Les autres pareil n'hésitez pas à me dire ça m'aiderait beaucoup.

Salut je vois bien comment tu es partit je sais pas si ta un meilleur code que moi car moi je suis partit dans un truc de fou idem a cakephp et j'ai réussi à faire fonctionner mon code et à transmettre les erreurs au helpers form mais je pense que je suis partit dans du trop compliqué mais ça marche jte montre ça se soit des que je suis devant mon Pc.

gwena
Auteur

ok dac c'est gentil de ta part. Je suis curieux de voir ça ;)

Alors voici mon validates:

public $validate = array(
        'add' => array(
            'title' => array(
                'rule' => array(
                    'type' => 'string',
                    'required' => true
                )
            )
        ),

        'admin_add' => array(
            'title' => array(
                'rule' => array(
                    'required' => true,
                    'allowEmpty' => true
                ),
                'message' => array(
                    'required' => 'Le champ titre est requis',
                    'allowEmpty' => 'Veuillez remplir le champ titre'
                )
            ),
            'category_id' => array(
                'rule' => array(
                    'required' => true,
                    'comparison' => array('notequal', 0)
                ),
                'message' => array(
                    'required' => 'Le champ catégorie est requis',
                    'comparison' => 'Veuillez remplir le champ catégorie'
                )
            )
        ),
        'admin_edit' => array(
            'title' => array(
                'rule' => array(
                    'required' => true,
                    'allowEmpty' => true
                ),
                'message' => array(
                    'required' => 'Le champ titre est requis',
                    'allowEmpty' => 'Veuillez remplir le champ titre'
                )
            )
        )
    );

Ensuite dans le dans Model.php je vérifie si une variable $validates existe dans mon model puis j'explore mon tableau comme ceci:

if($this->validate) {
            $this->data = $data;
            $d = get_object_vars($this->data);

            if($this->request->prefix) {
                if($this->request->action != 'edit') {
                    $a = $this->request->action;
                } elseif($this->request->action == 'edit' && $d$this->primaryKey] != null) {
                    $a = $this->request->prefix.'_edit';
                } else {
                    $a = $this->request->prefix.'_add';
                }
            } else {
                if($this->request->action != 'edit') {
                    $a = $this->request->action;
                } elseif($this->request->action == 'edit' && $d$this->primaryKey] != null) {
                    $a = 'edit';
                } else {
                    $a = 'add';
                }
            }
            if(isset($this->validate$a])) {
                $valid = $this->_validates($a, $this->validate$a]);
            }
        }

Puis je verifie si ma fonction _validates me return true ou false pour savoir si j'exécute ma requête ou pas.
Voici la fonction:

public function _validates($action, $tab) {
        $valid = array();

        foreach($tab as $field => $rules) {
            if(isset($rules'message'])) {
                $message = $rules'message'];
                unset($rules'message']);
            } else {
                $message = null;
            }
            if(!is_array($rules) || (is_array($rules) && isset($rules'rule']))) {
                $rules = array('rule' => $rules);
            }
            $rules = current($rules);
            foreach($rules'rule'] as $k => $v) {
                $d = get_object_vars($this->data);
                $valid] = call_user_func_array(array('Validate', $k), array($field, $v, $d$field], (isset($message$k])) ? $message$k] : null));
            }
        }

        if(in_array(false, $valid, true)) {
            $this->validateError] = call_user_func(array('Validate', '_return'));
            return false;
        } else {
            return true;
        }
    }

Après ça se corse j'ai modifié pas mal le MVC pour transmettre le request au helper Form.
Ensuite dans le helper Form je fais comme ceci:

public function getModel() {
        if($this->controller->model[1]'return']->validateError) {
            $this->error = current($this->controller->model[1]'return']->validateError);
        }
    }
    public function input($name, $label, $opt = array()) {
        $errorClass = '';
        $errorMessage = false;
        if($this->controller->request->isPost) {
            $this->getModel();

            if($this->error) {
                $n = count($this->error);

                if(preg_match("#([a-zA-Z]+)#", $name, $match)) {
                    $field = $match[0];
                } else {
                    $field = $name;
                }
                for($i = 0; $i < $n; $i++) {
                    if($field == $this->error$i]'field']) {
                        $errorClass = ' error';
                        $errorMessage = $this->error$i]'message'];
                    }
                }
            }
        }
        // le reste du code pour mes inputs
    }

En faites au moment ou le input se crée j'interroge le model pour savoir si des erreurs existent et si oui je traite mon tableau des erreurs pour voir quel champs est erroné pour lui affiché l'erreur.

Je t'avoue que j'ai bossé pendant 2 jours pour arrivé à se résultat mais je cherche toujours si y a pas un moyen plus facile pour y arrivé.