Symfony 2 - Doctrine - oneToMany : delete from many - doctrine-orm

I have two entities : Episode and Version.
When I tried to delete a version a get an exception:
Notice: Undefined index: episode in /var/www/Mendrock/vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php line 1561
I already check relations but I didn't find the error.
My entities:
Episode
namespace Mendrock\Bundle\SagaBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Mendrock\Bundle\SagaBundle\Entity\Episode
*
* #ORM\Table(name="episode")
* #ORM\Entity(repositoryClass="Mendrock\Bundle\SagaBundle\Repository\EpisodeRepository")
*/
class Episode {
...
/**
*
* #ORM\OneToMany(targetEntity="Version", mappedBy="episode", cascade={"remove", "persist"})
*/
private $versions;
Version
namespace Mendrock\Bundle\SagaBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;
/**
* Mendrock\Bundle\SagaBundle\Entity\EpisodeVersion
*
* #ORM\Table(name="version")
* #ORM\Entity(repositoryClass="Mendrock\Bundle\SagaBundle\Repository\EpisodeVersionRepository")
*/
class Version {
...
/**
* #ORM\ManyToOne(targetEntity="Episode", inversedBy="versions", cascade={"persist"})
* #ORM\JoinColumn(name="episode_id", referencedColumnName="id")
*/
private $episode;
...
Controller
/**
*
* #Route("/versionConfirmeDelete/{id}", options={"expose"=true})
* #Method("GET")
* #Template()
*/
public function versionConfirmeDeleteAction($id) {
$em = $this->getDoctrine()->getManager();
$entity = $em->getRepository('MendrockSagaBundle:Version')->find($id);
if (!$entity) {
throw $this->createNotFoundException('Unable to find Version entity.');
}
$deleteForm = $this->createDeleteForm($id);
return array(
'entity' => $entity,
'delete_form' => $deleteForm->createView(),
);
}
/**
* Deletes a Episode entity.
*
* #Route("/versionDelete/{id}")
* #Method("POST")
*/
public function versionDeleteAction(Request $request, $id) {
$form = $this->createDeleteForm($id);
$form->bind($request);
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$entity = $em->getRepository('MendrockSagaBundle:Version')->find($id);
$episode = $entity->getEpisode();
if (!$entity) {
throw $this->createNotFoundException('Unable to find Version entity.');
}
$em->remove($entity);
$em->flush();
$this->get('session')->setFlash('success', 'La version "' . $entity . '" de l\'épisode "'.$episode.'" à été supprimé !');
} else {
$this->get('session')->setFlash('error', 'Impossible de supprimer la version "' . $entity . '".');
}
return $this->redirect($this->generateUrl('mendrock_saga_default_episodes'));
}
#################################################################
### Commun ##################################################
#################################################################
private function createDeleteForm($id) {
return $this->createFormBuilder(array('id' => $id))
->add('id', 'hidden')
->getForm()
;
}
Any ideas of my problem?

I found the error, it was an other relation for this entities who make problem.
Name of attribut was not corresponded.

Related

upload not running with VichUploaderBundle

I would like to use a VichUploaderBundle for upload files in my symfony 3.2.3 project (PHP 5.6). I try lot of thing but nothing upload run. But the persistance layer run perfeclty with my database.
config.yml
knp_gaufrette:
stream_wrapper: ~
adapters:
fileupload_adapter:
local:
directory: %kernel.root_dir%/../web/
create: true
filesystems:
fileupload_fs:
adapter: fileupload_adapter
# VichUploaderBundle Configuration
vich_uploader:
db_driver: orm
twig: true
storage: gaufrette
mappings:
tgmedia_file:
uri_prefix: web
upload_destination: fileupload_fs
namer: vich_uploader.namer_origname
Entity
namespace MediaBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use TweedeGolf\MediaBundle\Model\AbstractFile;
use Vich\UploaderBundle\Mapping\Annotation as Vich;
/**
* #ORM\Entity
* #Vich\Uploadable
* #ORM\HasLifecycleCallbacks
* #ORM\Table
*/
class FileUpload
{
/**
* #ORM\Column(type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* NOTE: This is not a mapped field of entity metadata, just a simple property.
*
* #Vich\UploadableField(mapping="tgmedia_file", fileNameProperty="imageName")
*
* #var File
*/
protected $imageFile;
/**
* #ORM\Column(type="string", length=255)
*
* #var string
*/
private $imageName;
/**
* #ORM\Column(type="datetime")
*
* #var \DateTime
*/
protected $updatedAt;
/**
* #return int
*/
public function getId()
{
return $this->id;
}
/**
* #return File|null
*/
public function getImageFile()
{
return $this->imageFile;
}
/**
* If manually uploading a file (i.e. not using Symfony Form) ensure an instance
* of 'UploadedFile' is injected into this setter to trigger the update. If this
* bundle's configuration parameter 'inject_on_load' is set to 'true' this setter
* must be able to accept an instance of 'File' as the bundle will inject one here
* during Doctrine hydration.
*
* #param File|\Symfony\Component\HttpFoundation\File\UploadedFile $image
*
* #return Product
*/
public function setImageFile(File $image = null)
{
$this->imageFile = $image;
if ($image) {
// It is required that at least one field changes if you are using doctrine
// otherwise the event listeners won't be called and the file is lost
$this->updatedAt = new \DateTimeImmutable();
}
return $this;
}
/**
* #param string $imageName
*
* #return FileUpload
*/
public function setImageName($imageName)
{
$this->imageName = $imageName;
return $this;
}
/**
* #return string|null
*/
public function getImageName()
{
return $this->imageName;
}
/**
* Set updatedAt
*
* #param \DateTime $updatedAt
*
* #return FileUpload
*/
public function setUpdatedAt($updatedAt)
{
$this->updatedAt = $updatedAt;
return $this;
}
/**
* Get updatedAt
*
* #return \DateTime
*/
public function getUpdatedAt()
{
return $this->updatedAt;
}
}
The formType
<?php
namespace MediaBundle\Form;
use MediaBundle\Entity\File;
use MediaBundle\Entity\FileUpload;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\FileType;
use Vich\UploaderBundle\Form\Type\VichFileType;
use Vich\UploaderBundle\Form\Type\VichImageType;
class FileUploadType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('imageName')
->add('imageFile', VichImageType::class, [
'required' => false,
'allow_delete' => true,
'download_link' => true,
'mapped' => false,
'data_class' => null
])
->add('submit', SubmitType::class);
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => FileUpload::class,
'csrf_protection' => false,
));
}
}
Controller
<?php
namespace MediaBundle\Controller;
use MediaBundle\Entity\File;
use MediaBundle\Entity\FileUpload;
use MediaBundle\Entity\Product;
use MediaBundle\Form\FileType;
use MediaBundle\Form\FileUploadType;
use MediaBundle\Form\ProductType;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
class MainController extends Controller
{
public function indexAction(Request $request)
{
$em = $this->getDoctrine()->getManager();
$fileUploaded = new FileUpload();
$form = $this->createForm(FileUploadType::class, $fileUploaded, array(
'action' => $this->generateUrl('media_main')
));
$form->handleRequest($request);
if ($form->isSubmitted())
{
$fileUploaded->setUpdatedAt(new \DateTime());
$fileUploaded->setImageFile($form->get('imageFile')->getData());
$em->persist($fileUploaded);
$em->flush();
}
return $this->render('MediaBundle:main:index.html.twig', array(
'form' => $form->createView()
));
}
}
Where is my error ? What wrong ?
uri_prefix: /project/web/fileupload_fs
upload_destination: '%kernel.root_dir%/../web/fileupload_fs'
uri_prefix begins from www folder.
and change controller like that
if ($form->isSubmitted() && $form->isValid())
{
$em->persist($fileUploaded);
$em->flush();
}

