Array does not keep previous elements after being updated - php

Job entity has a property called candidates which is an array of Users and it is not mapped or related to any other entity.On given route we fetch specific Job object by id.We update our candidates array by assigning the user who we get from the current session.It turns out that the user is being saved, but on each call we lose those users which had been saved before.
Why does that happen?
/**
* #Route("/job/apply/{id}", requirements={"id"="\d+"}, name="student_candidate", methods={"POST"})
*
* #param int $id
*
* #return JsonResponse
*/
public function apply(int $id)
{
$job = $this->getDoctrine()->getRepository(Job::class)->find($id);
$candidate = $this->getUser();
$job->addCandidate($candidate);
$this->getDoctrine()->getManager()->flush();
return new JsonResponse([
'status' => 'success',
'message' => 'some_success_message'
]);
}
class Job
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="title", type="string", length=255)
*/
private $title;
/**
* #var string
*
* #ORM\Column(name="content", type="text", length=65535)
*/
private $content;
/**
* #var User[]|ArrayCollection
*/
private $candidates;
public function __construct()
{
$this->candidates = new ArrayCollection();
}
/**
* #return User[]|ArrayCollection
*/
public function getCandidates()
{
return $this->candidates;
}
/**
* #param User $user
*
* #return Job
*/
public function addCandidate(User $user)
{
$this->candidates[] = $user;
return $this;
}
}

Related

Symfony Could not determine access type when using EntityType form builder

