Insert foreign key in Symfony2 in OneToMany relation - symfony

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(),
));
}

Related

How to write unit test in symfony3

I want to know how to write standard unit test code for the below controller. I believe PHPUNIT is installed by default in symfony3 but I'm not sure how to execute it as well. Can someone guide me how to write testcontroller and execution command for symfony3 as well.
class RegistrationController extends Controller
{
/**
* #Route("/register", name="user_registration")
* #Security("has_role('ROLE_SUPER_ADMIN')")
*/
public function userAction(Request $request)
{
$user = new User();
$form = $this->createForm(UserType::class, $user);
$form->handleRequest($request);
if ($request->isMethod('POST') && $form->isValid()) {
$password = $this->get('security.password_encoder')
->encodePassword($user, $user->getPlainPassword());
$user->setPassword($password);
$em = $this->getDoctrine()->getManager();
$em->persist($user);
$em->flush();
$this->get('app.mailer')->sendUserCredentials($user);
$this->addFlash('notice', 'An account is created');
}
return $this->render('masteradmin/account/addUser.html.twig',
array('form' => $form->createView())
);
}
/**
* #Route(
* "/user/edit/{id}",
* requirements={"id" = "\d+"},
* name="user_edit"
* )
*/
public function editUserAction(User $user, Request $request)
{
if (!$this->get('security.authorization_checker')->isGranted('ROLE_SUPER_ADMIN')) {
throw new AccessDeniedException();
}
$em = $this->getDoctrine()->getManager();
$id = $request->attributes->get('id');
if (!$user = $em->getRepository('AppBundle:User')->findOneById($id)) {
throw new NotFoundHttpException('user details not found.');
}
$form = $this->createForm(UserType::class, $user)
->remove('plainPassword');
$form->handleRequest($request);
$data = $form->getData();
if ($form->isValid()) {
$em->persist($user);
$em->flush();
$this->addFlash('notice', 'Account information is updated');
return $this->redirectToRoute('user_list');
}
return $this->render(
'masteradmin/account/editUser.html.twig', ['form' => $form->createView()]
);
}

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.

Automatically set related entity id in one to many relationship 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.

Symfony2 persist correlated objects

This my issue:
Entity AddressBook 1-N Entity Number
The controller displays the edit form with AddressBook and its number, but when I save the form, I get this error:
Fatal error: Call to a member function setTipo() on a non-object
Strangely, however, the data is saved correctly
This my code:
/**
* Modifica dati Anagrafica
* #Route("/contatto/{id}/modifica", name="_anagrafica_modifica")
* #Template()
*/
public function modificaAction($id)
{
$em = $this->getDoctrine()->getManager();
$anagrafica = $em->getRepository('MercurioInterfaceBundle:Anagrafica')->find($id);
if (!$anagrafica) {
throw $this->createNotFoundException('No anagrafica found for id '.$id);
}
$form = $this->createForm(new \Mercurio\InterfaceBundle\Form\Anagrafica\FormAnagrafica(), $anagrafica);
$request = $this->getRequest();
if ($request->getMethod() == 'POST')
{
$form->bind($request);
if ($form->isValid())
{
$chiave = $request->request->get('anagrafica');
$em = $this->getDoctrine()->getManager();
$anagrafica = $em->getRepository('MercurioInterfaceBundle:Anagrafica')->find($id);
$anagrafica->setNominativo($chiave['nominativo']);
$anagrafica->setIndirizzo($chiave['indirizzo']);
$anagrafica->setCap($chiave['cap']);
$anagrafica->setCitta($chiave['citta']);
$anagrafica->setNote($chiave['note']);
$em->flush();
$dettaglio = $em->getRepository('MercurioInterfaceBundle:AnagDettaglio')->findBy(array('anagrafica_id' => $id,));
foreach ($chiave['anag_dettagli'] as $d)
{
$dettaglio->setTipo($d['tipo']);
$dettaglio->setValore($d['valore']);
$dettaglio->setRiferimento($d['riferimento']);
}
$em->flush();
return $this->redirect($this->generateUrl('_anagrafica_contatto', array('id' => $id)));
}
}
return array(
'form' => $form->createView(),
'id' => $id
);
}
Solved:
$form = $this->createForm(new \Mercurio\InterfaceBundle\Form\Anagrafica\FormAnagrafica(),$anagrafica);
if ($request->isMethod('POST')){
$form->bind($request);
if ($form->isValid()) {
$em->persist($anagrafica);
$em->flush();
return $this->redirect(....)
}
}

One-To-One, Unidirectional Relationship

I have these entities: - Store and Package
I'd like to build a StoreType form where i add package Id.
I've made a StoreType Form class: (I would expect to get a select box from this, where all package are listed)
I've add the package through one to one, but my problem is when i add package in store form then form is create but in my database store table column package are empty.i don't know why?
Store.php
/**
* #ORM\Entity
*/
class Store
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\Column(type="string", length="255")
*/
protected $title;
/**
* #ORM\Column(type="string", length="255")
*/
protected $domain;
/**
* #ORM\OneToOne(targetEntity="Package",cascade={"persist", "remove"})
* #ORM\JoinColumn(name="package_id", referencedColumnName="id")
*/
protected $package;
}
Package.php
/**
* #ORM\Entity
*/
class Package
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\Column(type="string", length=255)
*/
protected $title;
/**
* #ORM\Column(type="text", length="4000")
*/
protected $description;
/**
* #ORM\Column(type="boolean")
*/
protected $active;
public function __toString()
{
return $this->getTitle();
}
}
StoreType.php
class StoreType extends AbstractType
{
public function buildForm(FormBuilder $builder, array $options)
{
$builder
->add('title')
->add('domain')
->add('package','entity',array(
'class' => 'WebmuchProductBundle:Package',
));
}
public function getName()
{
return 'webmuch_productbundle_storetype';
}
}
StoreController.php
/**
* Store controller.
*
* #Route("/store")
*/
class StoreController extends Controller
{
/**
* Lists all Store entities.
*
* #Route("/", name="store")
* #Template()
*/
public function indexAction()
{
$em = $this->getDoctrine()->getEntityManager();
$entities = $em->getRepository('WebmuchProductBundle:Store')->findAll();
return array('entities' => $entities);
}
/**
* Finds and displays a Store entity.
*
* #Route("/{id}/show", name="store_show")
* #Template()
*/
public function showAction($id)
{
$em = $this->getDoctrine()->getEntityManager();
$entity = $em->getRepository('WebmuchProductBundle:Store')->find($id);
if (!$entity) {
throw $this->createNotFoundException('Unable to find Store entity.');
}
$deleteForm = $this->createDeleteForm($id);
return array(
'entity' => $entity,
'delete_form' => $deleteForm->createView(), );
}
/**
* Displays a form to create a new Store entity.
*
* #Route("/new", name="store_new")
* #Template()
*/
public function newAction()
{
$store = new Store();
$form = $this->createForm(new StoreType(), $store);
return array(
'entity' => $store,
'form' => $form->createView()
);
}
/**
* Creates a new Store entity.
*
* #Route("/create", name="store_create")
* #Method("post")
* #Template("WebmuchProductBundle:Store:new.html.twig")
*/
public function createAction()
{
$entity = new Store();
$request = $this->getRequest();
$form = $this->createForm(new StoreType(), $entity);
$form->bindRequest($request);
if ($form->isValid()) {
$em = $this->getDoctrine()->getEntityManager();
$em->persist($entity);
$em->flush();
return $this->redirect($this->generateUrl('store_show', array('id' => $entity->getId())));
}
return array(
'entity' => $entity,
'form' => $form->createView()
);
}
/**
* Displays a form to edit an existing Store entity.
*
* #Route("/{id}/edit", name="store_edit")
* #Template()
*/
public function editAction($id)
{
$em = $this->getDoctrine()->getEntityManager();
$entity = $em->getRepository('WebmuchProductBundle:Store')->find($id);
if (!$entity) {
throw $this->createNotFoundException('Unable to find Store entity.');
}
$editForm = $this->createForm(new StoreType(), $entity);
$deleteForm = $this->createDeleteForm($id);
return array(
'entity' => $entity,
'edit_form' => $editForm->createView(),
'delete_form' => $deleteForm->createView(),
);
}
/**
* Edits an existing Store entity.
*
* #Route("/{id}/update", name="store_update")
* #Method("post")
* #Template("WebmuchProductBundle:Store:edit.html.twig")
*/
public function updateAction($id)
{
$em = $this->getDoctrine()->getEntityManager();
$entity = $em->getRepository('WebmuchProductBundle:Store')->find($id);
if (!$entity) {
throw $this->createNotFoundException('Unable to find Store entity.');
}
$editForm = $this->createForm(new StoreType(), $entity);
$deleteForm = $this->createDeleteForm($id);
$request = $this->getRequest();
$editForm->bindRequest($request);
if ($editForm->isValid()) {
$em->persist($entity);
$em->flush();
return $this->redirect($this->generateUrl('store_edit', array('id' => $id)));
}
return array(
'entity' => $entity,
'edit_form' => $editForm->createView(),
'delete_form' => $deleteForm->createView(),
);
}
/**
* Deletes a Store entity.
*
* #Route("/{id}/delete", name="store_delete")
* #Method("post")
*/
public function deleteAction($id)
{
$form = $this->createDeleteForm($id);
$request = $this->getRequest();
$form->bindRequest($request);
if ($form->isValid()) {
$em = $this->getDoctrine()->getEntityManager();
$entity = $em->getRepository('WebmuchProductBundle:Store')->find($id);
if (!$entity) {
throw $this->createNotFoundException('Unable to find Store entity.');
}
$em->remove($entity);
$em->flush();
}
return $this->redirect($this->generateUrl('store'));
}
private function createDeleteForm($id)
{
return $this->createFormBuilder(array('id' => $id))
->add('id', 'hidden')
->getForm()
;
}
}
I think you forget to do this in your createAction :
$request = $this->getRequest();
$form->setData($request->getPost());

Resources