Automatically set related entity id in one to many relationship Symfony - symfony

I have a many to one related entities and everytime I create a new comment which is related to Project, I want to automatically save the realted project_id.
comment
id
comment
manyToOne
project:
targetEntity: Project
cascade: { }
mappedBy: null
inversedBy: comments
joinColumn:
name: project_id
referencedColumnName: id
orphanRemoval: false
project
id
projectName
oneToMany:
comments:
targetEntity: Comment
mappedBy: project
When using Annotation, this can be done easily using the ParamConverter, but in this case I am using Yaml format.I am using the Symfony nice Crud command to automatically generate forms and templates as well as the controllers.
I tried in controller this way
public function createAction(Request $request, Project $project)//Project
{
$entity = new Comment();
$form = $this->createCreateForm($entity);
$form->handleRequest($request);
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
// $entity->setProject($projectName->getProject());
$entity->setProject($project);
$em->persist($entity);
$em->flush();
return $this->redirect($this->generateUrl('comment_show', array('id' => $entity->getId())));
}
Then in form,
{{ form(form) }}
The problem with this is it will generate a form with a dropdown with hundreds of project_id in comment project_id field
Then when submitted
Unable to guess how to get a Doctrine instance from the request information.
I am thinking of writing a jquery autocomplete to solve this but if there is more shortcut way of doing this, like the annotation Paramconverter, I am glad to use it
How would you do it so that the related project_id will be automatically saved?
Update
This is exactly the code when running Symfony2 nice crud command in console
<?php
namespace EdgeWeb\Project\EmployeeBundle\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use EdgeWeb\Project\EmployeeBundle\Entity\Comment;
use EdgeWeb\Project\EmployeeBundle\Form\CommentType;
/**
* Comment controller.
*
*/
class CommentController extends Controller
{
/**
* Lists all Comment entities.
*
*/
public function indexAction()
{
$em = $this->getDoctrine()->getManager();
$entities = $em->getRepository('EmployeeBundle:Comment')->findAll();
return $this->render('EmployeeBundle:Comment:index.html.twig', array(
'entities' => $entities,
));
}
/**
* Creates a new Comment entity.
*
*/
public function createAction(Request $request)
{
$entity = new Comment();
$form = $this->createCreateForm($entity);
$form->handleRequest($request);
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($entity);
$em->flush();
return $this->redirect($this->generateUrl('comment_show', array('id' => $entity->getId())));
}
return $this->render('EmployeeBundle:Comment:new.html.twig', array(
'entity' => $entity,
'form' => $form->createView(),
));
}
/**
* Creates a form to create a Comment entity.
*
* #param Comment $entity The entity
*
* #return \Symfony\Component\Form\Form The form
*/
private function createCreateForm(Comment $entity)
{
$form = $this->createForm(new CommentType(), $entity, array(
'action' => $this->generateUrl('comment_create'),
'method' => 'POST',
));
$form->add('submit', 'submit', array('label' => 'Create'));
return $form;
}
/**
* Displays a form to create a new Comment entity.
*
*/
public function newAction()
{
$entity = new Comment();
$form = $this->createCreateForm($entity);
return $this->render('EmployeeBundle:Comment:new.html.twig', array(
'entity' => $entity,
'form' => $form->createView(),
));
}
/**
* Finds and displays a Comment entity.
*
*/
public function showAction($id)
{
$em = $this->getDoctrine()->getManager();
$entity = $em->getRepository('EmployeeBundle:Comment')->find($id);
if (!$entity) {
throw $this->createNotFoundException('Unable to find Comment entity.');
}
$deleteForm = $this->createDeleteForm($id);
return $this->render('EmployeeBundle:Comment:show.html.twig', array(
'entity' => $entity,
'delete_form' => $deleteForm->createView(),
));
}
/**
* Displays a form to edit an existing Comment entity.
*
*/
public function editAction($id)
{
$em = $this->getDoctrine()->getManager();
$entity = $em->getRepository('EmployeeBundle:Comment')->find($id);
if (!$entity) {
throw $this->createNotFoundException('Unable to find Comment entity.');
}
$editForm = $this->createEditForm($entity);
$deleteForm = $this->createDeleteForm($id);
return $this->render('EmployeeBundle:Comment:edit.html.twig', array(
'entity' => $entity,
'edit_form' => $editForm->createView(),
'delete_form' => $deleteForm->createView(),
));
}
/**
* Creates a form to edit a Comment entity.
*
* #param Comment $entity The entity
*
* #return \Symfony\Component\Form\Form The form
*/
private function createEditForm(Comment $entity)
{
$form = $this->createForm(new CommentType(), $entity, array(
'action' => $this->generateUrl('comment_update', array('id' => $entity->getId())),
'method' => 'PUT',
));
$form->add('submit', 'submit', array('label' => 'Update'));
return $form;
}
/**
* Edits an existing Comment entity.
*
*/
public function updateAction(Request $request, $id)
{
$em = $this->getDoctrine()->getManager();
$entity = $em->getRepository('EmployeeBundle:Comment')->find($id);
if (!$entity) {
throw $this->createNotFoundException('Unable to find Comment entity.');
}
$deleteForm = $this->createDeleteForm($id);
$editForm = $this->createEditForm($entity);
$editForm->handleRequest($request);
if ($editForm->isValid()) {
$em->flush();
return $this->redirect($this->generateUrl('comment_edit', array('id' => $id)));
}
return $this->render('EmployeeBundle:Comment:edit.html.twig', array(
'entity' => $entity,
'edit_form' => $editForm->createView(),
'delete_form' => $deleteForm->createView(),
));
}
/**
* Deletes a Comment entity.
*
*/
public function deleteAction(Request $request, $id)
{
$form = $this->createDeleteForm($id);
$form->handleRequest($request);
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$entity = $em->getRepository('EmployeeBundle:Comment')->find($id);
if (!$entity) {
throw $this->createNotFoundException('Unable to find Comment entity.');
}
$em->remove($entity);
$em->flush();
}
return $this->redirect($this->generateUrl('comment'));
}
/**
* Creates a form to delete a Comment entity by id.
*
* #param mixed $id The entity id
*
* #return \Symfony\Component\Form\Form The form
*/
private function createDeleteForm($id)
{
return $this->createFormBuilder()
->setAction($this->generateUrl('comment_delete', array('id' => $id)))
->setMethod('DELETE')
->add('submit', 'submit', array('label' => 'Delete'))
->getForm()
;
}
}
Then in FormType
$builder
->add('comment')
->add('createdby')
->add('updatedby')
->add('datecreated')
->add('dateupdated')
->add('project')//related entity
;