Doctrine2 ORM OneToMany or ManyToOne not working

I would like to have the relationship between 2 tables, with OneToMany and ManyToOne relationships.
Survey
id
title
Questions:
id
survey_id
So i am looking to list the surveys and their respective questions, so how can i achieve that.
Here is my code,
Survey Entity:
<?php
namespace Survey\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
use Library\Entity\BaseEntity;
/**
* Description of Survey
*
* #author Mubarak
*/
/**
* #ORM\Entity
* #ORM\Table(name="surveys")
*/
class Survey extends BaseEntity{
public function __construct() {
$this->questions = new ArrayCollection();
}
/**
* #ORM\Column(name="title", type="string")
* #var string
*/
protected $title;
/**
* #ORM\Column(name="description", type="string")
* #var string
*/
protected $description;
/**
* #ORM\OneToMany(targetEntity="Survey\Entity\Questions", mappedBy="surveys")
*/
private $questions;
public function getTitle() {
return $this->title;
}
public function setTitle($title) {
$this->title = $title;
}
public function getDescription() {
return $this->description;
}
public function setDescription($description) {
$this->description = $description;
return $this;
}
public function getQuestions() {
return $this->questions;
}
public function setQuestions(ArrayCollection $questions) {
$this->questions = $questions;
}
public function __toString() {
return __CLASS__ . ": [id: {$this->id}, name: {$this->name}]";
}
}
Below is the Questions Entity:
<?php
namespace Survey\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
use Library\Entity\BaseEntity;
/**
* Description of Survey Questions
*
* #author Mubarak
*/
/**
* #ORM\Entity
* #ORM\Table(name="survey_questions")
*/
class Questions extends BaseEntity{
/**
* #ORM\Column(name="question", type="string")
* #var string
*/
protected $question;
/**
* #ORM\ManyToOne(targetEntity="Survey\Entity\Survey", inversedBy="questions")
* #ORM\JoinColumn(name="survey_id", referencedColumnName="id")
*/
private $surveys;
public function getQuestion() {
return $this->question;
}
public function setQuestion($question) {
$this->question = $question;
}
public function getSurveys() {
return $this->surveys;
}
public function setSurveys(ArrayCollection $surveys) {
$this->surveys = $surveys;
}
public function __toString() {
return __CLASS__ . ": [id: {$this->id}, name: {$this->name}]";
}
}
What is the mistake i am doing here, this is my code to get the surveys and questions:
$surveysInterface = $this->surveyService->getAllSurveys();
foreach($surveysInterface as $survey){
$surveysArray[] = array(
'id' => $survey->getId(),
'title' => $survey->getTitle(),
'description' => $survey->getDescription(),
'isActive' => $survey->getActive(),
'questions' => array(
'question' => $survey->getQuestions()->getQuestion()
)
);
}
'questions' => array(
'question' => $survey->getQuestions()->getQuestion()
)
This part look wrong since getQuestions() function return array of Questions entities. Suggest to change it to
'questions' => $survey->getQuestions()

