Bonjour,

J'ai un soucis au niveau pour mon action edit. Lors de l'édition (dans mon cas, d'un profil), la validation chie au niveau du champs email.

Ce que je fais

Mes actions en question:

<?php
public function add()
    {
        $user = $this->Users->newEntity();
        if ($this->request->is('post')) {
            $user = $this->Users->patchEntity($user, $this->request->getData());
            if ($this->Users->save($user)) {
                $this->Flash->success(__("L'utilisateur a été sauvegardé."));
                $this->redirect(['action' => 'liste']);
            }
        }
        $this->set('user', $user);
    }

    public function edit($id = null){

        $user = $this->Users->get($id,[
            'fields' => ['name','surname','username','courriel','avatar','avatar_dir','poste','content','role']
        ]);
        if ($this->request->is(['patch', 'post', 'put'])) {
            $user = $this->Users->patchEntity($user, $this->request->getData());
            if ($this->Users->save($user)) {
                $this->Flash->success(__('Cet utilisateur a été édité et ajouté.'));
                $this->redirect(['controller' => 'Users', 'action' => 'liste']);
            }
        }
        $this->set(compact('user'));
        $this->set('_serialize', ['user']);
    }
    ?>

Mes règles de validation

<?php
public function validationDefault(Validator $validator)
    {
        return $validator
            ->notEmpty('username', "Un nom d'utilisateur est nécessaire")
            ->notEmpty('password', 'Un mot de passe est nécessaire')
            ->add('password', 'custom', [
                'rule' => [$this, 'passwordComplexe'],
                'message' => 'Le mot de passe ne respecte pas les règles (une majuscule minimum, un chiffre minimum, 8 caractères minimum).'
            ])
            ->add('password', [
                'compare' => [
                    'rule' => ['compareWith', 'confirm_password'],
                    'message' => 'Les mots de passe diffèrent.'
                ]
            ])
            ->allowEmpty('password')
            ->add('courriel', 'valid', [
                'rule' => 'email'
            ])
            ->add('courriel', [
                'unique' => [
                    'rule' => 'validateUnique',
                    'provider' => 'table',
                    'message' => 'Un compte avec cette adresse existe déjà.'
                ]
            ])
            ->requirePresence('courriel', 'create')
            ->notEmpty('courriel','Une adresse mail est obligatoire')
            ->notEmpty('role', 'Un role est nécessaire')
            ->notEmpty('name', "Un prénom est nécessaire")
            ->notEmpty('surname', "Un nom est nécessaire")
            ->notEmpty('content', "Merci de saisir une présentation de cette personne")
            ->notEmpty('avatar','create', "Une photo est obligatoire");
    }

    public function validationUpdate(Validator $validator)
    {
        return $validator
            ->notEmpty('username', "Un nom d'utilisateur est nécessaire")
            ->add('password', 'custom', [
                'rule' => [$this, 'passwordComplexe'],
                'message' => 'Le mot de passe ne respecte pas les règles (une majuscule minimum, un chiffre minimum, 8 caractères minimum).'
            ])
            ->add('password', [
                'compare' => [
                    'rule' => ['compareWith', 'confirm_password'],
                    'message' => 'Les mots de passe diffèrent.'
                ]
            ])
            ->allowEmpty('password')
            ->add('courriel', 'valid', [
                'rule' => 'email'
            ])
            ->requirePresence('courriel', 'create')
            ->notEmpty('role', 'Un role est nécessaire')
            ->notEmpty('name', "Un prénom est nécessaire")
            ->notEmpty('surname', "Un nom est nécessaire")
            ->notEmpty('content', "Merci de saisir une présentation de cette personne")
            ->allowEmpty('avatar','update');
    }
?>

Ce que je veux

Je cherche à faire appliquer des règles différentes entre l'ajout (insert) et l'edition (update).

Je vous met mon fichier edit correspondant:

<div class="table-responsive">
    <ul class="nav nav-tabs nav-justified" role="tablist">
        <li class="li_identify" role="presentation" class="active"><a href="#identity" aria-controls="identify" role="tab" data-toggle="tab">Identification</a></li>
        <li class="li_present" role="presentation" ><a href="#present" aria-controls="present" role="tab" data-toggle="tab">Présentation dans le site</a></li>
        <li class="li_authentification" role="presentation" ><a href="#authentification" class="authentification" aria-controls="authentification" role="tab" data-toggle="tab">Mot de passe</a></li>
    </ul>
    <br />
    <?= $this->Form->create($user, ['type' => 'file']) ?>
    <div class="tab-content">
        <div id="identity" class="tab-pane active">
            <?= $this->Form->input('username', ['label' => "Indiquez un nom d'utilisateur (utile pour l'identification)"]) ?>
            <?= $this->Form->input('courriel', ['label' => "Indiquez une adresse mail (utile pour récupérer mot de passe)"]) ?>
            <?= $this->Form->input('role', [
                'options' => ['admin' => __('Administrateur'), 'author' => __('Auteur'), 'member' => __("Membre")],
                'label' => __("Sélectionnez le role de ce membre")
            ]) ?>
            <?php
            echo $this->Form->input('avatar', ['type' => 'file', 'label' => __('Sélectionnez une photo')]);
            echo $this->Form->input('avatar_dir', ['type' => 'hidden']);
            ?>
        </div>
        <div id="present" class="tab-pane">
            <?= $this->Form->input('name', ['label' => "Indiquez son vrai prénom"]) ?>
            <?= $this->Form->input('surname', ['label' => "Indiquez son vrai nom"]) ?>
            <?= $this->Form->input('poste', ['label' => "Indiquez son poste dans l'équipe"]) ?>
            <?= $this->Form->input('content', ['label' => "Description"]) ?>
        </div>
        <div id="authentification" class="tab-pane">
            <fieldset class="bg-danger">
                <?= $this->Form->input('password', ['label' => "Veuillez indiquer un mot de passe", "required" => false]) ?>
                <?= $this->Form->input('confirm_password', ['type' => 'password', 'label' => "Veuillez indiquer un nouveau mot de passe", "required" => false]) ?>
                <div class="cb"></div>
            </fieldset>
        </div>
        <br />
        <?= $this->Form->button(__('Modification de ce membre')); ?>
        <?= $this->Form->end() ?>
    </div>
</div>

Ce que j'obtiens

Quand je valide, le validator renvoie un message m'indiquant que l'adresse mail est déjà utilisé. Oui car c'est une edition donc l'adresse est déjà dans la BDD.

Si vous voulez mon erreur.
leknoppix

3 réponses


Lartak
Réponse acceptée

Bonsoir.
Si tu ne veux utiliser que les règles de validations contenues dans la fonction validationUpdate lors de ton action edit, il te faut le spécifier dans le patchEntity, soit :

$user = $this->Users->patchEntity($user, $this->request->getData(), ['validate' => 'update']);
Lartak
Réponse acceptée

Oui, pour l'édition d'un enregistrement, il faut la clé primaire dans les données à sauvegarder, soit l'id et tu ne la définie à aucun moment vu que tu filtres les champs à récupérer en base de données et que l'id n'y figure pas, il te faut donc au minimum que tu l'ajoutes dans les champs que tu veux récupérer, ou alors faire par exemple :


$user = $this->Users->get($id, [
    'fields' => ['name','surname','username','courriel','avatar','avatar_dir','poste','content','role']
]);

if ($this->request->is(['patch', 'post', 'put'])) {
    $user->id = $id;
    $user = $this->Users->patchEntity($user, $this->request->getData(), ['validate' => 'update']);
    // etc ...
}

Bonjour
La validation passe avec cet ajout dans le patchEntity. Par contre, j'obtiens une erreur:

"All primary key value(s) are needed for updating, App\Model\Entity\User is missing id"

Une idée?