symfony doctrine update from form - symfony

I'm stuck since this morning with the update of an entity.
Don't know what I'm missing, pretty sure this is a newbie mistake.
I'm just trying to update something via a form.
The controller:
public function editAction($pid, $plid, Request $request)
{
$plan = new Plan();
$form = $this->createForm(new PlanType(), $plan);
$plan = $this->getDoctrine()->getRepository('QArthFrameworkBundle:Plan')->findOneByPlid($plid);
$project = $this->getDoctrine()->getRepository('QArthFrameworkBundle:Project')->findOneByPid($pid);
$form->handleRequest($request);
if ($request->getMethod() == 'POST') {
$em = $this->getDoctrine()->getManager();
$em->flush();
return $this->redirect($this->generateUrl('qarth_framework_plan_edit', array('pid' => $pid, 'plid' => $plid)));
}
return $this->render('QArthFrameworkBundle:Pages:plan_edit.html.twig', array(
'plan' => $plan,
'project' => $project,
'form' => $form->createView(),
));
}
The form:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('name');
$builder->add('description', 'textarea');
}
The Entity : http://pastebin.com/bTqKehyQ
With the profiler I can see that my post parameters are well posted
plan {"name":"fsggsfgsf","description":"gsfgsfgsf","_token":"7d089aca0203c60fe1e617488e532ac966101440"}
But I can't see any trace of an update query or something else.
If you have an idea, it will be great!
Many thanks,
Ben