I have 2 entities Cars and Parts and I want to be able to create new Car with multiple parts. For this reason I made this form in CarsType
$builder->
add('make')->
add('model')->
add('travelledDistance')->
add('parts',EntityType::class,array(
'class' => Parts::class,
'choice_label'=>"name",
'query_builder' => function(PartsRepository $partsRepository){
return $partsRepository->getAllPartsForCarsForm();
},
'multiple' => true
));
It gives me this error
Could not determine access type for property "parts" in class
"AppBundle\Entity\Cars".
Here is my entity Cars
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Cars
*
* #ORM\Table(name="cars")
* #ORM\Entity(repositoryClass="AppBundle\Repository\CarsRepository")
*/
class Cars
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="Make", type="string", length=255)
*/
private $make;
/**
* #var string
*
* #ORM\Column(name="Model", type="string", length=255)
*/
private $model;
/**
* #var int
*
* #ORM\Column(name="TravelledDistance", type="bigint")
*/
private $travelledDistance;
/**
* #ORM\ManyToMany(targetEntity="AppBundle\Entity\Parts", inversedBy="cars")
* #ORM\JoinTable(
* name="Parts_Cars",
* joinColumns={
* #ORM\JoinColumn(name="Part_Id", referencedColumnName="id")
* },
* inverseJoinColumns={
* #ORM\JoinColumn(name="Car_Id", referencedColumnName="id")
* })
*/
private $parts;
/**
* Get id
*
* #return int
*/
public function getId()
{
return $this->id;
}
/**
* Set make
*
* #param string $make
*
* #return Cars
*/
public function setMake($make)
{
$this->make = $make;
return $this;
}
/**
* Get make
*
* #return string
*/
public function getMake()
{
return $this->make;
}
/**
* Set model
*
* #param string $model
*
* #return Cars
*/
public function setModel($model)
{
$this->model = $model;
return $this;
}
/**
* Get model
*
* #return string
*/
public function getModel()
{
return $this->model;
}
/**
* Set travelledDistance
*
* #param integer $travelledDistance
*
* #return Cars
*/
public function setTravelledDistance($travelledDistance)
{
$this->travelledDistance = $travelledDistance;
return $this;
}
/**
* Get travelledDistance
*
* #return int
*/
public function getTravelledDistance()
{
return $this->travelledDistance;
}
/**
* #return mixed
*/
public function getParts()
{
return $this->parts;
}
}
And in case it matters here is my Parts entity
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Parts
*
* #ORM\Table(name="parts")
* #ORM\Entity(repositoryClass="AppBundle\Repository\PartsRepository")
*/
class Parts
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="Name", type="string", length=255)
*/
private $name;
/**
* #var string
*
* #ORM\Column(name="Price", type="decimal", precision=10, scale=2)
*/
private $price;
/**
* #var int
*
* #ORM\Column(name="Quantity", type="integer")
*/
private $quantity;
/**
* #ORM\ManyToOne(targetEntity="AppBundle\Entity\Suppliers", inversedBy="parts")
* #ORM\JoinColumn(name="Supplier_Id", referencedColumnName="id")
*/
private $supplier;
/**
* #ORM\ManyToMany(targetEntity="AppBundle\Entity\Cars", mappedBy="parts")
*/
private $cars;
/**
* Get id
*
* #return int
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* #param string $name
*
* #return Parts
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* #return string
*/
public function getName()
{
return $this->name;
}
/**
* Set price
*
* #param string $price
*
* #return Parts
*/
public function setPrice($price)
{
$this->price = $price;
return $this;
}
/**
* Get price
*
* #return string
*/
public function getPrice()
{
return $this->price;
}
/**
* Set quantity
*
* #param integer $quantity
*
* #return Parts
*/
public function setQuantity($quantity)
{
$this->quantity = $quantity;
return $this;
}
/**
* Get quantity
*
* #return int
*/
public function getQuantity()
{
return $this->quantity;
}
/**
* #return mixed
*/
public function getSupplier()
{
return $this->supplier;
}
/**
* #return mixed
*/
public function getCars()
{
return $this->cars;
}
public function __toString()
{
return $this->getName();
}
}
To save time here is the mapping between the 2 entities as well as the property parts in Cars
/**
* #ORM\ManyToMany(targetEntity="AppBundle\Entity\Parts", inversedBy="cars")
* #ORM\JoinTable(
* name="Parts_Cars",
* joinColumns={
* #ORM\JoinColumn(name="Part_Id", referencedColumnName="id")
* },
* inverseJoinColumns={
* #ORM\JoinColumn(name="Car_Id", referencedColumnName="id")
* })
*/
private $parts;
and In Parts
/**
* #ORM\ManyToMany(targetEntity="AppBundle\Entity\Cars", mappedBy="parts")
*/
private $cars;
Here is the newAction in CarsController
/**
* Creates a new car entity.
*
* #Route("/new", name="cars_new")
* #Method({"GET", "POST"})
*/
public function newAction(Request $request)
{
$carsRepository = $this->getDoctrine()->getManager()->getRepository('AppBundle:Cars');
$car = new Cars();
$form = $this->createForm('AppBundle\Form\CarsType', $car);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($car);
$em->flush();
return $this->redirectToRoute('cars_show', array('id' => $car->getId()));
}
return $this->render('cars/new.html.twig', array(
'car' => $car,
'form' => $form->createView(),
));
}
My question is - How can I make it so that I can create new Car with several Parts and to save the relationship in the database so that when I retrieve the Car I can get the parts as well?
Basically how to make it so when I create a new car the relationship is saved in the parts_cars table which holds the id's?
Let Doctrine do the JOIN work
Since you're doing a ManyToMany (EntityToEntity), the #JoinColumn directives are not needed.
Try removing it from the Cars entity.
Cars
/**
* #ORM\ManyToMany(targetEntity="AppBundle\Entity\Parts", inversedBy="cars")
*/
$parts
The only cases in which you need to specify the JoinColumns are:
Joining against self
Joining where the primary key is not the Entity ID.
Need to define fields in the join_table
Would be MUCH easier in this case to do A OneToMany J ManyToOne B
Since you're doing none of the above, Doctrine is having trouble accessing the Entities' IDENTITY fields for the join.

Generating Symfony Form from generic data

