Symfony2 404 error: Object Not Found (ParamConverter error) - php

I created a new boundary class called search.html.twig, but when I go to the URL (http://localhost:8000/shrubs/search) I get the following error:
ERROR - Uncaught PHP Exception Symfony\Component\HttpKernel\Exception\NotFoundHttpException: "AppBundle\Entity\Shrubs object not found." at C:\Users\rosmith\shrub_search\vendor\sensio\framework-extra-bundle\Request\ParamConverter\DoctrineParamConverter.php line 66
There must be something wrong with my ParamConverter? Are my annotations correct? I read the symfony documentation but it just doesn't make sense to me. Here's my controller:
/**
* Finds and displays a shrub entity.
*
* #Route("/search", name="shrubs_search")
* #ParamConverter("post", class="AppBundle:Shrubs")
*/
private function searchAction(Request $request)
{
$shrub = new Shrubs();
$form = $this->createForm('AppBundle\Form\ShrubsType', $shrub)
->add('botanicalname', TextType::class, array('label' => 'Botanical Name:'))
->add('commonname', TextType::class, array('label' => 'Common Name:'))
->add('wetsoil', CheckboxType::class, array('label' => 'Tolerates Wet Soil:'))
->add('moistsoil', CheckboxType::class, array('label' => 'Prefers Moist Soil:'))
->add('peatysoil', CheckboxType::class, array('label' => 'Prefers Peaty Soil:'))
->add('welldrainedsoil', CheckboxType::class, array('label' => 'Prefers Well-drained Soil:'))
->add('drought', CheckboxType::class, array('label' => 'Tolerates Drought:'))
->add('claysoil', CheckboxType::class, array('label' => 'Tolerates Clay Soil:'))
->add('sandysoil', CheckboxType::class, array('label' => 'Prefers Sandy Soil:'))
->add('loamsoil', CheckboxType::class, array('label' => 'Prefers Loam Soil:'))
->add('infertilesoil', CheckboxType::class, array('label' => 'Tolerates Infertile Soil:'))
->add('richsoil', CheckboxType::class, array('label' => 'Prefers Rich Soil:'))
->add('compactedsoil', CheckboxType::class, array('label' => 'Tolerates Compacted Soil:'))
->add('cityconditions', CheckboxType::class, array('label' => 'Tolerates City Conditions:'))
->add('pollution', CheckboxType::class, array('label' => 'Tollerates Pollution:'))
->add('salt', CheckboxType::class, array('label' => 'Tolerates Salt Conditions:'))
->add('windy', CheckboxType::class, array('label' => 'Tolerates Windy Conditions:'))
->add('shade', CheckboxType::class, array('label' => 'Prefers Shade:'))
->add('partshade', CheckboxType::class, array('label' => 'Prefers Part Shade:'))
->add('fullsun', CheckboxType::class, array('label' => 'Prefers Full Sun:'))
->add('pestproblem', CheckboxType::class, array('label' => 'Pest Problem:'))
->add('borderlinehardy', CheckboxType::class, array('label' => 'BorderLine Hardy'));
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($shrub);
$em->flush($shrub);
return $this->redirectToRoute('shrubs_show', array('id' => $shrub->getNumber()));
}
return $this->render('shrubs/new.html.twig', array(
'shrub' => $shrub,
'form' => $form->createView(),
));
}

Your route should contain post param.
#Route("/search/{post}", name="shrubs_search")
Also your method should take this param as method argument.

Related

How to show field value in sonata edit form?

