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!
Related
I have a field collection type, but when i save it, its don't save the relationship oneToMany.
My code is:
Config.yml:
Splitter:
class: AppBundle\Entity\Splitter
controller: AppBundle\Controller\EasyAdmin\SplitterController
list:
fields:
- caixa.elemento.nome
- paridadeVias
form:
fields:
- caixa
- paridadeVias
- balanceamentoCaixa
- dataHoraInstalacao
- { property: 'splitterSaida', type: 'collection', type_options: { entry_type: 'AppBundle\Form\SplitterSaidaForm', by_reference: false } }
Look i have a specific controller and my property is a collection type
SplitterController:
protected function newAction()
{
$this->dispatch(EasyAdminEvents::PRE_NEW);
$entity = $this->executeDynamicMethod('createNew<EntityName>Entity');
$easyadmin = $this->request->attributes->get('easyadmin');
$easyadmin['item'] = $entity;
$this->request->attributes->set('easyadmin', $easyadmin);
$fields = $this->entity['new']['fields'];
$newForm = $this->createForm(SplitterForm::class, $entity);
$newForm->handleRequest($this->request);
if ($newForm->isSubmitted() && $newForm->isValid()) {
$this->dispatch(EasyAdminEvents::PRE_PERSIST, array('entity' => $entity));
$this->executeDynamicMethod('prePersist<EntityName>Entity', array($entity));
$this->executeDynamicMethod('persist<EntityName>Entity', array($entity));
$this->dispatch(EasyAdminEvents::POST_PERSIST, array('entity' => $entity));
return $this->redirectToReferrer();
}
$this->dispatch(EasyAdminEvents::POST_NEW, array(
'entity_fields' => $fields,
'form' => $newForm,
'entity' => $entity,
));
return $this->render('easy_admin/Splitter/new.html.twig', array(
'form' => $newForm->createView(),
'entity_fields' => $fields,
'entity' => $entity,
));
}
protected function editAction()
{
$this->dispatch(EasyAdminEvents::PRE_EDIT);
$id = $this->request->query->get('id');
$easyadmin = $this->request->attributes->get('easyadmin');
$entity = $easyadmin['item'];
if ($this->request->isXmlHttpRequest() && $property = $this->request->query->get('property')) {
$newValue = 'true' === mb_strtolower($this->request->query->get('newValue'));
$fieldsMetadata = $this->entity['list']['fields'];
if (!isset($fieldsMetadata[$property]) || 'toggle' !== $fieldsMetadata[$property]['dataType']) {
throw new \RuntimeException(sprintf('The type of the "%s" property is not "toggle".', $property));
}
$this->updateEntityProperty($entity, $property, $newValue);
// cast to integer instead of string to avoid sending empty responses for 'false'
return new Response((int)$newValue);
}
$fields = $this->entity['edit']['fields'];
$editForm = $this->createForm(SplitterForm::class, $entity);
$deleteForm = $this->createDeleteForm($this->entity['name'], $id);
$editForm->handleRequest($this->request);
if ($editForm->isSubmitted() && $editForm->isValid()) {
$this->dispatch(EasyAdminEvents::PRE_UPDATE, array('entity' => $entity));
$this->executeDynamicMethod('preUpdate<EntityName>Entity', array($entity));
$this->executeDynamicMethod('update<EntityName>Entity', array($entity));
$this->dispatch(EasyAdminEvents::POST_UPDATE, array('entity' => $entity));
return $this->redirectToReferrer();
}
$this->dispatch(EasyAdminEvents::POST_EDIT);
return $this->render('easy_admin/Splitter/new.html.twig', array(
'form' => $editForm->createView(),
'entity_fields' => $fields,
'entity' => $entity,
'delete_form' => $deleteForm->createView(),
));
}
SplitterEntity:
/**
* #ORM\OneToMany(
* targetEntity="SplitterSaida",
* mappedBy="splitter",
* fetch="EAGER",
* orphanRemoval=true,
* cascade={"persist"}
* )
* #Assert\Valid()
*/
private $splitterSaida;
public function addSplitterSaida(SplitterSaida $splitterSaida)
{
$this->splitterSaida->add($splitterSaida);
$splitterSaida->setSplitter($this);
return $this;
}
public function removeSplitterSaida(SplitterSaida $splitterSaida)
{
if (!$this->splitterSaida->contains($splitterSaida)) {
return;
}
$this->splitterSaida->removeElement($splitterSaida);
$splitterSaida->setSplitter(null);
}
/**
* #return ArrayCollection|SplitterSaida[]
*/
public function getSplitterSaida()
{
return $this->splitterSaida;
}
/**
* #param mixed $splitterSaida
*/
public function setSplitterSaida($splitterSaida)
{
$this->splitterSaida = $splitterSaida;
}
The method addSplitterSaida is never called
SplitterSaidaEntity:
/**
* #ORM\ManyToOne(targetEntity="Splitter", inversedBy="splitterSaida")
*/
private $splitter;
to sum up…
Why my relationship is not saved?
Why method addSplitterSaida was never called?
Please help-me! thanks!
After long time of lerking on these boards I have finally decided to make my first post. I have recently started to play around with Symfony (2.4, don't yell at me please :) ). Using doctrine's terminal commands I generated CRUD events. Now, that is great and all, except that you have to pass the ID in the url, for example: www.mydomain.com/account/16/. This will pre-fill the form with the data from a row that has id 16 in mysql. My question is, how do I manipulate the pre-made CRUD (only interested in the update) so that I don't have to pass the id to the url, but rather, it renders the form based on the id the logged in user has associated with their account?
Here is my code:
class AccountController extends Controller
{
/**
* Displays a form to edit an existing Event entity.
* #Route("/account/{id}", name="post_login_account_edit")
* #PreAuthorize("isFullyAuthenticated()")
*/
public function editAction($id)
{
$em = $this->getDoctrine()->getManager();
$entity = $em->getRepository('UserBundle:User')->find($id);
if (!$entity) {
throw $this->createNotFoundException('Unable to find Event entity.');
}
$editForm = $this->createEditForm($entity);
return $this->render('UserBundle:Account:account.html.twig', array(
'entity' => $entity,
'edit_form' => $editForm->createView()
));
}
/**
* Creates a form to edit a Event entity.
*
* #param User $entity The entity
*
* #return \Symfony\Component\Form\Form The form
*/
private function createEditForm(User $entity)
{
$form = $this->createForm(new UserType(), $entity, array(
'action' => $this->generateUrl('post_login_account_update', array('id' => $entity->getId())),
'method' => 'PUT',
));
$form->add('submit', 'submit', array('label' => 'Update'));
return $form;
}
/**
* Edits an existing User entity.
* #Route("/account/{id}/update", name="post_login_account_update")
* #PreAuthorize("isFullyAuthenticated()")
*/
public function updateAction(Request $request, $id)
{
$em = $this->getDoctrine()->getManager();
$entity = $em->getRepository('UserBundle:User')->find($id);
if (!$entity) {
throw $this->createNotFoundException('Unable to find Event entity.');
}
$editForm = $this->createEditForm($entity);
$editForm->handleRequest($request);
if ($editForm->isValid()) {
$em->flush();
return $this->redirect($this->generateUrl('post_login_account'));
}
return $this->render('UserBundle:Account:account.html.twig', array(
'entity' => $entity,
'edit_form' => $editForm->createView()
));
}
}
Simply get logged in user in controller:
$entity = $this->get('security.context')->getToken()->getUser();
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
.
.
.
}
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);
}
}