ZF2 Doctrine2 : How to implement form with relation? - doctrine-orm

I have found a tutorial to implement a form with entities annotations.
Doctrine entity with zend form
I want to know how to implement with a relation.
This is my code...
My entity :
/**
* Account
*
* #ORM\Table(name="account", indexes={#ORM\Index(name="IDX_7D3656A4C6798DB", columns={"account_type_id"})})
* #ORM\Entity(repositoryClass="Application\Repository\Account")
* #Annotation\Name("account")
*/
class Account extends EntityAbstract implements InputFilterAwareInterface, UserInterface
{
/**
* #var Zend\InputFilter\InputFilter
*/
protected $inputFilter;
/**
* #var integer
*
* #ORM\Column(name="id", type="bigint", nullable=false, options={"input" = "hidden"})
* #ORM\Id
* #ORM\GeneratedValue(strategy="SEQUENCE")
* #ORM\SequenceGenerator(sequenceName="account_id_seq", allocationSize=1, initialValue=1)
* #Annotation\Attributes({"type":"hidden"})
*/
protected $id;
/**
* #var string
*
* #ORM\Column(name="code", type="string", nullable=false, unique=true, options={"input" = "text"})
* #Annotation\Attributes({"type":"text", "class":"test"})
* #Annotation\Options({"label":"Code"})
*/
protected $code;
/**
* #var string
*
* #ORM\Column(name="password", type="string", nullable=false, options={"input" = "password"})
* #Annotation\Attributes({"type":"text"})
* #Annotation\Options({"label":"Mot de passe"})
*/
protected $password;
/**
* #var string
*
* #ORM\Column(name="password_key", type="string", nullable=false, options={"input" = "password"})
* #Annotation\Exclude()
*/
protected $passwordKey;
/**
* #var boolean
*
* #ORM\Column(name="active", type="boolean", nullable=false, options={"input" = "checkbox"})
* #Annotation\Attributes({"type":"checkbox"})
* #Annotation\Options({"label":"Actif"})
*/
protected $active = false;
/**
* #var string
*/
protected $displayName;
/**
* #var boolean
*
* #ORM\Column(name="visible", type="boolean", nullable=false, options={"input" = "checkbox"})
* #Annotation\Attributes({"type":"checkbox"})
* #Annotation\Options({"label":"Visible"})
*/
protected $visible = false;
/**
* #var \DateTime
*
* #ORM\Column(name="start_date", type="datetime", nullable=false, options={"input" = "date"})
* #Annotation\Attributes({"type":"date"})
* #Annotation\Options({"label":"Date de début"})
*/
protected $startDate = 'now()';
/**
* #var \DateTime
*
* #ORM\Column(name="end_date", type="datetime", nullable=true, options={"input" = "date"})
* #Annotation\Attributes({"type":"date"})
* #Annotation\Options({"label":"Date de fin"})
*/
protected $endDate;
/**
* #var string
*
* #ORM\Column(name="token", type="string", nullable=false, options={"input" = "password"})
* #Annotation\Exclude()
*/
protected $token;
/**
* #var integer
*
* #ORM\Column(name="expires", type="integer", nullable=true)
* #Annotation\Exclude()
*/
protected $expires;
/**
* #var \Application\Entity\AccountType
*
* #ORM\ManyToOne(targetEntity="Application\Entity\AccountType", fetch="EAGER", inversedBy="accounts")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="account_type_id", referencedColumnName="id", nullable=false)
* })
* #Annotation\Type("DoctrineModule\Form\Element\ObjectSelect")
* #Annotation\Options({"label":"Type de compte", "object_manager":"Doctrine\Common\Persistence\ObjectManager" ,"target_class":"Application\Entity\AccountType"})
*/
protected $accountType;
...
My controller edit action :
public function editAction()
{
try
{
$entityManager = $this->getEntityManager();
$repository = $this->getRepository();
$id = (int)$this->params()->fromRoute('id');
$user = $repository->find($id);
$builder = new AnnotationBuilder($entityManager);
$form = $builder->createForm($user);
$form->setHydrator(new DoctrineHydrator($entityManager,'Application\Entity\Account'));
$form->bind($user);
$view = new ViewModel();
$view->setVariable('form', $form);
return $view;
}
catch(\Exception $e)
{
echo '<pre>';
print_r($e->getMessage());
echo '</pre>';
}
}
I catch this error :
Catchable fatal error: Argument 1 passed to DoctrineModule\Form\Element\Proxy::setObjectManager() must implement interface Doctrine\Common\Persistence\ObjectManager, string given, called in /Users/thibaud/Sites/api/vendor/doctrine/doctrine-module/src/DoctrineModule/Form/Element/Proxy.php on line 86 and defined in /Users/thibaud/Sites/api/vendor/doctrine/doctrine-module/src/DoctrineModule/Form/Element/Proxy.php on line 185
Ok. I know how relations works and how to build a form with doctrine with relations but don't know how to implement the same with anotations. Here is how i build form with a relation :
$this->add
(
array
(
'name' => 'accountType',
'type' => 'DoctrineModule\Form\Element\ObjectSelect',
'options' => array
(
'label' => 'Type de compte',
'object_manager' => $this->getObjectManager(),
'target_class' => 'Application\Entity\AccountType',
'label_generator' => function($target)
{
return $target->getName();
}
),
)
);

use Zend\Form\Annotation as Form;
/**
*
* #Form\Type("DoctrineModule\Form\Element\ObjectSelect")
* #Form\Attributes({"required":"required"})
* #Form\Required(true)
* #Form\Options({
* "label":"Account",
* "empty_option": "Please choose",
* "target_class": "Application\Entity\Whatever",
* "property": "CoolProperty",
* "find_method": {
* "name": "findBy",
* "params": {
* "criteria": {"awesomeCriteria": 0},
* "orderBy": {"letsSayDate": "ASC"}
* }
* }
* })
*/
For clarity and shorter codes sake I gave the namespace a alias called Form.

Related

Symfony 3.3 and doctrine 2

I have two entities Article and Image related by a ManytoMany relations using a third entity called ArticlesHaveImages.
I don't use classical ManytoMany relation of Doctrine because I have a third field in ArticlesHaveImages called sequence.
class Article
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
...
...
/**
* One Article has Many articleHaveImage.
* #ORM\OneToMany(targetEntity="ArticlesHaveImages", mappedBy="article")
*/
private $images;
class Image
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
...
...
/**
* One Image has Many articleHaveImage.
* #ORM\OneToMany(targetEntity="ArticlesHaveImages", mappedBy="image")
*/
private $articles;
public function __construct() {
$this->articles = new ArrayCollection();
}
class ArticlesHaveImages
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* Many ArticlesHaveImages have One Article.
* #ORM\ManyToOne(targetEntity="Article", inversedBy="images")
* #ORM\JoinColumn(name="article_id", referencedColumnName="id")
*/
private $article;
/**
* Many ArticlesHaveImages have One Image.
* #ORM\ManyToOne(targetEntity="Image", inversedBy="articles")
* #ORM\JoinColumn(name="image_id", referencedColumnName="id")
*/
private $image;
/**
* #var int
*
* #ORM\Column(name="sequence", type="integer")
*/
private $sequence;
How do I create a form out of this ?
I want a multiple select option which all images name.
I tried :
class ArticleType extends AbstractType
{
/**
* {#inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$images = $options['images'];
$builder
->add('translations', CollectionType::class, array(
'entry_type' => ArticleTranslationType::class,
'entry_options' => array('label' => false)))
->add('images', ChoiceType::class, array(
"required" => false,
"choices" => $images,
'multiple' => true,
But I get :
Could not determine access type for property "images" in class
"AppBundle\Entity\Article".
BIG THANKS !

"Class is not a valid entity..." error for EntityManager#getClassMetadata(...)

I'm trying to write a test case for to post it on the Doctrine's GitHub page and have a problem with schema generating. The call
$this->_em->getClassMetadata(Server::class)
causes the exception
Class "Doctrine\Tests\Models\DDC6786\Server" is not a valid entity or mapped super class.
What am I doing wrong ? / How to get it working?
CODE
DDC6786Test
namespace Doctrine\Tests\ORM\Functional\Ticket;
use Doctrine\Tests\Models\DDC6786\Endpoint;
use Doctrine\Tests\Models\DDC6786\EndpointServerConfig;
use Doctrine\Tests\Models\DDC6786\Server;
use Doctrine\Tests\OrmFunctionalTestCase;
class DDC6786Test extends OrmFunctionalTestCase
{
public function testIssue()
{
$this->assertTrue(true);
}
public function setUp()
{
parent::setUp();
try {
$this->_schemaTool->createSchema(
[
$this->_em->getClassMetadata(Server::class),
$this->_em->getClassMetadata(EndpointServerConfig::class),
$this->_em->getClassMetadata(Endpoint::class),
]
);
} catch(\Exception $e) {
$breakpoint = null;
}
}
}
Endpoint
namespace Doctrine\Tests\Models\DDC6786;
use Doctrine\ORM\Mapping as ORM;
use ReflectionClass;
/**
* Endpoint
*
* #ORM\Table(name="endpoint")
* #ORM\Entity
*/
class Endpoint
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
protected $id;
/**
* #var string
*
* #ORM\Column(name="role", type="string", nullable=true)
*/
protected $role;
/**
* #var string
*
* #ORM\Column(name="server_place", type="string", nullable=true)
*
* #Groups({"export"})
*/
protected $serverPlace;
/**
* #var string
*
* #ORM\Column(name="contact_person", type="string", length=500, nullable=true)
*
* #Groups({"export"})
*/
protected $contactPerson;
/**
* #var \DateTime
*
* #ORM\Column(name="created", type="datetime", nullable=false)
*/
protected $created;
/**
* #var \DateTime
*
* #ORM\Column(name="updated", type="datetime", nullable=true)
*/
protected $updated;
/**
* #var EndpointServerConfig
*
* #ORM\OneToOne(targetEntity="EndpointServerConfig", inversedBy="endpoint", cascade={"persist"})
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="endpoint_server_config_id", referencedColumnName="id")
* })
*
* #Groups({"export"})
*/
protected $endpointServerConfig;
/**
* #param integer $id
*
* #return Endpoint
*/
public function setId($id)
{
$this->id = $id;
return $this;
}
/**
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* #param string $role
*
* #return Endpoint
*/
public function setRole($role)
{
$this->role = $role;
return $this;
}
/**
* #return string
*/
public function getRole()
{
return $this->role;
}
/**
* #param string $type
*
* #return Endpoint
*/
public function setType($type)
{
$this->type = $type;
return $this;
}
/**
* #return string
*
* #Groups({"export"})
*/
public function getType()
{
return str_replace(
'Endpoint',
'',
(new ReflectionClass($this))->getShortName()
);
}
/**
* #param string $serverPlace
*
* #return Endpoint
*/
public function setServerPlace($serverPlace)
{
$this->serverPlace = $serverPlace;
return $this;
}
/**
* #return string
*/
public function getServerPlace()
{
return $this->serverPlace;
}
/**
* #param string $contactPerson
*
* #return Endpoint
*/
public function setContactPerson($contactPerson)
{
$this->contactPerson = $contactPerson;
return $this;
}
/**
* #return string
*/
public function getContactPerson()
{
return $this->contactPerson;
}
/**
* #param \DateTime $created
*
* #return Endpoint
*/
public function setCreated($created)
{
$this->created = $created;
return $this;
}
/**
* #return \DateTime
*/
public function getCreated()
{
return $this->created;
}
/**
* #param \DateTime $updated
*
* #return Endpoint
*/
public function setUpdated($updated)
{
$this->updated = $updated;
return $this;
}
/**
* #return \DateTime
*/
public function getUpdated()
{
return $this->updated;
}
/**
* #param EndpointServerConfig $endpointServerConfig
*
* #return Endpoint
*/
public function setEndpointServerConfig(EndpointServerConfig $endpointServerConfig = null)
{
$this->endpointServerConfig = $endpointServerConfig;
return $this;
}
/**
* #return EndpointServerConfig
*/
public function getEndpointServerConfig()
{
return $this->endpointServerConfig;
}
}
EndpointServerConfig
namespace Doctrine\Tests\Models\DDC6786;
use Doctrine\ORM\Mapping as ORM;
/**
* EndpointServerConfig
*
* #ORM\Table(name="endpoint_server_config", indexes={
* #ORM\Index(name="fk_endpoint_server_config_server_idx", columns={"server_name"})}
* )
* #ORM\Entity
*/
class EndpointServerConfig
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
protected $id;
/**
* #var string
*
* #ORM\Column(name="dns_address", type="string", length=253, nullable=true)
*/
protected $dnsAddress;
/**
* #var Server
*
* #ORM\ManyToOne(targetEntity="Server")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="server_name", referencedColumnName="name")
* })
*/
protected $server;
/**
* #var Endpoint
*
* #ORM\OneToOne(targetEntity="Endpoint", mappedBy="endpointServerConfig")
*/
protected $endpoint;
/**
* #param integer $id
*
* #return EndpointServerConfig
*/
public function setId($id)
{
$this->id = $id;
return $this;
}
/**
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* #param string $dnsAddress
*
* #return EndpointServerConfig
*/
public function setDnsAddress($dnsAddress)
{
$this->dnsAddress = $dnsAddress;
return $this;
}
/**
* #return string
*/
public function getDnsAddress()
{
return $this->dnsAddress;
}
/**
* #param Server $server
*
* #return EndpointServerConfig
*/
public function setServer(Server $server = null)
{
if(! $server || ! $server->getName()) {
$server = null;
}
$this->server = $server;
return $this;
}
/**
* #return Server
*/
public function getServer()
{
return $this->server;
}
/**
* #param Endpoint $endpoint
*
* #return EndpointServerConfig
*/
public function setEndpoint($endpoint)
{
$this->endpoint = $endpoint;
return $this;
}
/**
* #return Endpoint
*/
public function getEndpoint()
{
return $this->endpoint;
}
}
Server
namespace Doctrine\Tests\Models\DDC6786;
use Doctrine\ORM\Mapping as ORM;
/**
* Server
*
* #ORM\Table(name="server")
* #ORM\Entity
*
* #author automatix
*/
class Server
{
/**
* #var string
*
* #ORM\Column(name="name", type="string", length=32, nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="NONE")
*/
protected $name;
/**
* #var boolean
*
* #ORM\Column(name="active", type="boolean", nullable=true)
*/
protected $active;
/**
* #var \DateTime
*
* #ORM\Column(name="updated", type="datetime", nullable=true)
*/
protected $updated;
/**
* #var string
*
* #ORM\Column(name="node_name", type="string", length=50, nullable=true)
*/
protected $nodeName;
/**
* #var string
*
* #ORM\Column(name="virtual_node_name", type="string", length=50, nullable=true)
*/
protected $virtualNodeName;
/**
* Not relevant for ORM. Should become obsolete after and be removed after the migration to Doctrine.
*
* #var EndpointServerConfig[]
*/
protected $endpointServerConfigs;
/**
* #param string $name
*
* #return Server
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* #return string
*/
public function getName()
{
return $this->name;
}
/**
* #param boolean $active
*
* #return Server
*/
public function setActive($active)
{
$this->active = $active;
return $this;
}
/**
* #return boolean
*/
public function getActive()
{
return $this->active;
}
/**
* #param \DateTime $updated
*
* #return Server
*/
public function setUpdated($updated)
{
$this->updated = $updated;
return $this;
}
/**
* #return \DateTime
*/
public function getUpdated()
{
return $this->updated;
}
/**
* #param string $nodeName
*
* #return Server
*/
public function setNodeName($nodeName)
{
$this->nodeName = $nodeName;
return $this;
}
/**
* #return string
*/
public function getNodeName()
{
return $this->nodeName;
}
/**
* #param string $virtualNodeName
*
* #return Server
*/
public function setVirtualNodeName($virtualNodeName)
{
$this->virtualNodeName = $virtualNodeName;
return $this;
}
/**
* #return string
*/
public function getVirtualNodeName()
{
return $this->virtualNodeName;
}
/**
* #param EndpointServerConfig[] $endpointServerConfigs
*
* #return Server
*/
public function setEndpointServerConfigs($endpointServerConfigs)
{
$this->endpointServerConfigs = $endpointServerConfigs;
return $this;
}
/**
* #return EndpointServerConfig[] $endpointServerConfigs
*/
public function getEndpointServerConfigs()
{
return $this->endpointServerConfigs;
}
}
The problem was caused by the annotations. use Doctrine\ORM\Mapping as ORM; & #ORM\Entity doesn't work, but just #ORM\Entity (and #ORM\Table etc.) does.