Using Zend Framework 2 + Doctrine2.3 with ObjectSelect and ManyToOne relations

I"m having a bit of trouble with using Doctrine's ObjectSelect on ManyToOne relations.
The relations I have below using ManyToMany work 100% adding and editing. My edit form is populated with the current selection without any problems.
The issue arises with the ManyToOne relations, it appears the form is not being populated with the current selection.
I have tried dumping the Task entity before I bind it to the form and it looks 100% right, all my relations are populated in the entity.
However after binding it, the form is being displayed without the current value selected.
Task entity:
/**
* #ORM\Entity
* #ORM\Table(name="tasks")
*/
class Task
{
/**
* #ORM\Id
* #ORM\Column(type="integer");
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
...
/**
* #ORM\ManyToOne(targetEntity="Category")
* #ORM\JoinColumn(name="category_id", referencedColumnName="id")
*/
protected $category;
...
/**
* #ORM\ManyToMany(targetEntity="ZDUser\Entity\User")
* #ORM\JoinTable(name="tasks_assigned_user_linker",
* joinColumns={#ORM\JoinColumn(name="task_id", referencedColumnName="id")},
* inverseJoinColumns={#ORM\JoinColumn(name="user_id", referencedColumnName="id")}
* )
*/
protected $assignedUsers;
/**
* Initialize
*/
public function __construct()
{
$this->assignedUsers = new ArrayCollection();
}
/**
* We need a few getters and setters
*/
public function getId()
{
return $this->id;
}
public function setId($id)
{
$this->id = $id;
}
public function getCategory() {
return $this->category;
}
public function setCategory(Category $category) {
$this->category = $category;
}
public function getAssignedUsers() {
return $this->assignedUsers;
}
public function addAssignedUsers(Collection $users) {
foreach ($users as $user) {
$this->assignedUsers->add($user);
}
}
public function removeAssignedUsers(Collection $users) {
foreach ($users as $user) {
$this->assignedUsers->removeElement($user);
}
}
}
I'm using ManyToOne in most of my entities, I find this way a little easier and extensible going forward. I can just add addtional entities and link them to other ones without having to do relations on both sides.
Category Entity
/**
* #ORM\Entity
* #ORM\Table(name="task_categories")
* #property int $id
* #property string $name
*/
class Category
{
/**
* #ORM\Id
* #ORM\Column(type="integer");
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\Column(type="string", nullable=false)
*/
protected $name;
...
/**
* Setters and getters we need
*/
public function getId()
{
return $this->id;
}
public function setId($id)
{
$this->id = (int) $id;
}
public function getName()
{
return $this->name;
}
public function setName($name)
{
$this->name = $name;
}
}
User Entity:
/**
* #ORM\Entity
* #ORM\Table(name="users")
*/
class User implements UserInterface, ProviderInterface
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
...
/**
* #ORM\ManyToMany(targetEntity="ZDUser\Entity\Group")
* #ORM\JoinTable(name="users_groups_linker",
* joinColumns={#ORM\JoinColumn(name="user_id", referencedColumnName="id")},
* inverseJoinColumns={#ORM\JoinColumn(name="group_id", referencedColumnName="id")}
* )
*/
protected $groups;
/**
* Initialies the object
*/
public function __construct()
{
$this->groups = new ArrayCollection();
}
/* Getters and setters, we must define these for the implementation to work */
public function getId()
{
return $this->id;
}
public function setId($id)
{
$this->id = (int) $id;
}
/* Get and add groups */
public function getGroups()
{
return $this->groups;
}
public function addGroup(Group $group)
{
$this->groups->add($group);
}
Form code:
class TaskForm extends Form implements ObjectManagerAwareInterface
{
protected $objectmanager;
public function __construct(EntityManager $em)
{
// we want to ignore the name passed
parent::__construct('task');
$this->setHydrator(new DoctrineHydrator($em,'TaskList\Entity\Task'));
$this->setAttribute('method', 'post');
$this->add(array(
'name' => 'id',
'attributes' => array(
'type' => 'hidden',
),
));
$this->add(array(
'name' => 'subject',
'type' => 'Text',
'options' => array(
'label' => 'Subject',
),
));
$this->add(array(
'name' => 'category',
'type' => 'DoctrineModule\Form\Element\ObjectSelect',
'options' => array(
'label' => "Category",
'object_manager' => $em,
'target_class' => 'TaskList\Entity\Category',
'property' => 'name',
),
));
$this->add(array(
'name' => 'assignedUsers',
'type' => 'DoctrineModule\Form\Element\ObjectSelect',
'attributes' => array(
'multiple' => 'multiple',
),
'options' => array(
'label' => "Assigned To (User)",
'object_manager' => $em,
'target_class' => 'ZDUser\Entity\User',
'property' => 'email',
),
));
Controller for Edit & Add:
public function addAction()
{
$this->addedit();
// Grab form
$form = new TaskForm($this->getEntityManager());
// Grab any request we may have
$request = $this->getRequest();
// If it a post ...
if ($request->isPost()) {
$task = new Task();
$form->bind($task);
// Populate data
$form->setData($request->getPost());
// Check if the form is valid
if ($form->isValid()) {
// Setup some things we need
$task->setCreated(new \DateTime("now"));
// Save
$this->getEntityManager()->persist($task);
$this->getEntityManager()->flush();
// Redirect to list of tasks
return $this->redirect()->toRoute('tasklist');
}
}
return array(
'form' => $form
);
}
public function editAction()
{
$this->addedit();
// Get ID or redirect
$id = (int)$this->getEvent()->getRouteMatch()->getParam('id');
if (!$id) {
return $this->redirect()->toRoute('tasklist');
}
// Create a form
$form = new TaskForm($this->getEntityManager());
// Grab entity from doctrine
$task = $this->getEntityManager()->find('TaskList\Entity\Task', $id);
// Bind the form to the task
$form->bind($task);
// Check if we have a request and if its POST
$request = $this->getRequest();
if ($request->isPost()) {
// If it is, set the form data from the request
$form->setData($request->getPost());
// If the form is valid, bind the values
if ($form->isValid()) {
// Setup some things we need
$task->setLastUpdated(new \DateTime("now"));
// Flush the update
$this->getEntityManager()->flush();
// Redirect to list of tasks
return $this->redirect()->toRoute('tasklist');
}
}
return array(
'id' => $id,
'form' => $form,
);
}
I'm so sure I'm missing something really simple.
I had a similar problem, see this issue on the DoctrineORMModule GitHub for more info.
It's something to do with Doctrine not returning the correct ID field from metadata when Proxies Entities are loaded. The solutions are as follows:
Wait for official fix in Doctrine 2.4 (you can install 2.4-beta2 now!).
Subclass the ObjectSelect to force the use of the correct ID field (someone in the aforelinked issue did this).
Patch DoctrineModule with this:
--- doctrine/doctrine-module/src/DoctrineModule/Form/Element/Proxy.php 2013-03-11 17:49:55.406011600 -0300
+++ doctrine/doctrine-module/src/DoctrineModule/Form/Element/Proxy.php 2013-03-11 17:51:33.592710900 -0300
## -240,7 +240,10 ##
if (count($identifier) > 1) {
//$value = $key;
} else {
- $value = current($metadata->getIdentifierValues($value));
+ // Doctrine has a bug that makes the following not work,
+ // this is a horrible workaround until Doctrine 2.4 is released with a fix.
+ //$value = current($metadata->getIdentifierValues($value));
+ $value = $value->getId();
}
}
}
The $value->getId() relies on that method being available in the corresponding entity. This isn't recommended but a quick fix.
Probably not the right way? I posted my idea to their ML :)
Probably not the right way? I posted my idea to their ML :)
diff --git a/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php
index cba525a..2f62375 100644
--- a/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php
+++ b/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php
## -667,7 +667,17 ## class ClassMetadataInfo implements ClassMetadata
return $id;
}
- $value = $this->reflFields[$this->identifier[0]]->getValue($entity);
+
+ /**
+ * NK: First try use the getter, in the case of a proxied object, the reflection is not going to work
+ * as the proxied object does not have any properties
+ */
+ $getter = 'get' . ucfirst($this->identifier[0]);
+ if (method_exists($entity, $getter)) {
+ $value = $entity->$getter();
+ } else {
+ $value = $this->reflFields[$this->identifier[0]]->getValue($entity);
+ }

