Setter avec 2 champs

Par alexyon, il y a 10 ans


j'ai lu dans le book qu'il est possible de créer un setter qui permet de modifier un champ dans l'entity :

protected function _setTitle($title) { $this->set('slug', Inflector::slug($title)); return $title; }

auteur : Rousseau
livre : Les confessions
mais par exemple si j'ai 2 champs (auteur + livre), comment puis je créer un setter pour obtenir dans mon champ name :

ce que je veux => name : Rousseau - Les confessions

16 réponses

Xeta, il y a 10 ans

Hello,

/** * Set the name of the user with his book. * * @return string */ protected function _setName($name) { $name = trim($this->auteur . ' - ' . $this->livre); return $name; }
alexyon, il y a 10 ans

et pourtant la sauvegarde en BDD ne prend pas en compte le champ name :

protected function _setName($name) { $this->set('name', trim($this->auteur . ' - ' . $this->livre);); return $name; }
Lartak, il y a 10 ans

Bonjour.

et pourtant la sauvegarde en BDD ne prend pas en compte le champ name

Tu n'as pas compris le principe et tu as mal reproduis le code, de plus que tu as des erreurs de ;.
L'exemple que tu nous montres de la doc, c'est pour effectuer un slug à partir du champ title.
Si tu veux que le name soit sauvegardé en base de donné avec la concaténation avec le livre, reproduis correctement le code que t'a proposé Xeta.
Par contre, ne confonds pas les setters et les getters.

alexyon, il y a 10 ans

slt à tous les 2,
même en recopiant exactement son code, la sauvegarde de ce champ ne se fait pas.
si je debug l'entity juste avant la sauvegarde, il devrait me l'afficher ?
voila comment je lai adapté :

protected function _setFullname($fullname) { $fullname = trim($this->name . ' - ' . $this->prenom); return $fullname; }
Lartak, il y a 10 ans

même en recopiant exactement son code, la sauvegarde de ce champ ne se fait pas.

Est-ce que tu transmets bien les données des deux champs au moment de la sauvegarde ?
Car si tu ne transmets pas par exemple le livre il ne pourra pas faire la sauvegarde du champ via le setter.
Et puis vérifies si ce n'est pas un problème de la taille du champ name.

alexyon, il y a 10 ans

jai mis le champ fullname en varchar 255
voila ce que me sort l'entity apres sauvegarde :

object(App\Model\Entity\Identite) { '_csrfToken' => '53aea4530bc326e26adb02a559d7931bf5551ca0', 'name' => 'dupond', 'prenom' => 'michel', 'id' => (int) 40, '[new]' => false, '[accessible]' => [ '*' => true ], '[dirty]' => [], '[original]' => [], '[virtual]' => [], '[errors]' => [], '[repository]' => 'Identites' }
Havok, il y a 10 ans

Si tu as les 2 champs "auteur" et "livre" sauvegardés en base, tu possèdes également une autre solution qui t'évite de sauvegarder un troisième champ qui concatène simplement les deux. Tu peux créer une "propriété virtuelle" :

// Va créer une propriété virtuelle "name" pour l'Entity protected function _getName() { return $this->_properties['auteur'] . ' - ' . $this->_properties['livre']; }

Et y accéder comme s'il s'agissait d'une propriété classique de ton Entity :

echo $entity->name;

L'avantage c'est que si tu mets à jour l'un ou l'autre champ, ta propriété "name" sera mise à jour automatiquement.

Plus de détails sur le Cookbook : http://book.cakephp.org/3.0/fr/orm/entities.html#creer-des-proprietes-virtuelles

alexyon, il y a 10 ans

merci Havok, mais je voudrais surtout savoir pkoi je n'arrive pas sauvegarder ce champ.
ps : vraiment dommage qu'on ne puisse pas se servir de ces virtual dans les find...

alexyon, il y a 10 ans

voila ma méthode mais le champ fullname ne se remplit pas

protected function _setFullname($fullname) { $fullname = trim($this->name . ' - ' . $this->prenom); $this->set('fullname', $fullname); return $fullname; }
alexyon, il y a 10 ans

mon entity est construite à partir du ($this->request->data), donc comme je ne mets pas dedans le champ fullname, il me parait normal qu'il n'apparaisse pas.
car si je fais un get($id), le champ fullname apparait :

object(App\Model\Entity\Identite) { 'id' => (int) 51, 'name' => 'dupont', 'prenom' => 'michel', 'fullname' => '', '[new]' => false, '[accessible]' => [ '*' => true ], '[dirty]' => [], '[original]' => [], '[virtual]' => [], '[errors]' => [], '[repository]' => 'Identites' }
Havok, il y a 10 ans

Ah, c'est pour ça.
Ta méthode _setFullname n'est jamais appelée car à aucun moment tu ne fournis fullname à l'entity.
Tu devrais faire ton set('fullname', ...) sur _setName ou _setPrenom

Cependant pour ce cas là, je reste sur mon premier conseil : une propriété virtuelle reste la meilleure solution.

alexyon, il y a 10 ans

Oui, je comprends, mais c'est juste pour comprendre comment fonctionne un setter.
j'ai essayé ca :

protected function _setName($fullname) { $fullname = trim($this->name . ' - ' . $this->prenom); $this->set('fullname', $fullname); return $fullname; }

et dans la base il remplit les champs name et fullname avec un tiret; donc 2 prob :
1 - il écrase le name
2 - il ne trouve pas $this->name et $this->prenom

alexyon, il y a 10 ans

on y est presque ; mais il ne connait pas $this->_properties['prenom']

Notice (8): Undefined index: prenom [APP/Model/Entity/Identite.php, line 26]
Havok, il y a 10 ans

Ah, j'ai voulu faire éditer, mais j'ai fait "Supprimer".
J'ai creusé un peu et l'erreur apparaît pr une raison simple.
Lorsque l'Entity est créée, les propriétés sont parcourus dans l'ordre dans lequel elles sont données dans le tableau qui crée l'Entity.
Du coup, vu que tu crées ton Entity à partir de $this->request->data, les propriétés sont set dans l'ordre dans lequel tes champs sont créés dans ton formulaire (j'imagine que dans ton formulaire, name est avant prenom).
Du coup, tu devrais changer pour ça :

protected function _setPrenom($prenom) { $fullname = trim($prenom . ' - ' . $this->_properties['name']); $this->set('fullname', $fullname); return $prenom; }