There is edit form. One field should not be editable. I have tried to set options disabled=true, attr => ['readonly' => true], they make it uneditable, but when submitting form, it gets submitted, sets null to that field and then I get error when getting that field value because it cannot be null.
So I want to make that field not even exist as field but show its value in edit form. Is there a way to do it? Or also if you know how to get rid of error when submitting form with disabled field, that would work too.
public function configureFormFields(FormMapper $form)
{
if ($this->subject->getId() === null) {
$form
->add('name', 'text', ['required' => true])
->add('codeMod', 'text', ['required' => true])
->add('position', 'text', ['required' => false])
->add('projectMod', EntityType::class, ['class' => ProjectEntity::class])
->add('active', 'checkbox', ['required' => false])
->add('first', 'checkbox', ['required' => false])
->add('last', 'checkbox', ['required' => false])
->add('denialReasons', 'text', ['required' => false])
;
} else {
$form
->add('name', 'text', ['required' => true])
->add('position', 'text', ['required' => false])
// ->add('project', TextType::class, ['label' => 'form.label_project_mod', 'attr' => [/*'readonly' => true,*/ 'disabled' => true]])
->add('project', EntityType::class,
['label' => 'form.label_project_mod', 'class' => ProjectEntity::class, 'attr' => ['readonly' => true, 'disabled' => true],
// 'template' => 'ClaimClaimBundle:ClaimStatusAdmin:show_project.html.twig'
]
)
// ->add('projectMod', TextType::class, ['label' => 'form.label_project_mod', 'attr' => [/*'readonly' => true,*/ 'disabled' => true]])
->add('active', 'checkbox', ['required' => false])
->add('first', 'checkbox', ['required' => false])
->add('last', 'checkbox', ['required' => false])
->add('denialReasons', 'text', ['required' => false])
;
}
}
Currently I get error:
Type error: Return value of Qms\ClaimComponent\Status\ManagedModel\StatusManaged::getProject() must implement interface Qms\CoreComponent\Domain\Project\ManagedModel\ProjectManagedInterface, null returned
That is because field value is set to null if I have disabled field.
One way could be rewrite edit.html.twig, now sonatas default template is used. But I did not find quick way, if I override, the styling is off. For one field looks bit too much.
If you don't mind that field's value when submitting you can unmap it by setting
'mapped' => false
in its attributes.
Example:
->add('name', 'text', ['required' => true, 'mapped' => false])

Symfony - checkbox form

I have trouble with syntax, my form does not show a checkbox in a right way. Any ideas?
$form = $this->createFormBuilder()
->add('generate', CheckboxType::class, array('label' => 'Generate', 'attr' => ['class'=>'form-control']))
->add('save', SubmitType::class, array('label' => 'Send', 'attr' => [
'class' => 'btn btn-primary action-save'
]))
->getForm();

Sonata/AdminBundle: Selected Option

I'm new in Symfony and Sonata/AdminBundle. I would like to know how to mark selected an option when the entity has a field from other entity. For example: I have two entities: Shop and City. The Shop entity has a field called id_city.
My problem is when I'm rendering the edit form Shop because always the first id_city in the option is selected.
This is the piece of code where I'm rendering the configuration form in AdminStores class:
protected function configureFormFields(FormMapper $formMapper)
{
$formMapper
->tab('Tiendas')
->with('Content', array('class' => 'col-md-9'))
->add('nombreTienda', 'text')
->add('cifTienda', 'text')
->add('direccionTienda', 'text')
->add('personaContacto', 'text', array('required' => false,'empty_data' => ''))
->add('cp', 'text', array('label' => 'Código Postal', 'required' => false, 'empty_data' => '00000'))
->add('urlTienda', 'text', array('required' => false, 'empty_data' => ''))
->add('emailTienda', 'text')
->add('telefonoTienda', 'text')
->add('login', 'text')
->add('pass', 'password', array('required' => false))
->add('idMunicipio', 'entity', array(
'class' => 'AppBundle:Municipios',
'choice_label' => 'municipio',
'query_builder' => function (EntityRepository $er) {
$lista = $er->createQueryBuilder('ss')
->orderBy('ss.municipio', 'ASC');
},
'data' => $this->subject->getIdMunicipio()
)) // end array idMunicipio y add()
->add('idProvincia', EntityType::class, array(
'class' => 'AppBundle:Provincias',
'label' => 'Provincia',
'choice_label' => 'provincia',
'choice_value' => 'getId',
'by_reference' => true,
))
->add('descripcionTienda', 'textarea')
->end()
->end()
->tab('Multimedia')
->with('Content', array('class' => 'col-md-3'))
->add('fotoTienda', 'file', array(
'label' => 'Imagenes (puedes subir hasta 6 imágenes)',
'attr' =>array('class' => 'form-control', 'multiple' => 'multiple', 'accept' => 'image/*'),
'data_class' => null,
'required' => false,
'empty_data' => 'noDisponible',
));
}
In this piece of code, I'm recovering all cities in AdminStores class:
->add('idMunicipio', 'entity', array(
'class' => 'AppBundle:Municipios',
'choice_label' => 'municipio',
'query_builder' => function (EntityRepository $er) {
$lista = $er->createQueryBuilder('ss')
->orderBy('ss.municipio', 'ASC');
},
'data' => $this->subject->getIdMunicipio()
)) // end array idMunicipio y add()
I would like to know, please, the logic for " if this->id_city == entity->id_city then, option is selected".
Thanks in advance
I edit this comment because I think that I solved it.
In my AdminController called ShopsAdmin I have created a method called getAllMunicipios which return an array with their name and id:
$allCities = array(
'Tokyo' => 1
'Madrid => 2
);
This is the method:
protected function getAllMunicipios()
{
$municipios = $this->getConfigurationPool()
->getContainer()
->get('doctrine')
->getRepository('AppBundle:Municipios')
->findBy([], ['municipio' => 'ASC']);
$todosmunicipios = array();
foreach ($municipios as $municipio) {
$todosmunicipios[(string)$municipio->getMunicipio()] = (int)$municipio->getId();
}
return $todosmunicipios;
}
Now my AdminStores::configureFormFields method like that this:
->add('idMunicipio', 'choice', array(
'choices' => $this->getAllMunicipios(),
'required' => false,
'by_reference' => false,
'data' => $this->subject->getIdMunicipio()
))
It is a good way to do it? I think that the method that return all, must be placed into the entity and not int the controller but I dont know how do it static
just call setCity(\AppBundle\Entity\City $city) in your Shop entity. and give the right city entity as the first and only parameter. Do this before you render the form

