Bonjour tout le monde !

J'ai un soucis avec Cake que je ne comprends pas trop.
Je suis en train de tester la validation de données d'un formulaire et ensuite update la base en fonction de ça.

J'ai donc quelques règles de validation dans un modèle User concernant le username et le password (username minimum 6 car, idem pour le pwd).
Là n'est pas le problème.

Le problème est qu'en voulant update des infos dans ma table autre que le username et le password, et bien j'ai une erreur remontée comme quoi le password est invalide.

Je fait appel au modele comme ceci :

if($this->User->save($userData)) { 
    //ok
}
else {
    //ko
}

Dans userData, il y a des données organisés dans ce style là

Array
(
    [User] => Array
        (
            [id] => 1
            [chp1] => "blabla"
            [chp1] => "blabla"
            [chp1] => "blabla"
            [chp1] => "blabla"
            [chp1] => "blabla"
               .
               .
               .
        )
    .
    .
    .
)

Ma question va être : comment structurer les infos à passer dans la méthode save() pour qu'il sache automatiquement modifier les champs que je lui donne et non pas ceux qu'il souhaite ?

Sachant que ailleurs sur le site sur lequel je bosse, il y a un autre formulaire du même type et j'ai bien fait attention de passer exactement la même structure à save() mais je n'ai pas le même résultat.

8 réponses


ccvf2s
Réponse acceptée

Bonjour,

ce que tu cherches à faire est bien expliqué dans l'api,
clique sur ce lien.

Petite doc save Api CakePhp

Soit mes variables

$username, $password, $chp1, $chp2, $chp3

Je veux enregistrer chp1,chp2 en outrepassant les validations.
Et en ne modifiant pas

$username, $password et $chp3

alors j'ai ceci :

$data = array(
'chp1' => $chp1,
'chp2' => $chp2
);
//troisième paramètre pour forcer l'enregistrement de chp1, chp2 et non autre chose.
$this->User->save($data,false,$data);
//Avec formulaire, et bien sur si je veux valider les paramètres je mettrai true au lieu de false.
$this->User->save($this->request->data,false,$data);

Je me permet de te donner ce conseil, lit de temps en temps ce qu'il y a dans L'API ou le Book
de ta version de CakePhp.

Superbement,
ccvf2s.

Si j ai bien compris tu voudrais updater les champs que tu souhaite.

Si oui, fais comme ceci:

$this->User->save(array(
    'chp1' => $this->request->data'User']'data1'],
    'chp2' => $this->request->data'User']'data2'],
    //etc
));

Oui tu as bien compris ma demande mikachu, mais apparemment ce n'est pas la bonne solution pour mon problème.
J'ai toujours l'erreur de validation du password qui remonte.

D'ailleurs, même en mettant un tableau vide j'ai cette erreur.
Et quand je passe par ce model cake, même si je ne met pas le password, il est quand modifié en base.

Ca vient peut être des devs qui étaient avant moi si l'erreur ne vient pas de cake mais logiquement, si une erreur de validation est remontée, la modification n'aurait jamais du être faite.

as tu tenté en enlevant la regle de validation pour le password ?
Ou tout simplement en rajoutant false dans le save poru éviter la verification.

DOCUMENTATION SUR LE SAVE

exemple:

$this->User->save(array(
        'chp1' => $this->request->data'User']'data1'],
        'chp2' => $this->request->data'User']'data2'],
        //etc
    ),
    false // ICI
);

Oui en enlevant la règle de validation, l'update est fait.
Je testerai demain en mettant false dans le save.

Bonjour,

Bon je debute en cakephp mais tu à la possibilité d'ajouter un 'on' dans la regle de validation qui te permet d'activer pour un create par exemple mais pas pour l'update :
http://api.cakephp.org/2.4/source-class-CakeValidationRule.html#192

Tiens je te rajoute un exemple :

public $validate = array(
    'fieldName1' => array(
        'rule' => 'ruleName',
        'required' => true,
        'allowEmpty' => false,
        'on' => 'create',
        'message' => 'Your Error Message'
    )
);

Cordialement

Je n'ai pas l'habitude de venir demander de l'aide sans faire des recherches auparavant :)

J'ai bien sur regarder le comportement sur l'api avant de venir, et d'ailleurs c'est pourquoi je suis ici.
Cependant, j'ai fait une erreur dans la présentation de mon problème, c'est que je n'ai pas précisé la version de cake que j'utilisais.

J'utilise (et je ne peux pas faire autrement) la version 1.3, et dans la version 1.3, CakeTestModel n'existe pas.
Je me suis donc contenté de la doc de la validation de données sur le book et par contre là, en effet, j'ai survolé la doc de la méthode save (api).

Pour revenir au problème, j'ai essayé en mettant le false dans le param de validation comme ceci :

if($this->User->save($this->data, false)) {
...
}

Ok la validation n'est pas faite mais ce n'est pas le comportement voulu parce qu'il y a quand même de la validation qui doit être faite sur les champs que je veux update

En essayant ceci :

$data = array(
    'username' => $username //déclaré plus haut dans le code
);
if($this->User->save($this->data, true, $data)) {
...
}

ou

$data = array(
    'username' => $username //déclaré plus haut dans le code
);
if($this->User->save($data, true, $data)) {
...
}

je passe dans le if, donc le save renvoie true mais rien n'est modifié dans ma base

Je pense tout de même que vous m'avez fourni les bonnes solutions.
Je suis en train de regarder le comportement du modèle et dans le beforeSave(), en essayant d'afficher $this->data via un debug, j'ai beaucoup plus de champs que prévu.

Merci en tout cas de votre aide, je vous tiens au courant dès que j'ai trouvé le coupable :)

Ok dans le problème venait bien du beforeSave, qui comportait une erreur de programmation de l'ancien dev avant moi.
Je vous donne un exemple du code du beforeSave pour vous montrer l'erreur

function beforeSave() {
    // Hash the password before save
    if(isset($this->data'User']'password']) & !empty($this->data'User']'password']))
        $this->data'User']'password'] = sha1($this->data'User']'password']);
    return true;
}

De 1) Remarquez la présence du "&" au lieu de "&&".
De 2) Ce test n'a rien à faire là puisque si le mot de passe est renseigné dans le model, alors il y aura un sha1 du mot de passe puis update.
Et ainsi de suite en boucle tant que l'on modifie qqchose sur le modèle.

En tout cas je vous remercie tous de votre aide, j'ai appris quelques petits tricks sur la validation de données :)

Ps : je ne pouvais pas modifier directement le comportement de la validation des données du modèle puisque c'est aussi utilisé pour d'autre formulaire de création et d'update.
En mettant la validation uniquement pour l'update par exemple, ça aurait pu péter tout les autres formulaire de création de données par rapport au User ayant besoin de la validation. L'inverse est aussi valable pour la mise à jour.