A new entity was found through the relationship - error

I try to establish a simple association of two tables. But I always geht the following error:
A new entity was found through the relationship 'Shopware\CustomModels\JoeKaffeeAbo\Client#abos' that was not configured to cascade persist operations for entity: Shopware\CustomModels\JoeKaffeeAbo\Abo#00000000211b173900000000cf7658ac
Here are my Models:
<?php
namespace Shopware\CustomModels\JoeKaffeeAbo;
use Symfony\Component\Validator\Constraints as Assert,
Doctrine\Common\Collections\ArrayCollection,
Shopware\Components\Model\ModelEntity,
Doctrine\ORM\Mapping AS ORM;
/**
* #ORM\Entity
* #ORM\Table(name="joe_kaffee_abo_abos")
*/
class Abo extends ModelEntity
{
public function __construct() {
$client = new ArrayCollection();
}
/**
* Unique identifier
*
* #var integer
* #ORM\Column(name="id", type="integer", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
protected $id;
/**
* #ORM\ManyToMany(targetEntity="Shopware\CustomModels\JoeKaffeeAbo\Client", inversedBy="abos", cascade={"persist", "remove"})
**/
protected $clients;
/**
* #var string
* #ORM\Column(name="name", type="string", length=255, nullable=true)
*/
protected $name = '';
/**
* #var string
* #ORM\Column(name="desc", type="string", length=255, nullable=true)
*/
protected $desc = '';
/**
* #var string
* #ORM\Column(name="name_en", type="string", length=255, nullable=true)
*/
protected $name_en = '';
/**
* #var string
* #ORM\Column(name="desc_en", type="string", length=255, nullable=true)
*/
protected $desc_en = '';
//getter and setters...
}
?>
Client Model:
<?php
namespace Shopware\CustomModels\JoeKaffeeAbo;
use Symfony\Component\Validator\Constraints as Assert,
Doctrine\Common\Collections\ArrayCollection,
Shopware\Components\Model\ModelEntity,
Doctrine\ORM\Mapping AS ORM;
/**
* #ORM\Entity
* #ORM\Table(name="joe_kaffee_abo_client")
*/
class Client extends ModelEntity
{
public function __construct() {
$this->abos = new ArrayCollection();
}
/**
* Unique identifier
*
* #var integer
* #ORM\Column(name="id", type="integer", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
protected $id;
/**
* #ORM\ManyToMany(targetEntity="Shopware\CustomModels\JoeKaffeeAbo\Abo", mappedBy="clients", cascade={"persist", "remove"})
**/
protected $abos = null;
public function addAbo($abo)
{
$abo->addClient($this);
$this->abos[] = $abo;
}
/**
* #var integer
* #ORM\Column(name="customerid", type="integer", nullable=true)
*/
protected $customerid;
/**
* #var integer
* #ORM\Column(name="customernumber", type="integer", nullable=true)
*/
protected $customernumber;
/**
* #var boolean
* #ORM\Column(name="is_active", type="boolean", nullable=true)
*/
protected $is_active;
//Getters and Setters
}
?>
The error occurs after I executed the following statements:
$client = new Client();
$client->setCustomerid(12);
$client->setCustomernumber(12);
$client->setIs_active(true);
Shopware()->Models()->persist($client);
$abo = new Abo();
$abo->setName("name");
$abo->setDesc("desc");
$abo->setName_en("name");
$abo->setDesc_en("desc");
$client->addAbo($abo);
//$abo->addClient($client);
//$client->addAbo($abo);
Shopware()->Models()->persist($client);
//Shopware()->Models()->persist($abo);
Shopware()->Models()->flush();
What this is telling you is that you need to save the Abo Entity before saving the client.
$abo = new Abo();
$abo->setName("name");
$abo->setDesc("desc");
$abo->setName_en("name");
$abo->setDesc_en("desc");
Shopware()->Models()->persist($abo); //Persist the Abo before assigning it to the client
$client->addAbo($abo);
//$abo->addClient($client);
//$client->addAbo($abo);
Shopware()->Models()->persist($client);
//Shopware()->Models()->persist($abo);
Shopware()->Models()->flush();