symfony2 : unable to save parent id in embedded object

I'm trying tu use my first embedded form (SF2.1 + Doctrine2)
the entities :
<?php
namespace Chris\BabelBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Doctrine\Common\Collections\ArrayCollection;
/**
* #ORM\Entity
*/
class Needs
{
/**
* #ORM\GeneratedValue
* #ORM\Id
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\ManyToOne(targetEntity="Projects")
* #Assert\NotBlank()
*/
private $relatedproject;
/**
* #ORM\ManyToOne(targetEntity="Activities")
* #Assert\NotBlank()
*/
private $relatedactivity;
/**
* #ORM\ManyToOne(targetEntity="Jobs")
* #Assert\NotBlank()
*/
private $relatedjob;
/**
* #ORM\Column(type="string", length=255)
* #Assert\NotBlank()
*/
private $firstname;
/**
* #ORM\Column(type="string", length=255)
* #Assert\NotBlank()
*/
private $lastname;
/**
* #ORM\ManyToOne(targetEntity="Experiences")
* #Assert\NotBlank()
*/
private $relatedexperience;
/**
* #ORM\ManyToOne(targetEntity="Plants")
* #Assert\NotBlank()
*/
private $maintrainingplant;
/**
* #ORM\Column(type="date")
* #Assert\NotBlank()
*/
private $trainingneedstart;
/**
* #ORM\Column(type="date")
* #Assert\NotBlank()
*/
private $readytowork;
/**
* #var ArrayCollection $trainings
*
* #ORM\OneToMany(targetEntity="Trainings", mappedBy="training", cascade={"persist", "remove", "merge"})
*/
private $trainings;
/**
* Constructor
*/
public function __construct()
{
$this->trainings = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set firstname
*
* #param string $firstname
* #return Needs
*/
public function setFirstname($firstname)
{
$this->firstname = $firstname;
return $this;
}
/**
* Get firstname
*
* #return string
*/
public function getFirstname()
{
return $this->firstname;
}
/**
* Set lastname
*
* #param string $lastname
* #return Needs
*/
public function setLastname($lastname)
{
$this->lastname = $lastname;
return $this;
}
/**
* Get lastname
*
* #return string
*/
public function getLastname()
{
return $this->lastname;
}
/**
* Set trainingneedstart
*
* #param \DateTime $trainingneedstart
* #return Needs
*/
public function setTrainingneedstart($trainingneedstart)
{
$this->trainingneedstart = $trainingneedstart;
return $this;
}
/**
* Get trainingneedstart
*
* #return \DateTime
*/
public function getTrainingneedstart()
{
return $this->trainingneedstart;
}
/**
* Set readytowork
*
* #param \DateTime $readytowork
* #return Needs
*/
public function setReadytowork($readytowork)
{
$this->readytowork = $readytowork;
return $this;
}
/**
* Get readytowork
*
* #return \DateTime
*/
public function getReadytowork()
{
return $this->readytowork;
}
/**
* Set relatedproject
*
* #param \Chris\BabelBundle\Entity\Projects $relatedproject
* #return Needs
*/
public function setRelatedproject(\Chris\BabelBundle\Entity\Projects $relatedproject = null)
{
$this->relatedproject = $relatedproject;
return $this;
}
/**
* Get relatedproject
*
* #return \Chris\BabelBundle\Entity\Projects
*/
public function getRelatedproject()
{
return $this->relatedproject;
}
/**
* Set relatedactivity
*
* #param \Chris\BabelBundle\Entity\Activities $relatedactivity
* #return Needs
*/
public function setRelatedactivity(\Chris\BabelBundle\Entity\Activities $relatedactivity = null)
{
$this->relatedactivity = $relatedactivity;
return $this;
}
/**
* Get relatedactivity
*
* #return \Chris\BabelBundle\Entity\Activities
*/
public function getRelatedactivity()
{
return $this->relatedactivity;
}
/**
* Set relatedjob
*
* #param \Chris\BabelBundle\Entity\Jobs $relatedjob
* #return Needs
*/
public function setRelatedjob(\Chris\BabelBundle\Entity\Jobs $relatedjob = null)
{
$this->relatedjob = $relatedjob;
return $this;
}
/**
* Get relatedjob
*
* #return \Chris\BabelBundle\Entity\Jobs
*/
public function getRelatedjob()
{
return $this->relatedjob;
}
/**
* Set relatedexperience
*
* #param \Chris\BabelBundle\Entity\Experiences $relatedexperience
* #return Needs
*/
public function setRelatedexperience(\Chris\BabelBundle\Entity\Experiences $relatedexperience = null)
{
$this->relatedexperience = $relatedexperience;
return $this;
}
/**
* Get relatedexperience
*
* #return \Chris\BabelBundle\Entity\Experiences
*/
public function getRelatedexperience()
{
return $this->relatedexperience;
}
/**
* Set maintrainingplant
*
* #param \Chris\BabelBundle\Entity\Plants $maintrainingplant
* #return Needs
*/
public function setMaintrainingplant(\Chris\BabelBundle\Entity\Plants $maintrainingplant = null)
{
$this->maintrainingplant = $maintrainingplant;
return $this;
}
/**
* Get maintrainingplant
*
* #return \Chris\BabelBundle\Entity\Plants
*/
public function getMaintrainingplant()
{
return $this->maintrainingplant;
}
/**
* Add trainings
*
* #param \Chris\BabelBundle\Entity\Trainings $trainings
* #return Needs
*/
public function addTraining(\Chris\BabelBundle\Entity\Trainings $trainings)
{
$this->trainings[] = $trainings;
return $this;
}
/**
* Remove trainings
*
* #param \Chris\BabelBundle\Entity\Trainings $trainings
*/
public function removeTraining(\Chris\BabelBundle\Entity\Trainings $trainings)
{
$this->trainings->removeElement($trainings);
}
/**
* Get trainings
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getTrainings()
{
return $this->trainings;
}
public function __toString() {return $this->getFirstname();}
}
<?php
namespace Chris\BabelBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
/**
* #ORM\Entity
*/
class Trainings
{
/**
* #ORM\GeneratedValue
* #ORM\Id
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\ManyToOne(targetEntity="Plants")
* #Assert\NotBlank()
*/
private $trainingplant;
/**
* #ORM\Column(type="date")
* #Assert\NotBlank()
*/
private $trainingstart;
/**
* #ORM\Column(type="date")
* #Assert\NotBlank()
*/
private $trainingend;
/**
* #var Needs $trainings
*
* #ORM\ManyToOne(targetEntity="Needs", inversedBy="trainings", cascade={"persist", "remove", "merge"})
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="Needs_id", referencedColumnName="id")
* })
*/
private $training;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set trainingstart
*
* #param \DateTime $trainingstart
* #return Trainings
*/
public function setTrainingstart($trainingstart)
{
$this->trainingstart = $trainingstart;
return $this;
}
/**
* Get trainingstart
*
* #return \DateTime
*/
public function getTrainingstart()
{
return $this->trainingstart;
}
/**
* Set trainingend
*
* #param \DateTime $trainingend
* #return Trainings
*/
public function setTrainingend($trainingend)
{
$this->trainingend = $trainingend;
return $this;
}
/**
* Get trainingend
*
* #return \DateTime
*/
public function getTrainingend()
{
return $this->trainingend;
}
/**
* Set trainingplant
*
* #param \Chris\BabelBundle\Entity\Plants $trainingplant
* #return Trainings
*/
public function setTrainingplant(\Chris\BabelBundle\Entity\Plants $trainingplant = null)
{
$this->trainingplant = $trainingplant;
return $this;
}
/**
* Get trainingplant
*
* #return \Chris\BabelBundle\Entity\Plants
*/
public function getTrainingplant()
{
return $this->trainingplant;
}
/**
* Set training
*
* #param \Chris\BabelBundle\Entity\Needs $training
* #return Trainings
*/
public function setTraining(\Chris\BabelBundle\Entity\Needs $training = null)
{
$this->training = $training;
return $this;
}
/**
* Get training
*
* #return \Chris\BabelBundle\Entity\Needs
*/
public function getTraining()
{
return $this->training;
}
}
The 2 Controllers :
<?php
namespace Chris\BabelBundle\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Chris\BabelBundle\Entity\Needs;
use Chris\BabelBundle\Form\NeedsType;
/**
* Needs controller.
*
*/
class NeedsController extends Controller
{
/**
* Lists all Needs entities.
*
*/
public function indexAction()
{
$em = $this->getDoctrine()->getManager();
$entities = $em->getRepository('ChrisBabelBundle:Needs')->findAll();
return $this->render('ChrisBabelBundle:Needs:index.html.twig', array(
'entities' => $entities,
));
}
/**
* Finds and displays a Needs entity.
*
*/
public function showAction($id)
{
$em = $this->getDoctrine()->getManager();
$entity = $em->getRepository('ChrisBabelBundle:Needs')->find($id);
if (!$entity) {
throw $this->createNotFoundException('Unable to find Needs entity.');
}
return $this->render('ChrisBabelBundle:Needs:show.html.twig', array(
'entity' => $entity, ));
}
/**
* Displays a form to create a new Needs entity.
*
*/
public function newAction()
{
$entity = new Needs();
$form = $this->createForm(new NeedsType(), $entity);
return $this->render('ChrisBabelBundle:Needs:new.html.twig', array(
'entity' => $entity,
'form' => $form->createView(),
));
}
/**
* Creates a new Needs entity.
*
*/
public function createAction(Request $request)
{
$entity = new Needs();
$form = $this->createForm(new NeedsType(), $entity);
$form->bind($request);
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($entity);
$em->flush();
return $this->redirect($this->generateUrl('needs_show', array('id' => $entity->getId())));
}
return $this->render('ChrisBabelBundle:Needs:new.html.twig', array(
'entity' => $entity,
'form' => $form->createView(),
));
}
/**
* Displays a form to edit an existing Needs entity.
*
*/
public function editAction($id)
{
$em = $this->getDoctrine()->getManager();
$entity = $em->getRepository('ChrisBabelBundle:Needs')->find($id);
if (!$entity) {
throw $this->createNotFoundException('Unable to find Needs entity.');
}
$editForm = $this->createForm(new NeedsType(), $entity);
return $this->render('ChrisBabelBundle:Needs:edit.html.twig', array(
'entity' => $entity,
'edit_form' => $editForm->createView(),
));
}
/**
* Edits an existing Needs entity.
*
*/
public function updateAction(Request $request, $id)
{
$em = $this->getDoctrine()->getManager();
$entity = $em->getRepository('ChrisBabelBundle:Needs')->find($id);
if (!$entity) {
throw $this->createNotFoundException('Unable to find Needs entity.');
}
$editForm = $this->createForm(new NeedsType(), $entity);
$editForm->bind($request);
if ($editForm->isValid()) {
$em->persist($entity);
$em->flush();
return $this->redirect($this->generateUrl('needs_edit', array('id' => $id)));
}
return $this->render('ChrisBabelBundle:Needs:edit.html.twig', array(
'entity' => $entity,
'edit_form' => $editForm->createView(),
));
}
/**
* Deletes a Needs entity.
*
*/
public function deleteAction($id)
{
$em = $this->container->get('doctrine')->getEntityManager();
$metier = $em->find('ChrisBabelBundle:Needs', $id);
if (!$metier)
{
throw new NotFoundHttpException("Need not found");
}
$em->remove($metier); $em->flush();
return $this->redirect($this->generateUrl('needs'));
}
}
<?php
namespace Chris\BabelBundle\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Chris\BabelBundle\Entity\Trainings;
use Chris\BabelBundle\Form\TrainingsType;
/**
* Trainings controller.
*
*/
class TrainingsController extends Controller
{
/**
* Lists all Trainings entities.
*
*/
public function indexAction()
{
$em = $this->getDoctrine()->getManager();
$entities = $em->getRepository('ChrisBabelBundle:Trainings')->findAll();
return $this->render('ChrisBabelBundle:Trainings:index.html.twig', array(
'entities' => $entities,
));
}
/**
* Finds and displays a Trainings entity.
*
*/
public function showAction($id)
{
$em = $this->getDoctrine()->getManager();
$entity = $em->getRepository('ChrisBabelBundle:Trainings')->find($id);
if (!$entity) {
throw $this->createNotFoundException('Unable to find Trainings entity.');
}
$deleteForm = $this->createDeleteForm($id);
return $this->render('ChrisBabelBundle:Trainings:show.html.twig', array(
'entity' => $entity,
'delete_form' => $deleteForm->createView(), ));
}
/**
* Displays a form to create a new Trainings entity.
*
*/
public function newAction()
{
$entity = new Trainings();
$form = $this->createForm(new TrainingsType(), $entity);
return $this->render('ChrisBabelBundle:Trainings:new.html.twig', array(
'entity' => $entity,
'form' => $form->createView(),
));
}
/**
* Creates a new Trainings entity.
*
*/
public function createAction(Request $request)
{
$entity = new Trainings();
$form = $this->createForm(new TrainingsType(), $entity);
$form->bind($request);
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($entity);
$em->flush();
return $this->redirect($this->generateUrl('trainings_show', array('id' => $entity->getId())));
}
return $this->render('ChrisBabelBundle:Trainings:new.html.twig', array(
'entity' => $entity,
'form' => $form->createView(),
));
}
/**
* Displays a form to edit an existing Trainings entity.
*
*/
public function editAction($id)
{
$em = $this->getDoctrine()->getManager();
$entity = $em->getRepository('ChrisBabelBundle:Trainings')->find($id);
if (!$entity) {
throw $this->createNotFoundException('Unable to find Trainings entity.');
}
$editForm = $this->createForm(new TrainingsType(), $entity);
$deleteForm = $this->createDeleteForm($id);
return $this->render('ChrisBabelBundle:Trainings:edit.html.twig', array(
'entity' => $entity,
'edit_form' => $editForm->createView(),
'delete_form' => $deleteForm->createView(),
));
}
/**
* Edits an existing Trainings entity.
*
*/
public function updateAction(Request $request, $id)
{
$em = $this->getDoctrine()->getManager();
$entity = $em->getRepository('ChrisBabelBundle:Trainings')->find($id);
if (!$entity) {
throw $this->createNotFoundException('Unable to find Trainings entity.');
}
$deleteForm = $this->createDeleteForm($id);
$editForm = $this->createForm(new TrainingsType(), $entity);
$editForm->bind($request);
if ($editForm->isValid()) {
$em->persist($entity);
$em->flush();
return $this->redirect($this->generateUrl('trainings_edit', array('id' => $id)));
}
return $this->render('ChrisBabelBundle:Trainings:edit.html.twig', array(
'entity' => $entity,
'edit_form' => $editForm->createView(),
'delete_form' => $deleteForm->createView(),
));
}
/**
* Deletes a Trainings entity.
*
*/
public function deleteAction(Request $request, $id)
{
$form = $this->createDeleteForm($id);
$form->bind($request);
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$entity = $em->getRepository('ChrisBabelBundle:Trainings')->find($id);
if (!$entity) {
throw $this->createNotFoundException('Unable to find Trainings entity.');
}
$em->remove($entity);
$em->flush();
}
return $this->redirect($this->generateUrl('trainings'));
}
private function createDeleteForm($id)
{
return $this->createFormBuilder(array('id' => $id))
->add('id', 'hidden')
->getForm()
;
}
}
and finally the forms :
<?php
namespace Chris\BabelBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
class NeedsType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('firstname')
->add('lastname')
->add('trainingneedstart')
->add('readytowork')
->add('relatedproject')
->add('relatedactivity')
->add('relatedjob')
->add('relatedexperience')
->add('maintrainingplant')
// Ajout du formulaire imbriqué des trainings en collection
->add('trainings', 'collection', array('type' => new TrainingsType(),
'allow_add' => true,
'allow_delete' => true,
'by_reference' => false,
))
;
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Chris\BabelBundle\Entity\Needs'
));
}
public function getName()
{
return 'chris_babelbundle_needstype';
}
}
<?php
namespace Chris\BabelBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
class TrainingsType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('trainingstart')
->add('trainingend')
->add('trainingplant')
->add('training')
;
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Chris\BabelBundle\Entity\Trainings'
));
}
public function getName()
{
return 'chris_babelbundle_trainingstype';
}
}
most of this is working except that the trainings saved do not contain the needs ID in the DB so, when editing a need I cant retrieve the several trainings.
Finally I found the solution with the help of French IRC :)
I only had to modify the Needs entity like this :
/**
* Add trainings
*
* #param \Chris\BabelBundle\Entity\Trainings $trainings
* #return Needs
*/
public function addTraining(\Chris\BabelBundle\Entity\Trainings $trainings)
{
$this->trainings[] = $trainings;
$trainings->setTraining($this);
return $this;
}