I see at least 3 questions in your question...
For the error :
Unable to guess how to get a Doctrine instance from the request
information,
I don't know why it's happening, but it doesn't seem related directly to the relationship question... Maybe try to suppress fields 'createdby', 'updatedby', 'datecreated', 'dateupdated'from the form builder, as they are not in your mapping yaml file (or maybe you just didn't show them) - whatever, you should probably not display them in the form, but complete these fields in the controller or via prePersist actions, as the user doesn't have to know about them.
Then for the problem that the project field of the form displays a dropdown with project ids : you can specify in the form builder which property of the comment entity you want to display, via the choice_label option, like this :
$builder
->add('comment')
->add('project', 'entity', array(
'class' => 'YourBundle:Project',
'choice_label' => 'projectName',
));
This way, you still will have a dropdown, but with project names displayed instead of ids. The 'entity' file field type has many other options, see the documentation.
For your last question, which is you would like to have a text field with autocomplete instead of a dropdown, you can manage it with a data transformer + a JS autocompleter. See this answer for more information.

Related

How to use Sonata Notification Bundle?

I want to add Notifications system in my symfony (2.8) project, i thought that Sonata Notification Bundle could help, but turns out that i do not know how to use it, i install it very well, but i do not know how to use it in my project.
i need some help about this bundle, some tutorial or so.
or
is there another way to use notification system, please tell me,
thank you in advance
That the controller that i want to use notification bundle
namespace LocationBundle\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use LocationBundle\Entity\Agence;
use Symfony\Component\HttpFoundation\JsonResponse;
/**
* Agence controller.
*
*/
class AgenceController extends Controller
{
/**
* Lists all Agence entities.
*
*/
public function indexAction()
{
$em = $this->getDoctrine()->getManager();
$agences = $em->getRepository('LocationBundle:Agence')->findAll();
return $this->render('agence/index.html.twig', array(
'agences' => $agences,
));
}
/**
* Creates a new Agence entity.
*
*/
public function newAction(Request $request)
{
$agence = new Agence();
$form = $this->createForm('LocationBundle\Form\AgenceType', $agence);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($agence);
$em->flush();
return $this->redirectToRoute('agence_show', array('id' => $agence->getId()));
}
return $this->render('agence/new.html.twig', array(
'agence' => $agence,
'form' => $form->createView(),
));
}
/**
* Finds and displays a Agence entity.
*
*/
public function showAction(Agence $agence)
{
$deleteForm = $this->createDeleteForm($agence);
return $this->render('agence/show.html.twig', array(
'agence' => $agence,
'delete_form' => $deleteForm->createView(),
));
}
/**
* Displays a form to edit an existing Agence entity.
*
*/
public function editAction(Request $request, Agence $agence)
{
$deleteForm = $this->createDeleteForm($agence);
$editForm = $this->createForm('LocationBundle\Form\AgenceType', $agence);
$editForm->handleRequest($request);
if ($editForm->isSubmitted() && $editForm->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($agence);
$em->flush();
return $this->redirectToRoute('agence_edit', array('id' => $agence->getId()));
}
return $this->render('agence/edit.html.twig', array(
'agence' => $agence,
'edit_form' => $editForm->createView(),
'delete_form' => $deleteForm->createView(),
));
}
/**
* Deletes a Agence entity.
*
*/
public function deleteAction(Request $request, Agence $agence)
{
$form = $this->createDeleteForm($agence);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->remove($agence);
$em->flush();
}
return $this->redirectToRoute('agence_index');
}
/**
* Creates a form to delete a Agence entity.
*
* #param Agence $agence The Agence entity
*
* #return \Symfony\Component\Form\Form The form
*/
private function createDeleteForm(Agence $agence)
{
return $this->createFormBuilder()
->setAction($this->generateUrl('agence_delete', array('id' => $agence->getId())))
->setMethod('DELETE')
->getForm()
;
}
I am pretty sure the Sonata Notification Bundle is not what you are searching. The Word "Notification" in the title is in your case a bit misleading. The Bundle is used to postpone actions/events using a queue system like RabbitMQ.
For what you are searching: Take a look at the Symfony's own "Flash Messages": http://symfony.com/doc/current/book/controller.html#flash-messages
It's very easy to implement and you don't need an additional bundle.

