I have a Entity that have a ManyToOne with a File Entity.
My problem is when I try to delete.
This is how I create:
/**
* Creates a new Catalogo entity.
*
* #Route("/create", name="catalogo_create")
* #Method("POST")
* #Template("BWSBajaCupcakesBundle:Catalogo:new.html.twig")
*/
public function createAction(Request $request)
{
$entity = new Catalogo();
$file = new Archivo();
$form = $this->createForm(new CatalogoType(), $entity);
$form->bind($request);
$file_form = false;
if($form['file']->getData()){
$file_form = $form['file'];
//unset($form['file']);
}
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($entity);
if($file_form){
$tipoImagen = $em->getRepository('BWSBajaCupcakesBundle:TipoArchivo')->find(1);
$file->setFile($file_form->getData());
$file->setPrincipal(true);
$file->setTipo($tipoImagen);
$file->setFechaCaptura(date_create(date("Y-m-d H:i:s")));
$file->upload();
$em->persist($file);
$entity->setImagen($file);
}
$em->flush();
return $this->redirect($this->generateUrl('catalogo_show', array('id' => $entity->getId())));
}
return array(
'entity' => $entity,
'form' => $form->createView(),
);
}
This is how I delete:
/**
* Deletes a Catalogo entity.
*
* #Route("/{id}/delete", name="catalogo_delete")
* #Method("POST")
*/
public function deleteAction(Request $request, $id)
{
$form = $this->createDeleteForm($id);
$form->bind($request);
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$entity = $em->getRepository('BWSBajaCupcakesBundle:Catalogo')->find($id);
if (!$entity) {
throw $this->createNotFoundException('Unable to find Catalogo entity.');
}
$em->remove($entity);
$em->flush();
}
return $this->redirect($this->generateUrl('catalogo'));
}
This is my relationship:
/**
* #ORM\ManyToOne(targetEntity="BWS\BajaCupcakesBundle\Entity\Archivo", cascade={"all"})
* #ORM\JoinColumn(name="imagen_id", referencedColumnName="id")
*/
private $imagen;
I dont get it, I did this in my other Symfony applications and never had this issue.
Thanks in advance for your help.
Cheers
Although you have the answer in your comment, I'd tought I'd give the code in any case (based on the cookbook document entity):
/**
* Pre remove upload
*
* #ORM\PreRemove()
*/
public function preRemoveUpload()
{
$this->temp = $this->getAbsolutePath();
}
/**
* Remove upload
*
* #ORM\PostRemove()
*/
public function removeUpload()
{
if ($this->temp) {
unlink($this->temp);
}
}
Related
I am wondering if there is a way I can reduce my code without inheriting.
And what would be the best practice?
I am working with Symfony. I have old code and I need to do some forms.
Most of them are quite similar.
I have many controllers, and forms and only few differences among them.
Here is an example of a controller.
Only (NAMETOBECHANGED) changes among the controllers.
<?php
namespace Data\LiveBundle\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
use Data\LiveBundle\Entity\DataAPatient;
use Data\LiveBundle\Entity\DataDNaMETOBECHANGED;
/**
* DataDNaMETOBECHANGED controller.
*
*/
class DataDNaMETOBECHANGEDController extends Controller
{
/**
* Lists all DataDNaMETOBECHANGED entities.
*
*/
public function indexAction(Request $request, $limit, $offset)
{
$repo = $this->getDoctrine()->getManager()->getRepository('DataLiveBundle:DataDNaMETOBECHANGED');
$qb = $repo->getDefaultQuery();
return $this->renderIndex($repo, $qb, $limit, $offset, 'default');
}
/**
* Lists all DataDNaMETOBECHANGED entities sorted by a chosen column.
*
*/
public function indexSortAction(Request $request, $limit, $offset, $column){
$repo = $this->getDoctrine()->getManager()->getRepository('DataLiveBundle:DataDNaMETOBECHANGED');
$qb = $repo->getDefaultQueryOrdered($column);
return $this->renderIndex($repo, $qb, $limit, $offset, $column);
}
/**
* Renders the index page
*
*/
private function renderIndex($repo, $qb, $limit, $offset, $column)
{
//TODO: Add Access-Control
if (!$this->isAdmin()) {
throw new AccessDeniedException();
}
//model taken from Events
//$queryHelper = $this->get('general_commonbundle.util.queryhelper');
//$qb = $queryHelper->addProjectFilter($qb);
//if(!$this->isAdmin()){
//$qb = $queryHelper->addAccessControl($qb);
//}
$total = $repo->countQueryResults($qb);
$qb = $repo->addLimitToQuery($qb, $limit, $offset);
$paginationOptions = array(
'total' => $total,
'limit' => $limit,
'offset' => $offset
);
$entities = $repo->getResults($qb);
//TODO: lock dataset if 180 days passed.
$editable = array();
foreach($entities as $entity){
$this->isAdmin(); // TODO: owner check: $editable[$entity->getPKpPatientid()] = $this->isOwner($entity->getPKpPatientid())
}
// Disable softdelete filter, such that view can access all foreign keys.
// View needs to distinguish between still existent foreign keys and deleted ones.
$em = $this->getDoctrine()->getManager();
if (array_key_exists('softdeleteable', $em->getFilters()->getEnabledFilters())) {
$em->getFilters()->disable('softdeleteable');
}
return $this->render('DataLiveBundle:DataDNaMETOBECHANGED:index.html.twig', array(
'entities' => $entities,
'editable' => $editable,
'paginationOptions' => $paginationOptions,
'orderColumn' => $column,
'parentRoute' => $this->generateUrl('datadnaMeTOBECHANGED')
));
}
/**
* Finds and displays an DataDNaMETOBECHANGED entity.
*
*/
public function showAction($pKpPatientid)
{
if (!$this->isAdmin()) {
throw new AccessDeniedException();
}
$em = $this->getDoctrine()->getManager();
$entity = $em->getRepository('DataLiveBundle:DataDNaMETOBECHANGED')->find($pKpPatientid);
if (!$entity) {
throw $this->createNotFoundException('Unable to find DataDNaMETOBECHANGED entity.');
}
// Access control
if($this->isAdmin() // || $this->isOwner($pKpPatientid)
) {
// allow access
}
else {
throw new AccessDeniedException();
}
// Disable softdelete filter, such that view can access all foreign keys.
// View needs to distinguish between still existent foreign keys and deleted ones.
if (array_key_exists('softdeleteable', $em->getFilters()->getEnabledFilters())) {
$em->getFilters()->disable('softdeleteable');
}
$editable = $this->isAdmin(); //$this->isOwner($entity->getPKpPatientid())
$print = $this->getRequest()->get('print') == '1';
return $this->render('DataLiveBundle:DataDNaMETOBECHANGED:show.html.twig', array(
'entity' => $entity,
'editable' => $editable,
'isPreview' => false,
'print' => $print,
));
}
/**
* Redirects to preview a new DataAPatient entity.
*
*/
public function newAction(Request $request)
{
if (!$this->isAdmin()) {
throw new AccessDeniedException();
}
$entity = new DataAPatient();
$em = $this->getDoctrine()->getManager();
$entity->setPDateOfBirth(new \DateTime('now'));
// $entity->setTimeStart(new \DateTime('now'));
// $entity->setTimeEnd(new \DateTime('now'));
$newForm = $this->createNewForm($entity);
$entity->setDatetimeCreated( new \DateTime('now') );
$entity->setDatetimeChanged (new \DateTime ('now'));
//TODO: set SNNID
$newForm->handleRequest($request);
if ($newForm->isValid()) {
if($newForm->get('submit')->isClicked()){//Save
$pKpPatientid = $this->storeNewDataAPatient($entity);
return $this->redirect($this->generateUrl('dataapatient_sendMessage', array("pKpPatientid" => $pKpPatientid)));
}
}
return $this->render('DataLiveBundle:DataDNaMETOBECHANGED:form.html.twig', array(
'entity' => $entity,
'form' => $newForm->createView(),
'isNew'=> true,
));
}
/**
* Creates a form to create a new DataAPatient entity.
*
* #param DataAPatient $entity The entity
*
* #return \Symfony\Component\Form\Form
*
*/
private function createNewForm(DataAPatient $entity)
{
$form = $this->createForm($this->get('data_livebundle.form.dataapatienttype'), $entity, array(
'action' => $this->generateUrl('dataapatient_new'),
'method' => 'POST',
));
$form->add('submit', 'submit', array('label' => 'Create'));
return $form;
}
/**
* Redirects to preview changes made to an existing DataDNaMETOBECHANGED entity.
*
*/
public function editAction(Request $request, $pKpPatientid)
{
$em = $this->getDoctrine()->getManager();
$entity = $em->getRepository('DataLiveBundle:DataDNaMETOBECHANGED')->find($pKpPatientid);
if (!$entity) {
throw $this->createNotFoundException('Unable to find DataDNaMETOBECHANGED entity.');
}
//Access control
if (!$this->isAdmin() //&& !$this->isOwner($pKpPatientid)
) {
throw new AccessDeniedException();
}
$editForm = $this->createEditForm($entity);
$editForm->handleRequest($request);
if ($editForm->isValid()) {
//Refresh Changed-Date
$entity->setDatetimeChanged( new \DateTime('now') );
//Set naMeTOBECHANGEDAgeRef in DataDNaMETOBECHANGED
$entity->getDNaMETOBECHANGED()->setNaMETOBECHANGEDAgeRef (round($entity->getDNaMETOBECHANGED()->getNaMETOBECHANGEDAgeCalc(),0));
if($editForm->get('submit')->isClicked()){//Save
$em->persist($entity);
//Store changes
$pKpPatientid = $this->storeEditedDataDNaMETOBECHANGED($entity);
//TODO: log changes in history
if($editForm->get('submit')->isClicked()){
return $this->redirect($this->generateUrl('datadnaMeTOBECHANGED_show', array('pKpPatientid' => $pKpPatientid)));
}
}
}
return $this->render('DataLiveBundle:DataDNaMETOBECHANGED:form.html.twig', array(
'entity' => $entity,
'form' => $editForm->createView(),
'isNew' => false,
));
}
/**
* Creates a form to edit a DataDNaMETOBECHANGED entity.
*
* #param DataDNaMETOBECHANGED $entity The entity
*
* #return \Symfony\Component\Form\Form The form
*/
private function createEditForm(DataDNaMETOBECHANGED $entity)
{
$form = $this->createForm($this->get('data_livebundle.form.datadnaMeTOBECHANGEDtype'), $entity, array(
'action' => $this->generateUrl('datadnaMeTOBECHANGED_edit', array('pKpPatientid' => $entity->getPKpPatientid())),
'method' => 'POST'
));
$form->add('submit', 'submit', array('label' => 'Save Changes'));
return $form;
}
/**
* Persists changes made to an existing DataDNaMETOBECHANGED entity to the database
*
*/
private function storeEditedDataDNaMETOBECHANGED($entity)
{
$em = $this->getDoctrine()->getManager();
$session = $this->getRequest()->getSession();
if (!$entity) {
throw $this->createNotFoundException('Unable to find DataDNaMETOBECHANGED entity.');
}
$pSnnid = $entity->getPSnnid();
$em->persist($entity);
$em->flush();
$session->getFlashBag()->add(
'notice',
'Your changes to the DataDNaMETOBECHANGED of ID: "'.$pSnnid. '" was saved!'
);
return $entity->getPKpPatientid();
}
/**
* Persists a new DataDNaMETOBECHANGED entity to the database
*
*/
private function storeNewDataDNaMETOBECHANGED($entity)
{
$em = $this->getDoctrine()->getManager();
$session = $this->getRequest()->getSession();
if (!$entity) {
throw $this->createNotFoundException('Unable to find DataDNaMETOBECHANGED entity.');
}
$pSnnid = $entity->getPSnnid();
$em->persist($entity);
$em->flush();
$session->getFlashBag()->add(
'notice', 'The new DataDNaMETOBECHANGED for "'.$pSnnid. '" was saved!'
);
return $entity->getPKpPatientid();
}
/**
* Removes hospital entity from the database by pKpPatientid
*
*/
public function deleteAction(Request $request, $pKpPatientid)
{
$em = $this->getDoctrine()->getManager();
$entity = $em->getRepository('DataLiveBundle:DataDNaMETOBECHANGED')->find($pKpPatientid);
if (!$entity) {
throw $this->createNotFoundException('Unable to find DataDNaMETOBECHANGED entity.');
}
//Access control
if (!$this->isAdmin()) {
throw new AccessDeniedException();
}
$pSnnid = $entity -> getPSnnid();
$em->remove($entity);
$em->flush();
$this->getRequest()->getSession()->getFlashBag()->add(
'notice',
'The DataDNaMETOBECHANGED for "'.$pSnnid.'" was deleted successfully!'
);
return $this->redirect($this->generateUrl('datadnaMeTOBECHANGED'));
}
/**
* Returns whether current user has role ROLE_ADMIN
*
* #return boolean
*/
private function isAdmin()
{
return $this->get('security.context')->isGranted('ROLE_ADMIN');
}
/**
* Returns whether current user has ID '$pKpPatientid'
*
* #param mixed $pKpPatientid The entity id which current user wants to edit
*
* #return boolean
*/
private function isOwner($pKpPatientid)
{
$em = $this->getDoctrine()->getManager();
// Disable softdeletable filter (only if it's not already inactive)
if (array_key_exists('softdeleteable', $em->getFilters()->getEnabledFilters())) {
$em->getFilters()->disable('softdeleteable');
}
$entity = $em->getRepository('DataLiveBundle:DataDNaMETOBECHANGED')->find($pKpPatientid);
$result = $entity->getFKOwner()->getPKpPatientid() == $this->get('security.context')->getToken()->getUser()->getPKpPatientid();
// Enable softdeletable filter before returning
$em->getFilters()->enable('softdeleteable');
return $result;
}
}
And for HTML, here is an example:
<div class='col-xs-4'>
<div class='col-xs-7'>{{ form_label(form.dFu2.fu2MdiRaw, 'Cognitive RAW score:', {'label_attr':{'style':'margin-top:3px'}})}}</div>
<div class='col-xs-2'>{{ form_widget(form.dFu2.fu2MdiRaw, {'attr':{'style':'width:50px'}})}}</div>
</div>
This kind of piece of code repeats itself a lot among the forms. And in each for most of the time only fu1, fu2, fu3, ... change.
Thank your for your advice!
I have made a CRUD for my question object. An error occurred once I tested it.
It seems that the getId() is returning an empty string of some sort.
The default behavior of the autogenerated CRUD is to redirect the user to the view page after successfully creating the entity. But in this case, it returns an error
"Parameter "id" for route "question_show" must match "[^/]++" ("" given) to generate a corresponding URL."
Here is my controller code:
/**
* Creates a new Question entity.
*
* #Route("/ask", name="question_create")
* #Method("POST")
* #Template("VerySoftAskMeBundle:Question:ask.html.twig")
*/
public function createAction(Request $request) {
$entity = new Question();
$form = $this->createCreateForm($entity);
$form->handleRequest($request);
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($entity);
$em->flush();
return $this->redirect($this->generateUrl('question_show', array('id' => $entity->getId())));
}
return array(
'entity' => $entity,
'form' => $form->createView(),
);
}
Here is the view action:
/**
* Finds and displays a Question entity.
*
* #Route("/{id}", name="question_show")
* #Method("GET")
* #Template()
*/
public function showAction($id) {
$em = $this->getDoctrine()->getManager();
$entity = $em->getRepository('VerySoftAskMeBundle:Question')->find($id);
if (!$entity) {
throw $this->createNotFoundException('Unable to find Question entity.');
}
$deleteForm = $this->createDeleteForm($id);
return array(
'entity' => $entity,
'delete_form' => $deleteForm->createView(),
);
}
/**
* Creates a form to create a Question entity.
*
* #param Question $entity The entity
*
* #return Form The form
*/
private function createCreateForm(Question $entity) {
$form = $this->createForm(new QuestionType(), $entity, array(
'action' => $this->generateUrl('question_create'),
'method' => 'POST',
'em' => $this->getDoctrine()->getEntityManager()
));
$form->add('submit', 'submit', array('label' => 'Ask'));
return $form;
}
How can I fix this?
It seems that your entity is not persisted in the database. Could you check it?
Also, it seems to be a typo in your code your wrote "$form = $this->createCreateForm($entity);", instead of $this->createForm
Otherwise I have used the code below (similar to yours) with no problem
/**
* #Route("/new", name="item_new")
* #Template()
*
* #return array
*/
public function newAction(Request $request)
{
$em = $this->get('doctrine.orm.entity_manager');
$item = new Item();
$form = $this->createForm(new ItemType(), $item, array(
'action' => $this->generateUrl('item_new'),
'method' => 'POST',
));
$form->handleRequest($request);
if ($form->isValid()) {
$em->persist($item);
$em->flush();
return $this->redirect($this->generateUrl('item_list'));
}
return array('form' => $form->createView());
}
Fixed it. I was inheriting a class named Post which has an $id variable. Turns out that I forgot to delete the $id variable in my Question class which is why Symfony gets confused on what id to return.
I'm working on some simple script, but can't wrap my head around this problem.
So here it is.
/**
* Booking
* #ORM\Table()
* #ORM\Entity(repositoryClass="Tons\BookingBundle\Entity\BookingRepository")
* #UniqueEntity(fields={"room", "since", "till"}, repositoryMethod="getInterferingRoomBookings")
* #Assert\Callback(methods={"isSinceLessThanTill"}, groups={"search","default"})
*/
class Booking
and repository Method
/**
* Get room state for a certain time period
*
* #param array $criteria
* #return array
*/
public function getInterferingRoomBookings(array $criteria)
{
/** #var $room Room */
$room = $criteria['room'];
$builder = $this->getQueryForRoomsBooked($criteria);
$builder->andWhere("ira.room = :room")->setParameter("room", $room);
return $builder->getQuery()->getArrayResult();
}
The problem is that this works on create methods like it should,
but when updating existing entity - it violates this constrain.
I tried to add Id constrain, but when creating entities, id is null, so repository Method don't even starts.
Also i tried to remove Entity and then recreate it. like
$em->remove($entity);
$em->flush();
//-----------
$em->persist($entity);
$em->flush();
but this also does not work.
Create Action
/**
* Creates a new Booking entity.
*
* #Route("/create", name="booking_create")
* #Method("POST")
* #Template("TonsBookingBundle:Booking:new.html.twig")
*/
public function createAction(Request $request)
{
$entity = new Booking();
$form = $this->createForm(new BookingType(), $entity);
$form->bind($request);
if ($form->isValid())
{
$em = $this->getDoctrine()->getManager();
$room = $entity->getRoom();
if($room->getLocked() && $room->getLockedBy()->getId() === $this->getUser()->getId())
{
$entity->setCreatedAt(new \DateTime());
$entity->setUpdatedAt(new \DateTime());
$entity->setManager($this->getUser());
$em->persist($entity);
$room->setLocked(false);
$room->setLockedBy(null);
$room->setLockedAt(null);
$em->persist($room);
$em->flush();
return $this->redirect($this->generateUrl('booking_show', array('id' => $entity->getId())));
}
else
{
$form->addError(new FormError("Номер в текущий момент не заблокирован или заблокирован другим менеджером"));
return array(
'entity' => $entity,
'form' => $form->createView(),
);
}
}
return array(
'entity' => $entity,
'form' => $form->createView(),
);
}
Update Action
/**
* Edits an existing Booking entity.
*
* #Route("/edit/{id}/save", name="booking_update")
* #Method("PUT")
* #Template("TonsBookingBundle:Booking:edit.html.twig")
*/
public function updateAction(Request $request, $id)
{
/** #var $em EntityManager */
$em = $this->getDoctrine()->getManager();
$entity = $em->getRepository('TonsBookingBundle:Booking')->find($id);
if (!$entity) {
throw $this->createNotFoundException('Unable to find Booking entity.');
}
$editForm = $this->createForm(new BookingType(), $entity);
$editForm->bind($request);
if ($editForm->isValid()) {
$em->persist($entity);
$em->flush();
return $this->redirect($this->generateUrl('booking_edit', array('id' => $id)));
}
return array(
'entity' => $entity,
'form' => $editForm->createView(),
);
}
I got this!
I changed annotation to this
/**
* Booking
* #ORM\Table()
* #ORM\Entity(repositoryClass="Tons\BookingBundle\Entity\BookingRepository")
* #UniqueEntity(fields={"id","room", "since", "till"}, repositoryMethod="getInterferingRoomBookings")
* #UniqueEntity(fields={"room", "since", "till"}, repositoryMethod="getInterferingRoomBookings",groups={"create"})
* #Assert\Callback(methods={"isSinceLessThanTill"}, groups={"search","default"})
*/
class Booking
Copy BookingType to BookingTypeCreate And added
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Tons\BookingBundle\Entity\Booking',
'validation_groups' => array('create'),
));
}
To form defaults. So now parameters are different when passing entity to validation method.
I think it's still a workaround method.
Short answer: You're not getting the form data into the entity, so you are working with a new entity that does not know its room has been set in the form.
Long answer: Getting the form data and putting it into the entity allows you to manipulate the data before update. See modified controller below. Key line is
$entity = form->getData(); Which then allows you to $room=$entity->getRoom();
/**
* Creates a new Booking entity.
*
* #Route("/create", name="booking_create")
* #Method("POST")
* #Template("TonsBookingBundle:Booking:new.html.twig")
*/
public function createAction(Request $request)
{
$entity = new Booking();
$form = $this->createForm(new BookingType(), $entity);
$form->bind($request);
$entity = $form->getData(); // Lighthart's addition
if ($form->isValid())
{
$em = $this->getDoctrine()->getManager();
$room = $entity->getRoom();
if($room->getLocked() && $room->getLockedBy()->getId() === $this->getUser()->getId())
{
$entity->setCreatedAt(new \DateTime());
$entity->setUpdatedAt(new \DateTime());
$entity->setManager($this->getUser());
$em->persist($entity);
$room->setLocked(false);
$room->setLockedBy(null);
$room->setLockedAt(null);
$em->persist($room);
$em->flush();
return $this->redirect($this->generateUrl('booking_show', array('id' => $entity->getId())));
}
else
{
$form->addError(new FormError("Номер в текущий момент не заблокирован или заблокирован другим менеджером"));
return array(
'entity' => $entity,
'form' => $form->createView(),
);
}
}
return array(
'entity' => $entity,
'form' => $form->createView(),
);
}
Pass an additional identifier (maybe a token) to the unique check field (for example loginName) (fields={"token", "loginName"}), to the repositoryMethod. The id itself is not working, it is null on object creation and the repositoryMethod is not executed. I create the token in the constructor Method. The token is needed to identify the entity on creation or update action.
/**
* #ORM\Table(name="anbieterregistrierung")
* #ORM\Entity(repositoryClass="AnbieterRegistrierungRepository")
* #UniqueEntity(
* fields={"token", "loginName"},
* repositoryMethod="findUniqueEntity"
* )
*/
then in repository class you edit the WHERE DQL:
public function findUniqueEntity(array $parameter)
{
$loginName = $parameter['loginName'];
$token = $parameter['token'];
.
.
.
. . . WHERE anbieterregistrierung.loginName = :loginName AND anbieterregistrierung.token <> :token
.
.
.
}
In a REST API that I'm developing a Company has a parent attribute which is also of the Company Class.
That way I can create a three of Companies. A Company has one parent Company (Company Class) and can have multiple children Companies (Collection)
/**
* #ORM\ManyToOne(targetEntity="Company", inversedBy="child")
* #Expose()
*/
protected $parent;
/**
* #ORM\OneToMany(targetEntity="Company", mappedBy="parent")
*/
protected $child;
public function __construct()
{
...
$this->child = new \Doctrine\Common\Collections\ArrayCollection();
}
How would I go about and make/remove that relationship of parents and children companies?
I've read about the LINK verb but I'm afraid it's not supported by all webservers.
Should I set the relationship with PUT?
How would I then remove the relationship to the parent (set it to NULL).
My CompanyController looks like this:
/**
* Edit Action
*
* #Rest\View()
*/
public function editAction(Company $company)
{
return $this->processForm($company);
}
/**
* Remove Action
*
* #Rest\View(statusCode=204)
*/
public function removeAction(Company $company)
{
$em = $this->getDoctrine()->getManager();
$em->remove($company);
$em->flush();
}
/**
* ProcessForm Action
*/
private function processForm(Company $company)
{
$statusCode = $this->getRequest()->getMethod() == 'POST' ? Codes::HTTP_CREATED : Codes::HTTP_SEE_OTHER;
$form = $this->createForm(new CompanyType(), $company);
$form->bind($this->getRequest());
if($form->isValid())
{
$em = $this->getDoctrine()->getManager();
$em->persist($company);
$em->flush();
return $this->redirectView(
$this->generateUrl(
'company_get',
array('id' => $company->getId())
),
$statusCode
);
}
return View::create($form, 400);
}
Any suggestions?
I have a M2M relationship, but when I create an item the relationship is not saved and I can't find where's the problem.
The Model:
class Serie
{
/**
* #ORM\ManyToMany(targetEntity="Magazine", mappedBy="series")
* */
protected $magazines;
/**
* Constructor
*/
public function __construct()
{
$this->magazines = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Add magazines
*
* #param MyList\DBBundle\Entity\Magazine $magazines
* #return Serie
*/
public function addMagazine(\MyList\DBBundle\Entity\Magazine $magazines)
{
$this->magazines[] = $magazines;
return $this;
}
/**
* Remove magazines
*
* #param MyList\DBBundle\Entity\Magazine $magazines
*/
public function removeMagazine(\MyList\DBBundle\Entity\Magazine $magazines)
{
$this->magazines->removeElement($magazines);
}
/**
* Get magazines
*
* #return Doctrine\Common\Collections\Collection
*/
public function getMagazines()
{
return $this->magazines;
}
}
The Magazine class:
class Magazine
{
/**
* #ORM\ManyToMany(targetEntity="Serie" , inversedBy="magazines")
* #ORM\JoinTable(name="magazines_series")
* */
protected $series;
public function __construct()
{
$this->series = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Add series
*
* #param MyList\DBBundle\Entity\Serie $series
* #return Magazine
*/
public function addSerie(\MyList\DBBundle\Entity\Serie $serie)
{
$serie->addMagazine($this);
$this->series[] = $serie;
return $this;
}
/**
* Remove series
*
* #param MyList\DBBundle\Entity\Serie $series
*/
public function removeSerie(\MyList\DBBundle\Entity\Serie $series)
{
$this->series->removeElement($series);
}
/**
* Get series
*
* #return Doctrine\Common\Collections\Collection
*/
public function getSeries()
{
return $this->series;
}
}
The Controller
class SerieController extends Controller
{
public function newAction()
{
$entity = new Serie();
$form = $this->createForm(new SerieType(), $entity);
return array(
'entity' => $entity,
'form' => $form->createView(),
);
}
/**
* Creates a new Serie entity.
*
* #Route("/create", name="serie_create")
* #Method("POST")
* #Template("DBBundle:Serie:new.html.twig")
*/
public function createAction(Request $request)
{
$entity = new Serie();
$form = $this->createForm(new SerieType(), $entity);
$form->bind($request);
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($entity);
$em->flush();
return $this->redirect($this->generateUrl('serie_show', array('id' => $entity->getId())));
}
return array(
'entity' => $entity,
'form' => $form->createView(),
);
}
}
And the Form:
class SerieType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('title')
->add('start')
->add('end')
->add('type')
->add('status')
->add('magazines','entity',array(
'class' => 'DBBundle:Magazine',
'multiple' => true,
'property' => 'name'
))
;
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'MyList\DBBundle\Entity\Serie'
));
}
public function getName()
{
return 'mylist_dbbundle_serietype';
}
}
I know there are some questions about this (i.e. Symfony2-Doctrine: ManyToMany relation is not saved to database), but none of them have solved my problem.
This is because you never persist() the magazine, the form added it already to the entity but Doctrine still needs to manage it.
add this in the if ($form->isValid()):
...
$magazines = $entity->getMagazines();
foreach($magazines as $magazine){
$em->persist($magazine);
}
...
$em->flush();