I am designing an application for managing reports. I'm developing this with Symfony 3.2.6 In this picture you can see my data model. I want to do two things:
1. Create new layouts for a report with a number of given modules
2. Create instances of this reports and save them in the database
So I think this is a way to do this with this data model, isn't it? But how can I now create a form in Symfony from that?
I do something like that:
$builder
->add('name', TextType::class)
;
foreach ($options['moduleValues'] as $moduleValue)
{
if($moduleValue instanceof RangeModuleValue)
{
$builder->add('value', RangeType::class, array(
'attr' => array(
'min' => $moduleValue->getRangeModule()->getStartValue(),
'max' => $moduleValue->getRangeModule()->getEndValue()
)
));
}
}
But then I get the error:
Neither the property "value" nor one of the methods "getValue()", "value()", "isValue()", "hasValue()", "__get()" exist and have public access in class "ReportBundle\Entity\Report".
I think the error is clear, the "value" is in the table range_module_value. But how should I change my design or my Form to handle this?
Note: the parent class Module exists, because there will be other modules like "TextModule" in future.
Here is my class Report:
class Report
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="name", type="string", length=255)
*/
private $name;
/**
* #ORM\ManyToOne(targetEntity="ReportBundle\Entity\ReportLayout")
* #ORM\JoinColumn(name="layout_id", referencedColumnName="id")
*/
private $layout;
/**
* Report constructor.
* #param int $id
*/
public function __construct($layout)
{
$this->layout = $layout;
}
/**
* #return int
*/
public function getLayout()
{
return $this->layout;
}
/**
* #param int $layout
*/
public function setLayout($layout)
{
$this->layout = $layout;
}
/**
* Get id
*
* #return int
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* #param string $name
*
* #return Report
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* #return string
*/
public function getName()
{
return $this->name;
}
}
And here is the class RangeModuleValue, in which I want to persist the value of a module for a specific report.
class RangeModuleValue
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ORM\ManyToOne(targetEntity="ReportBundle\Entity\RangeModule")
* #ORM\JoinColumn(name="rangeModule_id", referencedColumnName="id")
*/
private $rangeModule;
/**
* #ORM\ManyToOne(targetEntity="ReportBundle\Entity\Report")
* #ORM\JoinColumn(name="report_id", referencedColumnName="id")
*/
private $report;
/**
* #var int
*
* #ORM\Column(name="value", type="integer")
*/
private $value;
/**
* RangeModuleValue constructor.
* #param $rangeModule
* #param $report
*/
public function __construct($report, $rangeModule)
{
$this->report = $report;
$this->rangeModule = $rangeModule;
}
/**
* Get id
*
* #return int
*/
public function getId()
{
return $this->id;
}
/**
* Set rangeModule
*
* #param string $rangeModule
*
* #return RangeModuleValue
*/
public function setRangeModule($rangeModule)
{
$this->rangeModule = $rangeModule;
return $this;
}
/**
* Get rangeModule
*
* #return string
*/
public function getRangeModule()
{
return $this->rangeModule;
}
/**
* Set report
*
* #param string $report
*
* #return RangeModuleValue
*/
public function setReport($report)
{
$this->report = $report;
return $this;
}
/**
* Get report
*
* #return string
*/
public function getReport()
{
return $this->report;
}
/**
* Set value
*
* #param integer $value
*
* #return RangeModuleValue
*/
public function setValue($value)
{
$this->value = $value;
return $this;
}
/**
* Get value
*
* #return int
*/
public function getValue()
{
return $this->value;
}
}
In class report you add this function to allow add many $rangeModule or $value :
public function addrangemodule (RangeModuleValue $rangeModule)
{
$day->setIdReport($this);
$this->ranges->add($day);
}
But ranged should be an ArrayCollection :
public function setranges(ArrayCollection $ranges)
{
$this->ranges= $ranges;
}
In Controller adds as much as you need :
$range = new RangeModuleValue();
$report->addrangemodule ($range);
This code is just an example i am not sure that he works.
For more information this is the documentation :
https://symfony.com/doc/current/form/form_collections.html
http://www.doctrine-project.org/api/common/2.3/class-Doctrine.Common.Collections.ArrayCollection.html

Doctrine 2: How to update one-to-one bidirectional