Symfony 2.3 PHP unit test using mock objects

Im new in Symfony and phpunit and im trying to do phpunit testing to the following codes.
/**
* Creates a form to delete a Product entity by id.
*
* #param mixed $id The entity id
*
* #return \Symfony\Component\Form\Form The form
*/
private function createDeleteForm($id)
{
return $this->createFormBuilder()
->setAction($this->generateUrl('product_delete', array('id' => $id)))
->setMethod('DELETE')
->add('submit', 'submit', array('label' => 'Delete'))
->getForm()
;
}
/**
* Finds and displays a Product entity.
*
* #Route("/{id}", name="product_show")
* #Method("GET")
* #Template()
*/
public function showAction($id)
{
$em = $this->getDoctrine()->getManager();
$entity = $em->getRepository('AppBundle:Product')->find($id);
if (!$entity) {
throw $this->createNotFoundException('Unable to find Product entity.');
}
$deleteForm = $this->createDeleteForm($id);
return array(
'entity' => $entity,
'delete_form' => $deleteForm->createView(),
);
}
Can anyone help me
My Unit Testing code (just some part)
$mockFormBuilder = $this->getMockBuilder('Symfony\Component\Form\FormBuilder')
->disableOriginalConstructor()
->getMock();
$mockFormBuilder->expects($this->any())
->method('setAction')
->will($this->returnValue(true));
And yes Im stock .. i dont know how to test setMethod, add and getForm to return a form where i can use createView Method again.

Persisting self referencing entity not works

I create an entity with self referencing. My entity look like this:
class Question
{
/**
* #ORM\OneToMany(targetEntity="Question", mappedBy="parent")
**/
private $children;
/**
* #ORM\ManyToOne(targetEntity="Question", inversedBy="children")
* #ORM\JoinColumn(name="parent_id", referencedColumnName="id")
**/
private $parent;
}
And i create a form to edit a Question. With this form i can add many childs to a Question. After i post this form i will save the childs for a parent Object. But the persisting of childs for a parent fails, nothing happens in the database.
public function manageDependencyAction(Request $request, $id)
{
$em = $this->getDoctrine()->getManager();
$question = $em->getRepository('AppMyBundle:Question')->find($id);
if (!$question) {
$this->get('session')->getFlashBag()->add('danger', $this->get('translator')->trans('objectNotFound'));
return $this->redirect($this->generateUrl('app_question_list'));
}
$form = $this->createForm($this->get('form.type.question'), $question, array())->add('save', 'submit', array('label' => 'save', 'translation_domain' => 'messages', 'attr' => array('class' => 'btn btn-primary')));
$form->handleRequest($request);
if ($form->isValid()) {
// dump($question->getChildren()); // This is not empty. In this array are the selected childs.
$em->persist($question);
$em->flush();
}
}
change your entity methods:
public function addChild(Question $children)
{
$this->children[] = $children;
$children->setParent($this);
return $this;
}

Insert foreign key in Symfony2 in OneToMany relation

