Zend FR

Consultez la FAQ sur le ZF avant de poster une question

Vous n'êtes pas identifié.

#1 20-06-2013 13:01:43

JiBe
Membre
Lieu: Brabant Wallon, Belgique
Date d'inscription: 27-06-2007
Messages: 16

[Résolu] ZF2 + Doctrine2 + Form

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

Code:

 [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 :

Code:

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 wink )


Les tables sql :

Code:

 [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 :

Code:

[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)

Code:

 [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

Code:

 [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

Code:

 [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

 

#2 25-06-2013 21:58:07

JiBe
Membre
Lieu: Brabant Wallon, Belgique
Date d'inscription: 27-06-2007
Messages: 16

Re: [Résolu] ZF2 + Doctrine2 + Form

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é

Code:

 [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

 

#3 26-06-2013 09:45:39

Orkin
Administrateur
Lieu: Paris
Date d'inscription: 09-12-2011
Messages: 1261

Re: [Résolu] ZF2 + Doctrine2 + Form

Salut merci pour ton retour ça pourra surement aider certains wink.

Hors ligne

 

Pied de page des forums

Propulsé par PunBB
© Copyright 2002–2005 Rickard Andersson
Traduction par punbb.fr

Graphisme réalisé par l'agence Rodolphe Eveilleau
Développement par Kitpages