I have problem with updating one-to-one bidirectional association.
User Entity
/**
*
* #ORM\Table(name="test_user")
*/
class User
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="login", type="string", length=32, nullable=false, unique=true)
*/
private $login;
/**
*
* #ORM\OneToOne(targetEntity="Points", mappedBy="user", cascade={"persist"})
*/
private $points;
...
/**
* Set points
*/
public function setPoints(array $points)
{
$this->points = new Points($points);
$this->points->setUser($this);
return $this;
}
/**
* Get points
*/
public function getPoints()
{
return $this->points;
}
}
Points Entity
/**
* Points
*
* #ORM\Table(name="test_user_points")
* #ORM\Entity
*/
class Points {
/**
* #var integer
*
* #ORM\Column(name="id", type="integer", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* #var integer
*
* #ORM\Column(type="integer", nullable=false)
*/
private $points;
/**
* #var string
*
* #ORM\Column(name="period", type="string", length=24)
*/
private $period;
/**
* #var User
*
* #ORM\OneToOne(targetEntity="User", inversedBy="points")
* #ORM\JoinColumn(name="user_id", referencedColumnName="id",onDelete="CASCADE", nullable=false)
*/
private $user;
/**
* Constructor
*/
public function __construct(array $params = array())
{
$hydrator = new MyHydrator();
$hydrator->hydrate($params, $this);
}
...
/**
* Set user
*
* #param User $user
*/
public function setUser(User $user = null)
{
$this->user = $user;
return $this;
}
/**
* Get user
*
* #return User
*/
public function getUser()
{
return $this->user;
}
}
Class MyHydrator is converting from array(first param) to object(second param). It is very important and I have to use it.
My save function looks like this:
public function save(array $data)
{
...
// This is how my input data looks
$data = array(
'login' => 'Test',
array(
'points' => 999,
'period' => 'monthly'
)
);
if ($userExists) {
// UPDATE
$hydrator = new MyHydrator();
$hydrator->hydrate($data, $userExists);
$this->em->persist($userExists);
$this->em->flush();
} else {
// INSERT
$user = new User($data);
$this->em->persist($user);
$this->em->flush();
}
}
Inserting to database works perfect, but when I try to update record I get error:
SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '4' for key 'UNIQ_DAD93D6EA76ED395'
4 is a value of user_id column in points table
How can I edit existing record without error about duplicate id?
It's old but since I encoutered a similar issue, I resolved it this way :
in User
public function setPoints($points)
{
if ($this->points !== null) {
$this->points->setUser(null);
}
$this->points = $points;
$points->setUser($this);
}

ZF2 Doctrine get manytomany relations with objectSelect

