Bonjour,

Voilà, je me lance dans CakePHP 3 mais j'ai malheureusement quelques difficultés de compréhension avec ce nouvel ORM.
Je suis entrain de refaire un tuto de cakephp 2 en cakephp3 et je bloque un peu sur l'insertion avec un model (hasOne) lié.
J'ai commenté le problème dans le code
Enfaite je pense que j'ai un problème de comprenhension entre les entities et les tables de cette nouvelle version. Si vous pouviez m'éclairer.

UsersController.php


    public function signIn(){

        $user = $this->Users->newEntity();

        if ($this->request->is('post')) {

        // Est ce la bonne façon de faire ?
            $user->created_at = $user->update_at = date('Y-m-d h:i:s');
            $user->role = 'member';
            $user->status = false;

        // C'est ici que cela bloque, lorsque je valide mon formulaire il ne prends pas en compte cette modification. Les insertions se font correctement mais ma valeur born du model Profil ne change pas.
            $profil = $this->Users->Profils->newEntity();
            $profil->born = $this->request->data['profil']['years']['year'].'-'.$this->request->data['profil']['months']['month'].'-'.$this->request->data['profil']['days']['day'];

           $user = $this->Users->patchEntity($user, $this->request->data,['associated'=>['Profils']]);

            if ($this->Users->save($user)) {
                $this->Flash->success(__('Votre inscription a bien été enregistrer. Veuillez tchecker vos mails.'));
                return $this->redirect($this->referer());
            }
            $this->Flash->error(__('Impossible de vous enregistrer.'));
        }
        $this->set('user', $user);

    }

Template signin.ctp

<div class="users form">
<?= $this->Flash->render('auth') ?>
<?= $this->Form->create($user) ?>
    <fieldset>
        <legend><?= __("Inscription"); ?></legend>
        <?= $this->Form->input('profil.name') ?>
        <?= $this->Form->input('profil.lastname') ?>
        <fieldset>
            <label>Born</label>
        <?= $this->Form->year('profil.years', ['minYear' => 1967,'maxYear' => date('Y')]);?>
        <?= $this->Form->month('profil.months',['monthNames' => false]);?>
        <?= $this->Form->day('profil.days');?>
        </fieldset>
        <?= $this->Form->input('username') ?>
        <?= $this->Form->input('password') ?>

<?= $this->Form->button(__('S\'inscrire')); ?>
<?= $this->Form->end() ?>
</fieldset>
</div>

Merci pour votre aide. Je galère..

5 réponses


J'avoue ne pas trop comprendre le code (je creuserais peut être un peu plus tard si c'est toujours pas résolu)
sinon pour quoi .....

$this->request->data['profil']['years']['year']

....2 tableaux 'years' ?? comme je vois pour month et day
et puis tu fais quoi de $profil->born, par ce que tu ne le fait que déclarer et rien d'autre avec.

j'y reviendrai quand j'aurais un moment.

http://book.cakephp.org/3.0/en/orm/saving-data.html
ça peut t'aider

Merci pour ta réponse @kivivi . Il est vrai que je me suis peut être mal exprimé quand à mon besoin.
Enfaite j'ai une relation HasOne entre ma table User et Profil. Dans mon formulaire j'ai des champs de la table User et de la table Profil.

        <?= $this->Form->input('profil.name') ?>
        <?= $this->Form->input('profil.lastname') ?>
        <fieldset>
            <label>Born</label>
        <?= $this->Form->year('profil.years', ['minYear' => 1967,'maxYear' => date('Y')]);?>
        <?= $this->Form->month('profil.months',['monthNames' => false]);?>
        <?= $this->Form->day('profil.days');?>
        </fieldset>
        <?= $this->Form->input('username') ?>
        <?= $this->Form->input('password') ?>

Je veux pouvoir rajouter des champs manuellement dans mon controller (rôle, status et born) et ensuite sauvegarder le tout.
j'ai modifié mon code de l'autre fois mais j'ai un problème avec $data['profil']['born']. il me retourne une mauvaise date.

voici mon code

 public function signIn(){

        if ($this->request->is('post')) {

            $users = TableRegistry::get('Users');

            $data = $this->request->data();
            $data['role'] = 'member';
            $data['status'] = false;
          //  Pour répondre à ta question, j'ai un champs born dans ma table Profil et ce sont les inputs profil.years, profil.months et profil.days qui vont l'alimenter en faisant un
            $data['profil']['born'] = $data['profil']['years']['year']."-".$data['profil']['months']['month']."-".$data['profil']['days']['day'];

            $user = $users->newEntity($data,[
                'associated'=>['Profils']
                ]);

            if ($this->Users->save($user)) {
                $this->Flash->success(__('Votre inscription a bien été enregistrer. Veuillez tchecker vos mails.'));
                return $this->redirect($this->referer());
            }
            $this->Flash->error(__('Impossible de vous enregistrer.'));
        }

    }

NB : j'ai lu dans la doc qu'on pouvait utiliser l'événement Model.beforeMarshal pour modifier les données requêtées

public function beforeMarshal(Event $event, ArrayObject $data, ArrayObject $options)
    {

       if (isset($data['years']) && isset($data['months']) && isset($data['days'])) {

           $data['born'] = $data['years']['year'].'-'.$data['months']['month'].'-'.$data['days']['day'];
       }
    }

mais pareil cette fonction me retourne une mauvaise date.
Voilà j'espère avoir été plus clair.

Bonjour.

Enfaite je pense que j'ai un problème de comprenhension entre les entities et les tables

Pour faire simple et concis :

  • Table correspond à la table en général, c'est dans cette classe que tu définiras par exemple les associations, les behaviors, les règles de validations et autre spécificités concernant la table correspondante
  • Entities correspond à une entité, donc un enregistrement de cette table, c'est dans cette classe par exemple que tu pourras définir des getters et des setters (accesseurs et mutateurs), par conséquent que tu pourras modifier la valeur d'un champ avant la sauvegarde du champ de l'enregistrement setter ou avant de récupérer les données getter

Donc, dans ton exemple, tu pourrais par exemple faire un setter pour ton champ born au lieu de vouloir utiliser un évènement spécifique.
Par contre, les champs years, months et days, ils existent dans ta table ?

Merci pour ces précisions Lartak, je vais m'employer à la tâche et je reviens vers vous pour vous dire.
Concernant les champs y-m-d, non ils n'existent pas c'est juste que je ne voyais pas comment faire pour créer une date dans un seul champ (born) donc j'ai mis trois inputs que je réunissait après pour remplir mon champs born.

Je test tout ça ce soir encore merci !

Si tu veux séparer les différentes parties de la date dans le formulaire avec les méthodes spécifiques pour le champ born, il te suffit de faire par exemple :

<?= $this->Form->year('profil.born', ['minYear' => 1967,'maxYear' => date('Y')]); ?>
<?= $this->Form->month('profil.born', ['monthNames' => false]); ?>
<?= $this->Form->day('profil.born'); ?>

Tu n'auras de cette manière aucun traitement supplémentaire spécifique à faire par la suite.