Consultez la FAQ sur le ZF avant de poster une question
Vous n'êtes pas identifié.
Bonjour,
J'essaye de créer l'application de Galeries photos proposée dans le livre de Sébastien Chazallet : ZF2 Industrialisez vos développements PHP.
J'ai un problème au niveau de la partie de la création des formulaires.
Je possède un formulaire qui propose :
- un champ name
- un champ description
- un champ caché id (l'id de la galerie pour l'édition)
- un champ caché id_user (l'id de l'user propriétaire de la galerie pour l'ajout)
Ce formulaire sert à la fois pour l'ajout d'une galerie mais aussi bien pour l'édition (champs pré-rempli).
Ceci se fait par une méthode save() présente dans un modèle. Cette fonction réalise un insert dans le cas d'un ajout et un update dans le cas d'une édition.
L'édition d'une galerie fonctionne correctement.
Cependant, l'ajout d'une galerie ne fonctionne pas, j'obtiens un message d'erreur :
[lang=php]Catchable fatal error: Argument 1 passed to Galerie\Model\Custom\Model\EntityManager::save() must be an instance of Galerie\Model\Custom\Model\Entity, array given, called in C:\Users\Romain\Documents\GitHub\zf2biz\galerie\module\Galerie\src\Galerie\Controller\IndexController.php on line 101 and defined in C:\Users\Romain\Documents\GitHub\zf2biz\galerie\module\Galerie\src\Galerie\Model\Custom\Model\EntityManager.php on line 90
Voici mon action "editAction()" qui s'occupe à la fois de l'ajout et de l'édition du fichier "IndexController" :
[lang=php] public function editAction() { //création du formulaire $form = new GalerieForm; //récupération de l'objet de travaille $id = $this->params()->fromRoute('id', null); if(!$id) { $galerie = null; } else { $galerie = $this->_getGalerieTable()->any( array('id' => $id) ); } //sommes nous en ajout ou en édition ? if(!$galerie) { //nous sommes en ajout $form->get('submit')->setValue('Ajouter'); //il faut créer un nouvelle objet Galerie $galerie = new Galerie; //$form->bind($galerie); //garder cette information pour la vue $is_new = true; } else { //nous sommes en modification $form->get('submit')->setValue('Modifier'); //il faut pré-remplir le formulaire avec les données actuelles $form->bind($galerie); //garder cette information pour la vue $is_new = false; } //récupération de l'objet requête $request = $this->getRequest(); if($request->isPost()) { //Mise en place pour la validation du formulaire $form->setInputFilter($galerie->getInputFilter()); $form->setData($request->getPost()); //Validation des données if($form->isValid()) { //sauvegarde des données $galerie = $form->getData(); if($is_new) { //si l'objet n'est pas nouveau //les autres paramètres restent inchangés //si l'object est nouveau, il faut renseigner //l'id de l'utilisateur courant //$galerie['id_user'] = 1; $galerie->id_user = 1; //TODO: Mettre ici le user connecté } $this->_getGalerieTable()->save($galerie); //Redirection return $this->redirect()->toRoute('galerie'); } }
La ligne 101 est celle ci :
[lang=php]$this->_getGalerieTable()->save($galerie);
Je pense que le problème vient d'ici :
[lang=php]$galerie = $form->getData();
car un print_r($galerie); avant cette ligne m'affiche un objet, en voici un extrait :
[lang=php]Galerie\Model\Galerie Object ( [id] => [id_user] => [name] => [description] => [created] => [updated] => [inputFilter:protected] => Zend\InputFilter\InputFilter Object ( [factory:protected] => [data:protected] => Array ( [id] => [id_user] => [name] => toto [description] => album de france [submit] => Ajouter ) [inputs:protected] => Ar
Tandis qu'un print_r($galerie); après le getData() ne me renvoit plus d'objets mais ceci :
[lang=php]Array ( [id] => 0 [id_user] => 0 [name] => toto [description] => album de france [submit] => Ajouter )
Voici ma méthode save() du fichier EntityManager.php
[lang=php] public function save(Entity $entity) { if ($this->is_new($entity)) { $this->insert( $entity->toUpdatableArray() ); } elseif ($this->any($this->extract_primary($entity))) { $this->update( $entity->toUpdatableArray(), $entity->toPrimaryArray() ); } else { $keys = array(); foreach($this->extract_primary($entity) as $k => $v) { $keys[] = "{$k}: {$v}"; } $keys = implode(', ', $keys); throw new \Exception("cannot update row {{$keys}} in table '{$this->table}'"); } }
Merci de votre aide. N'hésitez à me demander, si vous voulez voir d'autres parties de code.
Hors ligne
Salut, j'ai pas tout lu parce que le code est vraiment pas propre et c'est pas vraiment comme ça qu'il faut faire pour utiliser les formulaires mais c'est pas le sujet.
En gros ce qu'il se passe c'est que dans un cas tu enregistres un objet donc comme ta méthode save attend un objet de type Entity ça fonctionne et dans le cas de l'ajout du lui passe un array. Le problème vient du faire que ton formulaire dans le cas de l'update tu lui fais un bind de ton objet alors que dans le cas de l'ajout non. Comme on ne voit pas ce que fait le formulaire je ne peux pas savoir s'il y a un hydrateur ou non. Je pense que oui vu que dans le cas de l'update le $form->getData() te retourne bien un objet de type Entity (objet que tu lui as bindé juste avant donc logique).
Donc la solution soit tu bind aussi à l'ajout ton entité et dans le cas où il y a un hydrateur dans le formulaire tu récupèreras bien une entité dans le cas contraire faire une méthode qui te rempli tout seul ton objet à partir d'un tableau en sachant que les hydrateurs peuvent le faire pour toi automatiquement.
Hors ligne
Merci pour votre réponse.
L'ajout fonctionne en ajoutant le bind sur le formulaire d'ajout.
Je ne pense pas utiliser les Hydrateurs. Peux tu m'en dire un peu plus ? a quoi servent ils ?
Pourquoi dites vous que ce n'est pas ce qu'il faut faire pour utiliser les formulaires. Le code que j'ai affiché vient du livre cité dans mon premier post.
Hors ligne
Si tu ne les utilises pas peut être que le formulaire est capable de le faire tout seul mais ça m'étonne il doit forcément y avoir un mécanisme d'hydrateur derriere (même automatique). En fait un hydrateur c'est tout bête ça va remplir un objet en fonction d'un tableau ou vice versa.
Voici un lien pour avoir plus d'infos : http://framework.zend.com/manual/2.0/en … rator.html
Parce que j'ai fait la relecture du livre de Sébastien et il y a des choses qui ne respectent pas les conventions et les bonnes pratiques. Il y a des bonnes choses pour débuter mais il y a par moment des méthodes un peu compliquées. Typiquement sur les formulaires quand ils sont bien utilisés t'as presque rien à écrire tout se faire tout seul.
Hors ligne
D'accord merci beaucoup, je vais lire ton lien sur les hydrateurs.
As tu un tuto sous la main pour la bonne façon d'écrire les formulaires?
Hors ligne
La documentation officielle et les blogs des contributeurs et plus particulièrement celui-ci : http://www.michaelgallego.fr/ (c'est lui qui a créé le composant formulaire).
Hors ligne