I have multiple users, with multiple stores in a many to many relational database. Every user has multiple stores attached to them.
Now, i want to load all the storenames from a logged in user in a select form.
How can i do this?
My user entity:
namespace Application\Entity;
use BjyAuthorize\Provider\Role\ProviderInterface;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use ZfcUser\Entity\UserInterface;
/**
* An example of how to implement a role aware user entity.
*
* #ORM\Entity
* #ORM\Table(name="users")
* #ORM\Entity(repositoryClass="Application\Repositories\UserRepository")
*
*/
class User implements UserInterface, ProviderInterface
{
/**
* #var int
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #var string
* #ORM\Column(type="string", length=255, unique=true, nullable=true)
*/
protected $username;
/**
* #var string
* #ORM\Column(type="string", unique=true, length=255)
*/
protected $email;
/**
* #var string
* #ORM\Column(type="string", length=50, nullable=true)
*/
protected $displayName;
/**
* #var string
* #ORM\Column(type="string", length=128)
*/
protected $password;
/**
* #var int
*/
protected $state;
/**
* #var \Doctrine\Common\Collections\Collection
* #ORM\ManyToMany(targetEntity="Application\Entity\Role")
* #ORM\JoinTable(name="user_role_linker",
* joinColumns={#ORM\JoinColumn(name="user_id", referencedColumnName="id")},
* inverseJoinColumns={#ORM\JoinColumn(name="role_id", referencedColumnName="id")}
* )
*/
protected $roles;
/**
* #var \Doctrine\Common\Collections\Collection
* #ORM\ManyToMany(targetEntity="Application\Entity\Store")
* #ORM\JoinTable(name="user_store_linker",
* joinColumns={#ORM\JoinColumn(name="user_id", referencedColumnName="id")},
* inverseJoinColumns={#ORM\JoinColumn(name="store_id", referencedColumnName="id")}
* )
*/
protected $stores;
/**
* Initialies the roles variable.
*/
public function __construct()
{
$this->roles = new ArrayCollection();
$this->stores = new ArrayCollection();
}
/**
* Get id.
*
* #return int
*/
public function getId()
{
return $this->id;
}
/**
* Set id.
*
* #param int $id
*
* #return void
*/
public function setId($id)
{
$this->id = (int) $id;
}
/**
* Get username.
*
* #return string
*/
public function getUsername()
{
return $this->username;
}
/**
* Set username.
*
* #param string $username
*
* #return void
*/
public function setUsername($username)
{
$this->username = $username;
}
/**
* Get email.
*
* #return string
*/
public function getEmail()
{
return $this->email;
}
/**
* Set email.
*
* #param string $email
*
* #return void
*/
public function setEmail($email)
{
$this->email = $email;
}
/**
* Get displayName.
*
* #return string
*/
public function getDisplayName()
{
return $this->displayName;
}
/**
* Set displayName.
*
* #param string $displayName
*
* #return void
*/
public function setDisplayName($displayName)
{
$this->displayName = $displayName;
}
/**
* Get password.
*
* #return string
*/
public function getPassword()
{
return $this->password;
}
/**
* Set password.
*
* #param string $password
*
* #return void
*/
public function setPassword($password)
{
$this->password = $password;
}
/**
* Get state.
*
* #return int
*/
public function getState()
{
return $this->state;
}
/**
* Set state.
*
* #param int $state
*
* #return void
*/
public function setState($state)
{
$this->state = $state;
}
/**
* Get role.
*
* #return array
*/
public function getRoles()
{
return $this->roles->getValues();
}
/**
* Add a role to the user.
*
* #param Role $role
*
* #return void
*/
public function addRole($role)
{
$this->roles[] = $role;
}
/**
* Get store.
*
* #return array
*/
public function getStores()
{
return $this->stores;
}
/**
* Get store.
*
* #return array
*/
public function getStore($id)
{
return $this->stores[$id]->getValues();
}
/**
* Add a store to the user.
*
* #param Role $store
*
* #return void
*/
public function addStore($store)
{
$this->stores[] = $store;
}
}
My store Entity:
namespace Application\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* An example entity that represents a store.
*
* #ORM\Entity
* #ORM\Table(name="store")
*
*/
class Store
{
/**
* #var int
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #var string
* #ORM\Column(type="string", name="storeName", length=255, unique=true, nullable=true)
*/
protected $storeName;
/**
* #var \Doctrine\Common\Collections\Collection
* #ORM\ManyToMany(targetEntity="Application\Entity\Product" )
*/
protected $products;
/**
* Initialies the roles variable.
*/
public function __construct()
{
$this->products = new ArrayCollection();
}
/**
* Get the id.
*
* #return int
*/
public function getId()
{
return $this->id;
}
/**
* Set the id.
*
* #param int $id
*
* #return void
*/
public function setId($id)
{
$this->id = (int)$id;
}
/**
* Get the store id.
*
* #return string
*/
public function getStoreName()
{
return $this->storeName;
}
/**
* Set the store id.
*
* #param string $storeName
*
* #return void
*/
public function setStoreName($storeName)
{
$this->storeName = (string) $storeName;
}
/**
* Get product.
*
* #return array
*/
public function getProducts()
{
return $this->products->getValues();
}
/**
* Add a product to the user.
*
* #param Role $product
*
* #return void
*/
public function addProduct($products)
{
$this->products[] = $products;
}
}
My form:
$this->add(array(
'type' => 'DoctrineModule\Form\Element\ObjectSelect',
'name' => 'stores',
'attributes' => array(
'multiple' => true,
),
'options' => array(
'object_manager' => $objectManager,
'target_class' => 'Application\Entity\User',
'label' => 'Selecteer winkel',
'column-size' => 'sm-9',
'label_attributes' => array('class' => 'col-sm-3 control-label'),
'property' => 'stores',
'find_method' => array(
'name' => 'findBy',
'params' => array(
'criteria' => array('id' => $userid)
),
),
'is_method' => true,
),
));
I'm getting this message:
File:
zend/vendor/zendframework/zendframework/library/Zend/View/Helper/Escaper/AbstractHelper.php:70
Message:
Object provided to Escape helper, but flags do not allow recursion
Anyone?
Ok i've figured it out with a custom repository.
Add a repositoryclass to your store entity
<?php
namespace Application\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
*
* #ORM\Entity
* #ORM\Table(name="store")
* #ORM\Entity(repositoryClass="Application\Repositories\StoreRepository")
*
*/
class Store
{
/**
* #var int
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #var string
* #ORM\Column(type="string", name="storeName", length=255, unique=true, nullable=true)
*/
protected $storeName;
/**
* #var \Doctrine\Common\Collections\Collection
* #ORM\ManyToMany(targetEntity="Application\Entity\Product", inversedBy="stores")
* #ORM\JoinTable(name="product_store")
*/
protected $products;
/**
* #var \Doctrine\Common\Collections\Collection
* #ORM\ManyToMany(targetEntity="Application\Entity\Category", inversedBy="stores")
* #ORM\JoinTable(name="category_store")
*/
protected $categories;
/**
* #var \Doctrine\Common\Collections\Collection
* #ORM\ManyToMany(targetEntity="Application\Entity\User", inversedBy="stores")
* #ORM\JoinTable(name="user_store")
*/
protected $users;
/**
* Initialies the roles variable.
*/
public function __construct()
{
$this->products = new ArrayCollection();
$this->categories = new ArrayCollection();
$this->users = new ArrayCollection();
}
/**
* Get the id.
*
* #return int
*/
public function getId()
{
return $this->id;
}
/**
* Set the id.
*
* #param int $id
*
* #return void
*/
public function setId($id)
{
$this->id = (int)$id;
}
/**
* Get the store id.
*
* #return string
*/
public function getStoreName()
{
return $this->storeName;
}
/**
* Set the store id.
*
* #param string $storeName
*
* #return void
*/
public function setStoreName($storeName)
{
$this->storeName = (string) $storeName;
}
/**
* Get product.
*
* #return array
*/
public function getProducts()
{
return $this->products->getValues();
}
/**
* Add a product to the user.
*
* #param Role $product
*
* #return void
*/
public function addProduct($products)
{
$this->products[] = $products;
}
/**
* Get category.
*
* #return array
*/
public function getCategories()
{
return $this->categories->getValues();
}
/**
* Add a product to the user.
*
* #param Role $product
*
* #return void
*/
public function addCategory($categories)
{
$this->categories[] = $categories;
}
/**
* Get category.
*
* #return array
*/
public function getUsers()
{
return $this->users->getValues();
}
/**
* Add a product to the user.
*
* #param Role $product
*
* #return void
*/
public function addUser($users)
{
$this->users[] = $users;
}
}
My user entity
namespace Application\Entity;
use BjyAuthorize\Provider\Role\ProviderInterface;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use ZfcUser\Entity\UserInterface;
/**
*
* #ORM\Entity
* #ORM\Table(name="users")
* #ORM\Entity(repositoryClass="Application\Repositories\UserRepository")
*
*/
class User implements UserInterface, ProviderInterface
{
/**
* #var int
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #var string
* #ORM\Column(type="string", length=255, unique=true, nullable=true)
*/
protected $username;
/**
* #var string
* #ORM\Column(type="string", unique=true, length=255)
*/
protected $email;
/**
* #var string
* #ORM\Column(type="string", length=50, nullable=true)
*/
protected $displayName;
/**
* #var string
* #ORM\Column(type="string", length=128)
*/
protected $password;
/**
* #var int
*/
protected $state;
/**
* #var \Doctrine\Common\Collections\Collection
* #ORM\ManyToMany(targetEntity="Application\Entity\Role")
* #ORM\JoinTable(name="user_role_linker",
* joinColumns={#ORM\JoinColumn(name="user_id", referencedColumnName="id")},
* inverseJoinColumns={#ORM\JoinColumn(name="role_id", referencedColumnName="id")}
* )
*/
protected $roles;
/**
* #var \Doctrine\Common\Collections\Collection
* #ORM\ManyToMany(targetEntity="Application\Entity\Store", mappedBy="users")
*/
protected $stores;
/**
* Initialies the roles variable.
*/
public function __construct()
{
$this->roles = new ArrayCollection();
$this->stores = new ArrayCollection();
}
/**
* Get id.
*
* #return int
*/
public function getId()
{
return $this->id;
}
/**
* Set id.
*
* #param int $id
*
* #return void
*/
public function setId($id)
{
$this->id = (int) $id;
}
/**
* Get username.
*
* #return string
*/
public function getUsername()
{
return $this->username;
}
/**
* Set username.
*
* #param string $username
*
* #return void
*/
public function setUsername($username)
{
$this->username = $username;
}
/**
* Get email.
*
* #return string
*/
public function getEmail()
{
return $this->email;
}
/**
* Set email.
*
* #param string $email
*
* #return void
*/
public function setEmail($email)
{
$this->email = $email;
}
/**
* Get displayName.
*
* #return string
*/
public function getDisplayName()
{
return $this->displayName;
}
/**
* Set displayName.
*
* #param string $displayName
*
* #return void
*/
public function setDisplayName($displayName)
{
$this->displayName = $displayName;
}
/**
* Get password.
*
* #return string
*/
public function getPassword()
{
return $this->password;
}
/**
* Set password.
*
* #param string $password
*
* #return void
*/
public function setPassword($password)
{
$this->password = $password;
}
/**
* Get state.
*
* #return int
*/
public function getState()
{
return $this->state;
}
/**
* Set state.
*
* #param int $state
*
* #return void
*/
public function setState($state)
{
$this->state = $state;
}
/**
* Get role.
*
* #return array
*/
public function getRoles()
{
return $this->roles->getValues();
}
/**
* Add a role to the user.
*
* #param Role $role
*
* #return void
*/
public function addRole($role)
{
$this->roles[] = $role;
}
/**
* Get store.
*
* #return array
*/
public function getStores()
{
return $this->stores;
}
/**
* Get store.
*
* #return array
*/
public function getStore($id)
{
return $this->stores[$id]->getValues();
}
/**
* Add a store to the user.
*
* #param Role $store
*
* #return void
*/
public function addStore($store)
{
$this->stores[] = $store;
}
}
The object select
$this->add(array(
'type' => 'DoctrineModule\Form\Element\ObjectSelect',
'name' => 'stores',
'attributes' => array(
'multiple' => true,
),
'options' => array(
'object_manager' => $objectManager,
'target_class' => 'Application\Entity\Store',
'label' => 'Selecteer winkel',
'column-size' => 'sm-9',
'label_attributes' => array('class' => 'col-sm-3 control-label'),
'property' => 'storeName',
'is_method' => true,
'find_method' => array(
'name' => 'storesByUser',
'params' => array(
'criteria' => array('id' => $userid),
),
),
),
));
My custom store repository
<?php
namespace Application\Repositories;
use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\Query\ResultSetMapping;
use Doctrine\DBAL\Types\Type;
class StoreRepository extends EntityRepository
{
public function storesByUser(array $criteria){
return $this->createQueryBuilder('s')
->select('s')
->innerJoin("s.users", "u", "WITH", "u=:userid")
->setParameter("userid", $criteria['id'])
->getQuery()->getResult();
}
}