Need to pass the queried plan to the form.
public function editAction($pid, $plid, Request $request)
{
$plan = $this->getDoctrine()->getRepository('QArthFrameworkBundle:Plan')->findOneByPlid($plid);
$project = $this->getDoctrine()->getRepository('QArthFrameworkBundle:Project')->findOneByPid($pid);
// Create a new one if not found
if (!$plan) $plan = new Plan();
// Build your form using queried or new plan
$form = $this->createForm(new PlanType(), $plan);
$form->handleRequest($request);
// Checks for POST as well as validity
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($plan); // To handle new plans, no impact for existting plans
$em->flush();
// Rest is the same

Related

can't update entity Symfony2

Trying to update my entity, unfortunately didnt use Doctrines generate CRUD feature (have to change stuff I didnt write).
I am finally getting data into my form, but it just won't save the changes (also, it doesn't create a new entity as one might suspect).
When I click 'save', I always return to the page where I have my form to edit the entity.
Checked if method is POST, it is.
if ($form->get('save')->isClicked()) {
doesn't seem to do anything, how can that be?
Here's the rest of my action:
/**
* Updates.
*
* #Route("/offerweekchange/{offerid}", name="offerweekchange")
* #Template("")
*/
public function offerweekchangeAction(Request $request, $offerid)
{
$request = $this->get('request');
if ($offerid) {
$em = $this->getDoctrine()->getManager();
$entity = $em->getRepository('AlexanderBuerkleShopBundle:Promotion')->findOneBy(array('id' => $offerid));
$form = $this->createForm(new OfferWeekChangeType(), $entity);
# \Doctrine\Common\Util\Debug::dump($request->getMethod());
if ($form->get('save')->isClicked()) {
if ($request->getMethod() == 'POST') {
$form->bind($request);
if ($form->isValid()) {
$em->flush();
return $this->redirect($this->generateUrl('offerweeklist'));
}
}
}
return $this->render('AlexanderBuerkleShopBundle:OfferWeekList:offerweekchange.html.twig',
array('form' => $form->createView(), 'offerid' => $offerid, 'entity' => $entity));
}
}
Any help would be greatly appreciated.
First, here is a working sample of your code:
public function offerweekchangeAction(Request $request, $offerid)
{
if ($offerid) {
$em = $this->getDoctrine()->getManager();
$entity = $em->getRepository('AlexanderBuerkleShopBundle:Promotion')->findOneBy(array('id' => $offerid));
$form = $this->createForm(new OfferWeekChangeType(), $entity);
$form->handleRequest($request);
# \Doctrine\Common\Util\Debug::dump($request->getMethod());
if ($form->isValid()) {
$em->persist($entity);
$em->flush();
return $this->redirect($this->generateUrl('offerweeklist'));
}
return $this->render('AlexanderBuerkleShopBundle:OfferWeekList:offerweekchange.html.twig',
array('form' => $form->createView(), 'offerid' => $offerid, 'entity' => $entity));
}
}
Secondly, you have several mistakes here, so let's analyse them one by one:
1:
if ($offerid) {
your code does nothing on the else branch.
2:
$request = $this->get('request');
you already have the request parameter injected into the action. This line is redundant.
3:
$form->bind($request);
This is deprecated since 2.3. Use $form->handleRequest($request) instead.
4:
$em->flush();
You are flushing the entity manager, but nothing is persisted, so nothing will happen. you have to persist the entity first with $em->persist($entity)
5:
if ($request->getMethod() == 'POST') {
The method $form->isValid() checks for this also, so checking for post is redundant.
That's it. Hope it helped.
The most likely issue here is with the AbstractType which define your form OfferWeekChangeType).
In order to map the form data on the entity you need to set the 'data_class'.
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(
array(
'data_class' => ' Acme\StoreBundle\Entity\Product',
)
);
}
then inside your controller you need to invoke :
$form->handleRequest($request);
This will bind the request to your form.
Only when you invoke:
$form->isValid()
The data from the form (if valid) will be mapped on the entity.
$em->persist($entity);
in this case is superflus because Doctrine UnityOfWork already 'knows' the entity from when you got it from the repository. Just invoke
$em->flush($entity);
As a side note remember that flushing only the needed entity is preferable (when possible) the flush the entire UnityOfWork in order to avoid unexpected behaviours.
Regards.

Symfony2 handleRequest with PUT request

I have some trouble with handleRequest:
Here is my code:
public function putAssetAction(Request $request, $id){
$em = $this->getDoctrine()->getManager();
$entity = $em->getRepository( 'BudgetBundle:Asset' )->find( $id );
$form = $this->createForm( new AssetType(), $entity, array('method' => 'PUT') );
$form->handleRequest($request);
The problem is that form data are correct, but $form->isValid() return false because isSubmitted() is false
But $form->bind() is also not working, because it's a PUT request, and when I do bind($request) then $form->getData() returns null.
I'm using this with FosRestBundle and Backbone, and for testing request I'm using chrome extension postman.
You can try submit() instead of handleRequest(), eg:
$form->submit($request);

Call an entity method in a controller

i have three entities: Invoice,Payment and Result
the relationships between entities are:
Result(1,1)-------------(1,n)Invoice(1,n)---------------(1,1)Payment
here's my problem :I would like in my PaymentController when I create a new payement ,I retrieve Invoice entity and in the same PaymentController I create a new Result.
here's my PaymentController code:
use MyApp\AccountBundle\Entity\Result;
class PaymentController extends Controller
public function createAction()
{
$entity = new Payment();
$request = $this->getRequest();
$form = $this->createForm(new PaymentType(), $entity);
$form->bindRequest($request);
$amount=$form->get('amountreceived')->getData();
if ($form->isValid()) {
$em = $this->getDoctrine()->getEntityManager();
$invoice = em->getRepository('MyAppAccountBundle:Invoice')->find($entity->getInvoice()->getId())
if (!$invoice) {
throw $this->createNotFoundException('Unable to find Invoice entity.');
}
$result=new Result();
$result=setDebitAmount($amount);
$result=setCreditAmount(0);
$result=setInvoice($invoice);
$em->persist($result);
$em->persist($entity);
$em->flush();
return $this->redirect($this->generateUrl('payment_show', array('id' => $entity->getId())));
}
return $this->render('MyAppAccountBundle:Payment:new.html.twig', array(
'entity' => $entity,
'form' => $form->createView()
));
when a execute PaymentController (in view) i get error:
Fatal error: Call to undefined function MyApp\AccountBundle\Controller\setDebitAmount() in C:\wamp\www\account\src\ MyApp\AccountBundle\Controller\PaymentController.php on line...
thank in advance
Change = to ->
$result=setDebitAmount($amount);
must be
$result->setDebitAmount($amount);

Symfony2 - Establish one form parameter from outside so cannot be modified by the users

I have a CRUD for one of my entities in Symfony2. In order to create a new entry, I have two controller functions:
public function newAction($id) {
$entity = new Clientes();
// Get the reference to the Login entity using its ID
$em = $this->getDoctrine()->getManager();
$ref_login = $em->getReference('LoginBundle:Login', $id);
// Put the retrieved reference to the entity
$entity->setLogin($ref_login);
$form = $this->createForm(new ClientesType(), $entity);
return $this
->render('MovinivelBundle:Persona/Clientes:new.html.twig',
array('entity' => $entity,
'form' => $form->createView(),));
}
public function createAction(Request $request) {
$entity = new Clientes();
$form = $this->createForm(new ClientesType(), $entity);
$form->bind($request);
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($entity);
$em->flush();
return $this->redirect($this->generateUrl('clientes'));
}
return $this
->render('MovinivelBundle:Persona/Clientes:new.html.twig',
array('entity' => $entity,
'form' => $form->createView(),));
}
In the previous code I added the $id input parameter to the newAction() function because I want it to be established from outside, because each of this Clientes is additional info of Login and has to be linked.
In the ClientesType form I have the following:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('login')
->add('direccion')
->add('localidad')
->add('provincia')
->add('telefono')
;
}
So far it works. In my form, the login parameter is chosen depending on the $id value. But the thing is that I want the login parameter to be fixed once the form is created, so the user cannot modify it from the form, but only calling the newAction($id) function with the appropiate value.
The thing is that if I delete the ->add('login') line in the FormType, it doesn't work anymore. It comes to my mind two options:
Hide somehow the 'login' in the form, but keeping it working, although I don't know how, or
pass to the createAction the $id parameter along with the $request one as input parameters, but I cannot figure out how do it either.
Any thoughts on this?
I think you are looking for a hidden field type:
public function buildForm(...)
{
$builder
->add('login', 'hidden')
// ...
;
}
Ok, I came out with the solution. All I was looking for is actually the following:
<div style="display:none">
{{ form_rest(form) }}
</div>
Typing this at the end of the template after having shown explicitly any other form field avoids any user to modify the fields I don't want to, while it still sends the info using the $POST method.

Symfony2, how to access Entity values inside Form?

I have a FormType in Symfony2. It is used to display the settings. The settings are stored as entities in a database. Using Doctrine2, I fetch the settings and create a form, like below:
public function showSettingsAction()
{
if(false === $this->get('security.context')->isGranted('ROLE_ADMIN')) {
throw new AccessDeniedException();
}
$settings = new CommunitySettings();
$repository = $this->getDoctrine()->getRepository('TestTestingBundle:CommunitySettings');
$allSettings = $repository->findAll();
$form = $this->createForm('collection', $allSettings, array(
'type' => 'settings_form'
));
$request = $this->container->get('request');
if($request->getMethod() === 'POST') {
$form->bindRequest($request);
if($form->isValid()) {
$em = $this->getDoctrine()->getEntityManager();
$settings = $form->getData();
foreach($settings as $setting) {
$oldsetting = $em->getRepository('TestTestingBundle:CommunitySettings')
->find($setting->getId());
if(!$oldsetting) {
throw $this->createNotFoundException('No setting found for id '.$setting->getId());
}
$oldsetting->setSettingValue($setting->getSettingValue());
$em->flush();
}
$this->get('session')->setFlash('message', 'Your changes were saved');
return new RedirectResponse($this->generateUrl('_admin_settings'));
}
}
return $this->render('TestTestingBundle:Admin:settings.html.twig',array(
'form' => $form->createView(),
));
}
This is the line of code where I send the array of $allSettings to the settings_form:
$form = $this->createForm('collection', $allSettings, array(
'type' => 'settings_form'
));
This is how the settings form looks like:
public function buildForm(FormBuilder $builder, array $options)
{
$builder->add('settingValue', 'text');
}
I have a label, a value and a field type stored in the entity and I would like to use those for building the form. However, when I use this it only shows me the variable names in the Form, like this:
0
Settingvalue //Is a checkbox, where it says Settingvalue, it should be the label stored in the entity
0
1
Settingvalue //Is a integer, where it says Settingvalue, it should be the label stored in the entity
3000
How can I use the variables stored in the Entity to build the Form fields with?
You can use an event listener in your settings form type to solve this problem.
public function buildForm(FormBuilder $builder, array $options)
{
$formFactory = $builder->getFormFactory();
$builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) use ($formFactory) {
$form = $event->getForm();
$data = $event->getData();
$form->add($formFactory->createNamed('settingsValue', $data->getSettingsType(), array(
'label' => $data->getSettingsLabel(),
)));
});
}

Resources