Symfony 3 - Best practice for concating form-blocks

I'm trying to learn how to build forms in symfony 3.
Following some tutorials I have built a PersonType
class PersonType extends AbstractType {
public function buildForm(FormBuilderInterface $builder, array $options) {
$builder->add('gender', ChoiceType::class, array('label' => 'Anrede', 'choices' => array('Herr' => 'Herr', 'Frau' => 'Frau'), 'attr' => array('class' => 'form-control')))
->add('title', TextType::class, array('label' => 'Titel', 'attr' => array('class' => 'form-control')))
->add('firstname', TextType::class, array('label' => 'Vorname', 'attr' => array('class' => 'form-control')))
->add('lastname', TextType::class, array('label' => 'Nachname', 'attr' => array('class' => 'form-control')))
->add('birthdate', DateType::class, array('label' => 'Geburtsdatum', 'attr' => array('class' => 'form-control')))
->add('street', TextType::class, array('label' => 'Straße', 'attr' => array('class' => 'form-control')))
->add('streetnumber', TextType::class, array('label' => 'Hausnummer', 'attr' => array('class' => 'form-control')))
->add('zip', TextType::class, array('label' => 'PLZ', 'attr' => array('class' => 'form-control')))
->add('city', TextType::class, array('label' => 'Stadt', 'attr' => array('class' => 'form-control')))
->add('email', TextType::class, array('label' => 'E-Mail', 'attr' => array('class' => 'form-control')));
}
public function getName() {
return 'person';
}
}
And some other types.
In the controller I have
$person = new Person();
$form = $this->createForm(PersonType::class, $person);
My question now is, how do I now concat the PersonType to some other Types to get one Form out of it? And how do I then set the submit-button?
You cannot concatenate but you can include a subset of fields in several forms.
Here you have a nice example in the Symfony documentation :
http://symfony.com/doc/current/cookbook/form/inherit_data_option.html
Recap :
Create a form with your subfields, with the option 'inherit_data' => true.
Use it in another form as field.
First of all, please note how you add fields to PersonType form, because it will be exactly the same.
->add('email', TextType::class, array('label' => 'E-Mail', 'attr' => array('class' => 'form-control')));
What you do here is adding a subform TextType. It actually contains single field, but it's still a form.
The same way you can add PersonType to any other form. That would be something like:
->add('person', PersonType::class, array(/* some options if needed*/);
And how do I then set the submit-button?
As mentioned in Best Practices for Symfony Forms, I would suggest to add them in template, not to the form object.

Nested forms error "Entities passed to the choice field must be managed"

I've been stuck on this for days and tried all the solutions I could find online but no luck.
I have a Student linked to many Transfers. Each transfer is linked to a Classe.
To make the form I use the following classes : StudentType, TransferType.
The StudentType form classe had a field of type TransferType. Codes below.
StudentType.php
<?php
// src/PS/PSchoolBundle/Form/StudentType.php
namespace PS\PSchoolBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilder;
use PS\PSchoolBundle\Entity\Responsible;
use PS\PSchoolBundle\Entity\AuthorizedPerson;
use PS\PSchoolBundle\Entity\Transfer;
class StudentType extends AbstractType
{
public function buildForm(FormBuilder $builder, array $options)
{
$builder
->add('subNumber', 'text', array('required' => false))
->add('subDate', 'date', array(
'required' => false,
'widget' => 'single_text',
'format' => 'dd/MM/yyyy',
'attr' => array('class' => 'datepicker')
))
->add('lastName', 'text')
->add('firstName', 'text')
->add('lastNameSecondLanguage', 'text', array('required' => false))
->add('firstNameSecondLanguage', 'text', array('required' => false))
->add('birthDate', 'date', array('required' => false,
'widget' => 'single_text',
'format' => 'dd/MM/yyyy',
'attr' => array('class' => 'datepicker')
))
->add('birthPlace', 'text', array('required' => false))
->add('birthPlaceSecondLanguage', 'text', array('required' => false))
->add('gender', 'choice', array('choices' => array('' => 'Veuillez choisir', 'm' => 'Garçon', 'f' => 'Fille')))
->add('nationality', 'text', array('required' => false))
->add('homeLanguage', 'text', array('required' => false))
->add('bloodType', 'text', array('required' => false))
->add('familySituation', 'choice', array('required' => false,
'choices' => array(
'' => 'Veuillez choisir',
'm' => 'Mariés',
'd' => 'Divorcés',
'w' => 'Veuve',
'a' => 'Autre')))
->add('schoolStatusBefore', 'choice', array('required' => false, 'choices' => array('' => 'Veuillez choisir', 's' => 'Scolarisé', 'ns' => 'Non scolarisé')))
->add('remark', 'textarea', array('required' => false))
->add('responsibles', 'collection', array('type' => new ResponsibleType,
'prototype' => true,
'allow_add' => true,
'allow_delete' => true))
->add('authorizedPersons', 'collection', array('type' => new AuthorizedPersonType,
'prototype' => true,
'allow_add' => true,
'allow_delete' => true))
->add('transfers', 'collection', array('type' => new TransferType,
'prototype' => true,
'allow_add' => true,
'allow_delete' => true));
}
public function getName()
{
return 'student';
}
public function getDefaultOptions(array $options)
{
return array(
'data_class' => 'PS\PSchoolBundle\Entity\Student'
);
}
}
TransferType.php
<?php
// src/PS/PSchoolBundle/Form/TransferType.php
namespace PS\PSchoolBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilder;
use PS\PSchoolBundle\Entity\Transfer;
use Doctrine\ORM\EntityRepository;
class TransferType extends AbstractType
{
public function buildForm(FormBuilder $builder, array $options)
{
$builder
->add('reason', 'choice', array(
'choices' => array('success' => 'Réussite', 'failure' => 'Échec'),
'required' => false
))
->add('date', 'date', array(
'widget' => 'single_text',
'format' => 'dd/MM/yyyy',
'attr' => array('class' => 'datepicker')
))
->add('school', 'text', array('required' => false))
->add('classe', 'entity', array('class' => 'PSPSchoolBundle:Classe', 'property' => 'name'));
}
public function getName()
{
return 'transfer';
}
public function getDefaultOptions(array $options)
{
return array(
'data_class' => 'PS\PSchoolBundle\Entity\Transfer'
);
}
}
When I added the "classe" field to the TransferType, instead of showing the form, I get this error thrown :
Entities passed to the choice field must be managed 500 Internal
Server Error - FormException
Please note that I have tried TransferType and the form shows correctly with classe choice field populated. This problem only arises when I use the TransferType and the StudentType together.
Thanks
Edit - Below is the action of the controller that generates the form:
public function byIdEditAction($id)
{
$em = $this->getDoctrine()->getEntityManager();
if(!$student = $em->getRepository('PSPSchoolBundle:Student')->find($id))
{
throw $this->createNotFoundException('Student[id='.$id.'] does not exist.');
}
$form = $this->createForm(new StudentType(), $student);
$formHandler = new StudentHandler($form, $this->get('request'), $em);
if($formHandler->process())
{
$this->get('session')->setFlash('wehappy', "L'élève a été mis à jour.");
return $this->redirect($this->generateUrl('_studentsbyidshow', array('id' => $student->getId())));
}
return $this->render('PSPSchoolBundle:Student:edit.html.twig', array(
'form' => $form->createView(),
'student' => $student
));
}
My problem was actually linked to the fact that I'm using a StudentType that has an entity field (Transfer) which itself has an entity field (Classe).
The transfer object that was linked to the Student object did not have a Classe linked to it and thus I had that exception thrown complaining about the fact that the Classe object, that needs to be added to the Classes choice field was not managed. That means that it has to be managed by the entity manager. In other words, it had to be coming from the database.
There are two ways to fix this problem :
The obvious one was to fix the link that was missing on the database as that relation is set to not nullable on Doctrine.
The second way was to create a default Classe object and pull it from the data base, then assign it to the transfer like so :
if(!$classe = $em->getRepository('PSPSchoolBundle:Classe')->find(-2))
{
throw $this->createNotFoundException('Classe[id='.$id.'] does not exist.');
}
$transfer->setClasse($classe);
before actually creating the form using the StudentType...
Hope this helps somebody.

Categories