Consultez la FAQ sur le ZF avant de poster une question
Vous n'êtes pas identifié.
Bonjour a tous,
Je migre une application vers Doctrine et je me confronte au problème de bind des formulaires.
Comme la base de donnée est déjà existante, les champs pour les ManyToOne et autres jointures sont defini dans JoinColumn
[lang=php] /** * @ORM\ManyToOne(targetEntity="TjSettings\Entity\Icon") * @ORM\JoinColumn(name="iconId", referencedColumnName="id") */ protected $icon;
Les findAll() fonctionnent à merveille je peux retrouver toutes les données voulues.
Mais pour afficher un formulaire avec DoctrineModule\Form\Element\ObjectSelect par exemple, j'ai bien la liste pour ValueOptions mais pas la sélection de la valeur "Bindé".
Pour l'enregistrement des valeurs j'obtiens un beau :
Warning: spl_object_hash() expects parameter 1 to be object, string given in /usr/local/zend/apache2/htdocs/MyApp/vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php on line 1367 Warning: get_class() expects parameter 1 to be object, string given in /usr/local/zend/apache2/htdocs/MyApp/vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php on line 765
J'ai testé pas mal de tuto dont celui-là et après 2 grosses journées de lecture et de tests je pense obtenir une méga belle usine à gaz.
Quelle bonne pratique adopter ?
Bonne journée, (parce que pour moi il est 13h01 au moment du post )
Les tables sql :
[lang=sql] CREATE TABLE icon ( id INT AUTO_INCREMENT NOT NULL, name VARCHAR(100) NOT NULL, cssClass VARCHAR(100) NOT NULL, UNIQUE INDEX UNIQ_659429DB81D80C6E (cssClass), PRIMARY KEY(id) ) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB; CREATE TABLE mediaCategory ( id INT AUTO_INCREMENT NOT NULL, name VARCHAR(255) NOT NULL, iconId INT DEFAULT NULL, INDEX IDX_EAA51CA3AC3A2DE (iconId), PRIMARY KEY(id) ) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB; ALTER TABLE mediaCategory ADD CONSTRAINT FK_EAA51CA3AC3A2DE FOREIGN KEY (iconId) REFERENCES icon (id);
Les Entity :
[lang=php] namespace TjSettings\Entity; use Doctrine\ORM\Mapping as ORM; /** * Icon Entity * @ORM\Entity(repositoryClass="TjSettings\Repository\IconRepository") * @ORM\Table(name="icon") */ class Icon { //protected $inputFilter; /** * @ORM\Id * @ORM\Column(type="integer") * @ORM\GeneratedValue(strategy="AUTO") */ protected $id; /** * @ORM\Column(type="string", length=100) */ protected $name; /** * @ORM\Column(type="string", length=100, unique=true, nullable=false) */ protected $cssClass; /** * Get Id * * @return integer */ public function getId() { return $this->id; } /** * Set Name * * @param string $name */ public function setName($name) { $this->name = $name; } /** * Get Name * * @return string */ public function getName() { return $this->name; } /** * Set CssClass * * @param string $cssClass */ public function setCssClass($cssClass) { $this->cssClass = $cssClass; } /** * Get CssClass * * @return string */ public function getCssClass() { return $this->cssClass; } /** * Convert the object to an array. * * @return array */ public function getArrayCopy() { return get_object_vars($this); } /** * Populate from an array. * * @param array $data */ public function populate($data = array()) { $this->id = $data['id']; $this->name = $data['name']; $this->cssClass = $data['cssClass']; } } namespace TjSettings\Entity; use Doctrine\ORM\Mapping as ORM; /** * MediaCategory Entity * @ORM\Entity(repositoryClass="TjSettings\Repository\MediaCategoryRepository") * @ORM\Table(name="mediaCategory") */ class MediaCategory { //protected $inputFilter; /** * @ORM\Id * @ORM\Column(type="integer") * @ORM\GeneratedValue(strategy="AUTO") */ protected $id; /** * @ORM\Column(type="string") */ protected $name; /** * @ORM\ManyToOne(targetEntity="TjSettings\Entity\Icon") * @ORM\JoinColumn(name="iconId", referencedColumnName="id") */ protected $icon; /** * Getter and Setter function */ /** * Get Id * * @return integer */ public function getId() { return $this->id; } /** * Set Name * * @param string $name * @return \TjSettings\Entity\MediaCategory */ public function setName($name) { $this->name = $name; return $this; } /** * Get Name * * @return string */ public function getName() { return $this->name; } /** * Set Icon * * @param \TjSettings\Entity\Icon $icon * @return \TjSettings\Entity\MediaCategory */ public function setIcon(Icon $icon) { $this->icon = $icon; return $this; } /** * Get Icon * * @return \TjSettings\Entity\Icon */ public function getIcon() { return $this->icon; } /** * Convert the object to an array. * * @return array */ public function getArrayCopy() { return get_object_vars($this); } /** * Populate from an array. * * @param array $data */ public function populate($data = array()) { $this->id = $data['id']; $this->name = $data['name']; $this->icon = $data['icon']; } }
Les repository (sur base de ZfrForum de Bakura)
[lang=php]namespace TjSettings\Repository; use Doctrine\ORM\EntityRepository; use TjSettings\Entity\Icon; class IconRepository extends EntityRepository { /** * Create de Icon * * @param Icon $icon * @return Icon * */ public function create(Icon $icon) { $this->_em->persist($icon); $this->_em->flush($icon); return $icon; } /** * Update the icon * * @param Icon $icon * @return Icon */ public function update(Icon $icon) { $this->_em->flush($icon); return $icon; } /** * Remove the icon * * @param Icon $icon * @return void */ public function remove(Category $icon) { $this->_em->remove($icon); $this->_em->flush($icon); } } namespace TjSettings\Repository; use Doctrine\ORM\EntityRepository; use TjSettings\Entity\MediaCategory; class MediaCategoryRepository extends EntityRepository { /** * Create de Icon * * @param Icon $icon * @return Icon * */ public function create(MediaCategory $mediaCategory) { $this->_em->persist($mediaCategory); $this->_em->flush($mediaCategory); return $mediaCategory; } /** * Update the icon * * @param Icon $icon * @return Icon */ public function update(MediaCategory $mediaCategory) { $this->_em->flush($mediaCategory); return $mediaCategory; } /** * Remove the icon * * @param Icon $icon * @return void */ public function remove(MediaCategory $mediaCategory) { $this->_em->remove($mediaCategory); $this->_em->flush($mediaCategory); } }
Les Forms
[lang=php]namespace TjSettings\Form; use DoctrineModule\Persistence\ObjectManagerAwareInterface; use Doctrine\Common\Persistence\ObjectManager; use Zend\Form\Form; use Zend\Form\Element; /** * Description of IconForm * * @author soltom */ class IconForm extends Form implements ObjectManagerAwareInterface { protected $objectManager; public function __construct(ObjectManager $objectManager) { $this->setObjectManager($objectManager); parent::__construct('db-adapter-form'); $this->setAttribute('method', 'post'); $this->add(array( 'type' => 'Zend\Form\Element\Hidden', 'name' => 'id', )); $this->add(array( 'type' => 'Zend\Form\Element\Text', 'name' => 'name', 'options' => array( 'label' => 'Name', ), )); $this->add(array( 'type' => 'Zend\Form\Element\Text', 'name' => 'cssClass', 'options' => array( 'label' => 'Css Class', ), )); // action buttons save (reset, cancel) $submitButton = new Element\Button('submit'); $submitButton->setValue('Save')->setLabel('Save') ->setAttribute('type', 'submit') ->setAttribute('class', 'btn btn-primary') ->setAttribute('id', 'submitButton'); $this->add($submitButton); $cancelButton = new element\Button('cancel'); $cancelButton->setValue('Cancel')->setLabel('Cancel') ->setAttribute('type', 'reset') ->setAttribute('class', 'btn') ->setAttribute('id', 'cancelButton'); $this->add($cancelButton); } public function setObjectManager(ObjectManager $objectManager) { $this->objectManager = $objectManager; return $this; } public function getObjectManager() { return $this->objectManager; } } namespace TjSettings\Form; use DoctrineModule\Persistence\ObjectManagerAwareInterface; use Doctrine\Common\Persistence\ObjectManager; use Zend\Form\Form; use Zend\Form\Element; /** * Description of IconForm * * @author Thomas Jacquart */ class MediaCategoryForm extends Form implements ObjectManagerAwareInterface { protected $objectManager; public function __construct(ObjectManager $objectManager) { $this->setObjectManager($objectManager); parent::__construct('db-adapter-form'); $this->setAttribute('method', 'post'); $this->setAttribute('class', 'form'); $this->add(array( 'type' => 'Zend\Form\Element\Hidden', 'name' => 'id', )); $this->add(array( 'type' => 'Zend\Form\Element\Text', 'name' => 'name', 'options' => array( 'label' => 'Name', ), )); $this->add(array( 'type' => 'DoctrineModule\Form\Element\ObjectSelect', 'name' => 'icon', 'options' => array( 'label' => 'Icon', 'object_manager' => $this->getObjectManager(), 'target_class' => 'TjSettings\Entity\Icon', 'property' => 'name', ), )); // action buttons save (reset, cancel) $submitButton = new Element\Button('submit'); $submitButton->setValue('Save')->setLabel('Save') ->setAttribute('type', 'submit') ->setAttribute('class', 'btn btn-primary') ->setAttribute('id', 'submitButton'); $this->add($submitButton); $cancelButton = new element\Button('cancel'); $cancelButton->setValue('Cancel')->setLabel('Cancel') ->setAttribute('type', 'reset') ->setAttribute('class', 'btn') ->setAttribute('id', 'cancelButton'); $this->add($cancelButton); } /** * Setter for ObjectManager * * @param \Doctrine\Common\Persistence\ObjectManager $objectManager * @return \TjSettings\Form\MediaCategoryForm */ public function setObjectManager(ObjectManager $objectManager) { $this->objectManager = $objectManager; return $this; } /** * Getter for ObjectManager * * @return \Doctrine\Common\Persistence\ObjectManager */ public function getObjectManager() { return $this->objectManager; } }
Les controllers
[lang=php]namespace TjSettings\Controller; use Zend\Mvc\Controller\AbstractActionController; use Zend\View\Model\ViewModel; use Doctrine\ORM\EntityManager; use TjSettings\Entity\Icon; use TjSettings\Form\IconForm; class IconController extends AbstractActionController { /** * @var Doctrine\ORM\EntityManager $em */ protected $em; public function setEntityManager(EntityManager $em) { $this->em = $em; } public function getEntityManager() { if (null === $this->em) { $this->em = $this->getServiceLocator()->get('doctrine.entitymanager.orm_default'); } return $this->em; } public function getIconRepository() { return $this->getEntityManager()->getRepository('TjSettings\Entity\Icon'); } (...) public function editAction() { $id = (int) $this->params()->fromRoute('id', 0); $icon = new Icon(); if ($id > 0 ) { $icon = $this->getIconRepository()->find($id); } $form = new IconForm($this->getEntityManager()); $form->bind($icon); $request = $this->getRequest(); if ($request->isPost()) { $form->setData($request->getPost()); if ($form->isValid()) { if ($id > 0) { // update $icon = $this->getIconRepository()->update($icon); } else { // create $icon = $this->getIconRepository()->create($icon); } } } return new ViewModel(array( 'form' => $form, 'id' => $id, )); } } namespace TjSettings\Controller; use Zend\Mvc\Controller\AbstractActionController; use Zend\View\Model\ViewModel; use Doctrine\ORM\EntityManager; use TjSettings\Entity\MediaCategory; use TjSettings\Form\MediaCategoryForm; class MediaCategoryController extends AbstractActionController { /** * @var Doctrine\ORM\EntityManager $em */ protected $em; public function setEntityManager(EntityManager $em) { $this->em = $em; } public function getEntityManager() { if (null === $this->em) { $this->em = $this->getServiceLocator()->get('doctrine.entitymanager.orm_default'); } return $this->em; } public function getMediaCategoryRepository() { return $this->getEntityManager()->getRepository('TjSettings\Entity\MediaCategory'); } (...) public function editAction() { $id = (int) $this->params()->fromRoute('id', 0); $mediaCategory = new MediaCategory(); if ($id > 0 ) { $mediaCategory = $this->getMediaCategoryRepository()->find($id); } $form = new MediaCategoryForm($this->getEntityManager()); $form->bind($mediaCategory); $request = $this->getRequest(); if ($request->isPost()) { $form->setData($request->getPost()); if ($form->isValid()) { if ($id > 0) { // update $mediaCategory = $this->getMediaCategoryRepository()->update($mediaCategory); } else { // create $mediaCategory = $this->getMediaCategoryRepository()->create($mediaCategory); } } } return new ViewModel(array( 'form' => $form, 'id' => $id, )); } }
Dernière modification par JiBe (25-06-2013 21:58:28)
Hors ligne
Et bien après une refonte complete sur base de l'architecture du ZfrForum j'ai résolu mon problème du à une mauvaise définition des Entity.
Avec une relation OneToMany si on peut fixer la valeur à null il ne faut pas oublié
[lang=php] // TjSettings\Entity\Icon (...) /** * @ORM\ManyToOne(targetEntity="TjSettings\Entity\Icon") * @ORM\JoinColumn(name="icon_id", referencedColumnName="id") */ protected $icon; (...) /** * Set Icon * * @param \TjSettings\Entity\Icon $icon * @return \TjSettings\Entity\MediaCategory */ public function setIcon(Icon $icon = null) { $this->icon = $icon; return $this; } (...)
Concernant le ObjectSelect de doctrine ne reprenant pas la valeur sélectionnée c'est corrigé dans la release 2.4 en version beta actuellement mais il y a un fix ici
Je suis donc en mode "cumulet" ou "roulade" selon le pays et replonge dans mon code.
Bonne soirée à tous.
Hors ligne
Salut merci pour ton retour ça pourra surement aider certains .
Hors ligne