I have a problem with adding data to the db. I have two entities InternalDocument and InternalDocumentProduct in OneToMany relation.
In InternalDocument:
/**
* #ORM\OneToMany(targetEntity="InternalDocumentProduct", mappedBy="document", cascade={"all"})
**/
protected $products;
In InternalDocumentProduct
/**
* #ORM\ManyToOne(targetEntity="InternalDocument", inversedBy="products")
* #ORM\JoinColumn(name="document_id", referencedColumnName="id")
* */
protected $document;
When I create new InternalDocument I need to insert InternalDocumentProduct too. But When i call persist() method, InternalDocumentProduct is saved without document_id field. It's null. This is my createForm() method in InternalDocumentController:
/**
* Creates a new InternalDocument entity.
*
*/
public function createAction(Request $request)
{
$entity = new InternalDocument();
$form = $this->createCreateForm($entity);
$form->handleRequest($request);
$em = $this->getDoctrine()->getManager();
if ($form->isValid()) {
$em->persist($entity);
$em->flush();
$em = $this->getDoctrine()->getManager();
foreach($entity->getProducts() as $p) {
$em->persist($p);
}
$em->flush();
return $this->redirect($this->generateUrl('acme_warehouse_documents'));
}
return $this->render('AcmeWarehouseBundle:InternalDocument:new.html.twig', array(
'entity' => $entity,
'form' => $form->createView(),
));
}
Can anyone help me?
EDIT:
I resolve this problem. I modified createAction method:
/**
* Creates a new InternalDocument entity.
*
*/
public function createAction(Request $request)
{
$entity = new InternalDocument();
$form = $this->createCreateForm($entity);
$form->handleRequest($request);
$em = $this->getDoctrine()->getManager();
if ($form->isValid()) {
foreach($entity->getProducts() as $p) {
$p->setDocument($entity);
}
$em->persist($entity);
$em->flush();
return $this->redirect($this->generateUrl('acme_warehouse_documents'));
}
return $this->render('AcmeWarehouseBundle:InternalDocument:new.html.twig', array(
'entity' => $entity,
'form' => $form->createView(),
));
}

How to save and edit multiple value using checkbox

I am working in Symfony2 and I have a Form where I show checkboxes which came out of a Database. I want to save the selected checkboxes in the Database (mayby as a array or string like value1, value2). How can I handle this
This is my Code:
Entity:
/**
* #var string
*/
private $relevantewaben;
/**
* #return string
*/
public function getRelevantewaben()
{
return $this->relevantewaben;
}
/**
* #param string $relevantewaben
*/
public function setRelevantewaben($relevantewaben)
{
$this->relevantewaben = $relevantewaben;
}
Controller:
public function newAction()
{
$entity = new ChangeRequest();
$form = $this->createCreateForm($entity);
return $this->render('OtlgCmdbBundle:ChangeRequest:new.html.twig', array(
'entity' => $entity,
'form' => $form->createView(),
));
}
public function updateAction(Request $request, $id)
{
$em = $this->getDoctrine()->getManager();
$entity = $em->getRepository('OtlgCmdbBundle:ChangeRequest')->find($id);
if (!$entity) {
throw $this->createNotFoundException('Unable to find ChangeRequest entity.');
}
$deleteForm = $this->createDeleteForm($id);
$editForm = $this->createEditForm($entity);
$editForm->handleRequest($request);
if ($editForm->isValid()) {
$em->flush();
return $this->redirect($this->generateUrl('changerequest_edit', array('id' => $id)));
}
return $this->render('OtlgCmdbBundle:ChangeRequest:edit.html.twig', array(
'entity' => $entity,
'edit_form' => $editForm->createView(),
'delete_form' => $deleteForm->createView(),
));
}
Form:
->add('relevantewaben', 'entity', array(
'class' => 'OtlgCmdbBundle:applicant',
'label' => 'Benötigte, relevante Waben zur Umsetzung',
'property' => 'name',
'expanded' => true,
'required' => false,
'multiple' => true,
'attr' => array('class' => 'css-checkbox')
If you declare the relationship between you entity and OtlgCmdbBundle:applicant, where your entity is the owner side of the relationship, Doctrine will take your changes in account automatically. For example, instead of
/**
* #var string
*/
private $relevantewaben;
you should have sth like
/**
* #var \Doctrine\Common\Collections\ArrayCollection
* #ORM\OneToMany(targetEntity="applicant", mappedBy="changeRequests", cascade={"persist"})
*/
private $relevantewaben;
Take a look at : http://docs.doctrine-project.org/en/2.0.x/reference/association-mapping.html
If what you want to save is not the relationship but, in fact, the checkboxes selected themselves:
In your controller, the variable $entity has all your changes when you enter if ($editForm->isValid()) {, so you could do $entity->getRelevantewaben() to get which ones where selected.
When you have a field that's not mapped, you can access that data with $form->get('relevantewaben')->getData(), and that's the value that you have in the form field. I haven't use it to get values that were already mapped, but that can give you an idea if that's your case.

Resources