UniqueEntity using Doctrine 2

I am using Zend Framework 2 and I have created a User Entity. Now I am trying to make the username field unique. However the following error is coming up.
[Semantical Error] The annotation "#UniqueEntity" in class User\Entity\User was never imported. Did you maybe forget to add a "use" statement for this annotation?
I have added this code for uniqueness check
#UniqueEntity("email")
I can see that it is a method used in Symfony. How can I use it for Zend Framework 2?
This is the Entity I am using
<?php
namespace User\Entity;
use Doctrine\ORM\Mapping as ORM,
Zend\Form\Annotation;
/**
* A user entity.
*
* #ORM\Entity
* #ORM\Table(name="users")
* #UniqueEntity("email")
* #property int $id
* #property string $username
* #property string $email
* #property string $password
*
* #Annotation\Name("User")
*/
class User {
/**
* #ORM\Id
* #ORM\Column(type="integer");
* #ORM\GeneratedValue(strategy="AUTO")
*
* #Annotation\Required(false)
*/
protected $id;
/**
* #ORM\Column(type="string")
*
* #Annotation\Attributes({"type":"text"})
* #Annotation\Options({"label":"Username:"})
* #Annotation\Filter({"name":"StringTrim"})
* #Annotation\Filter({"name":"StripTags"})
*/
protected $username;
/**
* #ORM\Column(type="string")
*
* #Annotation\Attributes({"type":"text" })
* #Annotation\Options({"label":"Email:"})
* #Annotation\Filter({"name":"StringTrim"})
* #Annotation\Filter({"name":"StripTags"})
*/
protected $email;
/**
* #ORM\Column(type="string")
*
* #Annotation\Attributes({"type":"text" })
* #Annotation\Options({"label":"Password:"})
* #Annotation\Filter({"name":"StringTrim"})
* #Annotation\Filter({"name":"StripTags"})
*/
protected $password;
public function __get($property) {
return $this->$property;
}
/**
* Magic setter to save protected properties.
*
* #param string $property
* #param mixed $value
*/
public function __set($property, $value) {
$this->$property = $value;
}
public function getArrayCopy() {
return array(
'username' => $this->username,
'email' => $this->email,
'surname' => $this->surname,
'first_name' => $this->first_name,
'company' => $this->company,
'postcode' => $this->postcode,
);
}
public function populate($data) {
$this->username = isset($data['username']) ? $data['username'] : $this->username;
}
public function setDate($property, $value){
$this->$property = new \DateTime($value);
}
}
#UniqueEntity is a particular extension of the symfony validation component (written as annotation here). What you are looking for is probably the validators you can find in DoctrineModule: https://github.com/doctrine/DoctrineModule/blob/master/docs/validator.md
Support for it as annotation is not yet built-in.