Persist link in One-to-many / many-to-many - Doctrine and Symfony2

I had a many-to-many using a User and Account entity. I needed to add an isOwner field to the association table so I changed it to a one-to-many / many-to-one relation. Below are my 3 entities (user, account, useraccount).
When I persist the user, the user record and account record are both added, but the association record is not. I am also unsure as to how I can set the isOwner field whilst persisting the user.
Does anyone know how the association record can be persisted? Should the association record be added automatically?
User:
/**
* xxx\CoreBundle\Entity\User
*
* #ORM\Table(name="user")
* #ORM\Entity
*/
class User implements UserInterface
{
/**
* #var integer $id
*
* #ORM\Column(name="id", type="integer", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* #var string $firstName
*
* #ORM\Column(name="firstName", type="string", length=255, nullable=false)
* #Assert\NotBlank()
*/
private $firstName;
/**
* #var Account
*
* #ORM\OneToMany(targetEntity="UserAccount", mappedBy="user", cascade={"persist"})
*/
private $account;
public function __construct()
{
$this->account = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set firstName
*
* #param string $firstName
*/
public function setFirstName($firstName)
{
$this->firstName = $firstName;
}
/**
* Get firstName
*
* #return string
*/
public function getFirstName()
{
return $this->firstName;
}
/**
* Add account
*
* #param xxx\CoreBundle\Entity\Account $account
*/
public function addAccount(\xxx\CoreBundle\Entity\Account $account)
{
$this->account[] = $account;
}
/**
* Get account
*
* #return Doctrine\Common\Collections\Collection
*/
public function getAccount()
{
return $this->account;
}
}
Account:
/**
* xxx\CoreBundle\Entity\Account
*
* #ORM\Table(name="account")
* #ORM\Entity(repositoryClass="xxx\CoreBundle\Repository\AccountRepository")
*/
class Account
{
/**
* #var integer $id
*
* #ORM\Column(name="id", type="integer", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* #var string $name
*
* #ORM\Column(name="name", type="string", length=255, nullable=false)
* #Assert\NotBlank()
*/
private $name;
/**
* #var User
*
* #ORM\OneToMany(targetEntity="UserAccount", mappedBy="account", cascade={"persist"})
*/
private $user;
public function __construct()
{
$this->user = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* 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;
}
/**
* Add user
*
* #param xxx\CoreBundle\Entity\User $user
*/
public function addUser(\xxx\CoreBundle\Entity\User $user)
{
$this->user[] = $user;
}
/**
* Get user
*
* #return Doctrine\Common\Collections\Collection
*/
public function getUser()
{
return $this->user;
}
}
UserAccount:
/**
* xxx\CoreBundle\Entity\UserAccount
*
* #ORM\Table(name="user_account")
* #ORM\Entity
*/
class UserAccount
{
/**
* #var integer $id
*
* #ORM\Column(name="id", type="integer", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* #ORM\ManyToOne(targetEntity="User", inversedBy="account", cascade={"persist"})
*/
private $user;
/**
* #ORM\ManyToOne(targetEntity="Account", inversedBy="user", cascade={"persist"})
*/
private $account;
/**
* #var boolean $isOwner
*
* #ORM\Column(name="isOwner", type="boolean", nullable=false)
*/
private $isOwner;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* #param string $name
*/
public function setName($name)
{
$this->name = $name;
}
/**
* Get isOwner
*
* #return bool
*/
public function getIsOwner()
{
return $this->isOwner;
}
/**
* Set isOwner
*
* #param string $isOwner
*/
public function setIsOwner($isOwner)
{
$this->isOwner = $isOwner;
}
/**
* Set user
*
* #param xxx\CoreBundle\Entity\User $user
*/
public function setUser(\xxx\CoreBundle\Entity\User $user)
{
$this->user = $user;
}
/**
* Get user
*
* #return xxx\CoreBundle\Entity\User
*/
public function getUser()
{
return $this->user;
}
/**
* Set account
*
* #param xxx\CoreBundle\Entity\Account $account
*/
public function setAccount(\xxx\CoreBundle\Entity\Account $account)
{
$this->account = $account;
}
/**
* Get account
*
* #return xxx\CoreBundle\Entity\Account
*/
public function getAccount()
{
return $this->account;
}
}
Controller:
$account = new Account();
$account->setName('Test account');
$user = new User();
$user->setFirstName('John');
$user->addAccount($account);
$manager->persist($user);
$manager->flush();
You are trying to persist an account as UserAccount entity. Try this:
$account = new Account();
$account->setName('Test account');
$user = new User();
$user->setFirstName('John');
$user_account = new UserAccount();
$user_account->setAccount($account);
$user_account->setUser($user);
$manager->persist($user);
$manager->flush();

Categories