ZF2 doctrine OneToMany annotation form

I have following entities:
User
/**
* Users
*
* #ORM\Table(name="users")
* #ORM\Entity(repositoryClass="Users\Entity\Repository\UsersRepository")
* #Annotation\Name("user")
* #Annotation\Hydrator("Zend\Stdlib\Hydrator\ClassMethods")
*/
class User
{
/**
* #var string
*
* #ORM\Column(name="name", type="string", length=100, nullable=false)
* #Annotation\Filter({"name":"StringTrim"})
* #Annotation\Validator({"name":"StringLength", "options":{"min":2, "max":100}})
* #Annotation\Attributes({"type":"text","class":"form-control"})
* #Annotation\Options({"label":"Full name:"})
*/
private $name;
/**
* #var User\Entity\UserItem
*
* #ORM\OneToMany(targetEntity="User\Entity\UserItem", mappedBy="user")
* #Annotation\Exclude()
*/
private $items;
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
* #Annotation\Exclude()
*/
private $id;
public function __construct()
{
$this->vessels = new ArrayCollection();
}
public function setName($name)
{
$this->name = $name;
return $this;
}
public function getName()
{
return $this->name;
}
public function getId()
{
return $this->id;
}
public function getItems()
{
return $this->items
}
public function setItems($items)
{
$this->itemr = $items;
return $this;
}
Item
/**
* Items
* #ORM\Entity
* #ORM\Table(name="items")
* #ORM\Entity(repositoryClass="User\Entity\Repository\ItemsRepository")
* #Annotation\Name("item")
* #Annotation\Hydrator("Zend\Stdlib\Hydrator\ClassMethods")
*/
class Item
{
/**
* #var string
*
* #ORM\Column(name="name", type="string", length=100, nullable=false)
* #Annotation\Filter({"name":"StringTrim"})
* #Annotation\Validator({"name":"StringLength", "options":{"min":2, "max":100}})
* #Annotation\Attributes({"type":"text","class":"form-control"})
* #Annotation\Options({"label":"Name:"})
*/
private $name;
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
* #Annotation\Exclude()
*/
private $id;
And finally entity keepeing relation between those two
UserItem
/**
* UserItem
*
* #ORM\Table(name="users_items")
* #ORM\Entity(repositoryClass="User\Entity\Repository\UserItemsRepository")
* #Annotation\Name("user_item")
* #Annotation\Hydrator("Zend\Stdlib\Hydrator\ClassMethods")
*/
class UserItem{
/**
* #var Users\Entity\User
*
* #ORM\ManyToOne(targetEntity="Users\Entity\User", inversedBy="items")
* #ORM\JoinColumn(name="user_id", referencedColumnName="id")
* #Annotation\Exclude()
*/
private $user;
/**
* #var User\Entity\Item
*
* #ORM\ManyToOne(targetEntity="User\Entity\Item", inversedBy="users")
* #ORM\JoinColumn(name="item_id", referencedColumnName="id")
* #Annotation\Type("DoctrineModule\Form\Element\ObjectSelect")
*/
private $item;
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
* #Annotation\Exclude()
*/
private $id;
With this entities i can create and edit User and Item. Form are generated from annotations.
My question is how can i generate form for assigning items to user. Preferably as select field(s) with multiple selection. And after submitting doctrine should save the relations.
I wrote this form to represent items to select:
class ItemsForm extends Form
{
public function __construct($entityManager, $name = null)
{
parent::__construct('items');
$this->setAttribute('method', 'post');
$this->add(array(
'type' => 'DoctrineModule\Form\Element\ObjectSelect',
'name' => 'items',
'attributes' => array(
'id' => 'selectItems',
'multiple' => true,
'data-placeholder' => 'Items'
),
'options' => array(
'object_manager' => $entityManager,
'target_class' => 'User\Entity\Item',
'property' => 'name',
),
)
);
}
}
And now i do not know how to preselect items user has already assigned.
In select field in value you must have id from items. After submit you can do something like that
foreach($post['items'] as $itemId)
{
$userItem = new UserItem();
$userItem->user = $this->getEntityManager()->getReference('User', $userId);
$userItem->item = $this->getEntityManager()->getReference('Item', $itemId);
$this->getEntityManager()->save($userItem);
}

Updating Doctrine Collection

I'm working on a survey project and I got 3 Entities, survey(umfrage), surveyQuestion(umfrageFrage) and surveyAnswer(umfrageAntwort).
Here are the entities(removed all unnecessary fields):
namespace Umfrage\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
/**
* Umfrage
*
* #ORM\Table(name="umfrage")
* #ORM\Entity
*/
class Umfrage
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var Fragen
*
* #ORM\OneToMany(targetEntity="Umfrage\Entity\UmfrageFrage", mappedBy="umfrage", cascade={"persist","remove"})
*/
private $fragen;
public function __construct() {
$this->fragen = new ArrayCollection();
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set fragen
*
* #param \Umfrage\Entity\UmfrageFrage $fragen
*
* #return UmfrageFrage
*/
public function setFragen($fragen)
{
$this->fragen = $fragen;
return $this;
}
/** Get fragen
*
* #param \Umfrage\Entity\UmfrageFrage $fragen
*
* #return UmfrageFrage
*/
public function getFragen() {
return $this->fragen;
}
public function addFragen(Collection $fragen)
{
foreach ($fragen as $frage) {
$frage->setUmfrage($this);
$this->fragen->add($frage);
}
}
public function removeFragen(Collection $fragen)
{
foreach ($fragen as $frage) {
$frage->setUmfrage(null);
$this->fragen->removeElement($frage);
}
}
}
The Questions:
namespace Umfrage\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
/**
* UmfrageFrage
*
* #ORM\Table(name="umfrage_frage")
* #ORM\Entity
*/
class UmfrageFrage
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var \Umfrage\Entity\Umfrage
*
* #ORM\ManyToOne(targetEntity="Umfrage\Entity\Umfrage", inversedBy="fragen")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="umfrage_id", referencedColumnName="id")
* })
*/
private $umfrage;
/**
* #var Antworten
*
* #ORM\OneToMany(targetEntity="Umfrage\Entity\UmfrageAntwort", mappedBy="umfrageFrage", cascade={"all"})
*/
private $antworten;
public function __construct() {
$this->antworten = new ArrayCollection();
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set umfrage
*
* #param \Umfrage\Entity\Umfrage $umfrage
*
* #return UmfrageFrage
*/
public function setUmfrage(\Umfrage\Entity\Umfrage $umfrage = null)
{
$this->umfrage = $umfrage;
return $this;
}
/**
* Get umfrage
*
* #return \Umfrage\Entity\Umfrage
*/
public function getUmfrage()
{
return $this->umfrage;
}
/**
* Set antworten
*
* #param \Umfrage\Entity\UmfrageAntwort $antworten
*
* #return UmfrageAntwort
*/
public function setAntworten($antworten)
{
$this->antworten = $antworten;
return $this;
}
/** Get antworten
*
* #param \Umfrage\Entity\UmfrageAntwort $antworten
*
* #return UmfrageAntwort
*/
public function getAntworten() {
return $this->antworten;
}
public function addAntworten(Collection $antworten)
{
foreach ($antworten as $antwort) {
$antwort->setUmfrageFrage($this);
$this->antworten->add($antwort);
}
}
public function removeAntworten(Collection $antworten)
{
foreach ($antworten as $antwort) {
$this->antworten->removeElement($antwort);
}
}
}
The Answers:
namespace Umfrage\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
/**
* UmfrageAntwort
*
* #ORM\Table(name="umfrage_antwort")
* #ORM\Entity
*/
class UmfrageAntwort
{
/**
* #var integer
*
* #ORM\Column(name="id", type="bigint", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var \Umfrage\Entity\UmfrageFrage
*
* #ORM\ManyToOne(targetEntity="Umfrage\Entity\UmfrageFrage", inversedBy="antworten")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="umfrage_frage_id", referencedColumnName="id")
* })
*/
private $umfrageFrage;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set umfrageFrage
*
* #param \Umfrage\Entity\UmfrageFrage $umfrageFrage
*
* #return UmfrageFrage
*/
public function setUmfrageFrage($umfrageFrage)
{
$this->umfrageFrage = $umfrageFrage;
return $this;
}
/**
* Get umfrageFrage
*
* #return \Umfrage\Entity\UmfrageFrage
*/
public function getUmfrageFrage()
{
return $this->umfrageFrage;
}
}
The Controller action:
public function editAction()
{
$id = (int) $this->params()->fromRoute('id', 0);
if (!$id) {
return $this->redirect()->toRoute('umfrage', array('action'=>'add'));
}
$umfrage = $this->getEntityManager()->find('Umfrage\Entity\Umfrage', $id);
$form = new UmfrageForm($this->getEntityManager());
$form->setHydrator(new DoctrineEntity($this->getEntityManager(),'Umfrage\Entity\Umfrage'));
$form->bind($umfrage);
$request = $this->getRequest();
if ($request->isPost()) {
$form->setData($request->getPost());
if ($form->isValid()) {
$this->getEntityManager()->persist($umfrage);
$this->getEntityManager()->flush();
// Redirect to overview
return $this->redirect()->toRoute('umfrage');
}
}
$this->layout('layout/umfrage_backend');
return new ViewModel(array(
'id' => $id,
'form' => $form
));
}
And the view:
<?php
// module/Umfrage/view/umfrage/umfrage/edit.phtml:
use Doctrine\Common\Util\Debug;
$title = 'Umfrage bearbeiten';
$this->headTitle($title);
?>
<h1><?php echo $this->escapeHtml($title); ?></h1>
<?php
$form = $this->form;
$form->setAttribute('action', $this->url(
'umfrage',
array(
'action' => 'edit',
'id' => $this->id,
)
));
echo $this->ztbForm($form);
?>
Adding a Survey works fine, Deleting also, the Survey and its related Questions/Answers are removed from the DB. Only the Update actions doesn't work as expected. Survey and Questions are updated, but for the Answers I receive an Insert, instead of an Update, which results in duplicate entries in the DB. What's wrong with the Mapping(Code)?
Thanks in advance for your help!