symfony form collection error bubbling not working as expected - php

I have 2 entities with form types :
User2Type.php is a sub form of Pca2Type.php.
If the form is not filled out properly, the errors from User2Type.php keep bubbling up to the "users" property of Pca2Type.php.
How can I get the errors so they appear next to their appropriate fields instead. I want the username, email, and password errors to appear next to their fields.
I will post the form types.
Pca2Type.php
namespace Homecare\HomecareBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
class Pca2Type extends AbstractType
{
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('firstName')
->add('lastName')
->add('umpi')
->add('agency', 'entity', array( 'class' => 'HomecareHomecareBundle:Agency', 'property' => 'agencyName', 'placeholder' => 'N/A' ) )
->add('create','submit', array(
'label' => 'Create Pca'
) )
;
$builder->add('users', 'collection', array('type' => new User4Type(), 'allow_add' => true, 'by_reference' => false, 'error_bubbling' => false ));
}
/**
* #param OptionsResolverInterface $resolver
*/
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Homecare\HomecareBundle\Entity\Pca',
'validation_groups' => array( 'adminCreatePca' ),
));
}
/**
* #return string
*/
public function getName()
{
return 'homecare_homecarebundle_pca';
}
}
User2Type.php
namespace Homecare\HomecareBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Doctrine\ORM\EntityRepository;
use Homecare\HomecareBundle\Entity\Recipient;
use Homecare\HomecareBundle\Entity\Pca;
use Homecare\HomecareBundle\Entity\User;
class User2Type extends AbstractType
{
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('firstName')
->add('lastName')
->add('username')
->add('email', 'email')
->add('password', 'password')
->add('agency', 'entity', array( 'class' => 'HomecareHomecareBundle:Agency', 'property' => 'agencyName', 'placeholder' => 'N/A' ) )
->add('save','submit')
;
}
/**
* #param OptionsResolverInterface $resolver
*/
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Homecare\HomecareBundle\Entity\User',
'validation_groups' => array( 'adminCreateAdmin', 'adminCreateAgency' )
));
}
/**
* #return string
*/
public function getName()
{
return 'homecare_homecarebundle_user2';
}
}

Related

Symony 3 Dynamic Forms and Doctrine

still strugling with a Symfony3 and Doctrine. Just trying to make simply autofilling form from database. I got 2 tables - countries and states.
countries.php
namespace AppBundle\Entity\Forms;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
/**
* #ORM\Entity
* #ORM\Table(name="countries")
*/
class Countries
{
/**
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\Column(type="string")
*/
private $country_code;
/**
* #ORM\Column(type="string")
*/
private $country_name;
public function __toString()
{
return $this->country_name;
}
/**
* #var Collection|States[]
*
* #ORM\OneToMany(targetEntity="AppBundle\Entity\Forms\States", mappedBy="country_code")
*/
protected $states;
public function __constructor()
{
$this->states = new ArrayCollection();
}
/**
* #return mixed
*/
public function getId()
{
return $this->id;
}
/**
* #return mixed
*/
public function getCountryCode()
{
return $this->country_code;
}
/**
* #param mixed $country_code
*/
public function setCountryCode($country_code)
{
$this->country_code = $country_code;
}
/**
* #return mixed
*/
public function getCountryName()
{
return $this->country_name;
}
/**
* #param mixed $country_name
*/
public function setCountryName($country_name)
{
$this->country_name = $country_name;
}
/**
* #return States[]|Collection
*/
public function getStates()
{
return $this->states;
}
/**
* #param States[]|Collection $states
* #return $this
*/
public function setStates($states)
{
$this->states = $states;
}
states.php
/**
* Created by PhpStorm.
* User: Alvydas Budrys
* Website: http://alvy.lt
* Date: 2017-02-07
* Time: 6:13 AM
*/
namespace AppBundle\Entity\Forms;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
* #ORM\Table(name="states")
*/
class States
{
/**
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\Column(type="string")
*/
private $name;
/**
*
* #ORM\ManyToOne(targetEntity="AppBundle\Entity\Forms\Countries", inversedBy="states")
* #ORM\JoinColumn(name="country_code", referencedColumnName="id", onDelete="CASCADE")
*/
private $country_code;
public function __toString()
{
return $this->name;
}
/**
* #return mixed
*/
public function getId()
{
return $this->id;
}
/**
* #return mixed
*/
public function getName()
{
return $this->name;
}
/**
* #param mixed $name
*/
public function setName($name)
{
$this->name = $name;
}
/**
* #return mixed
*/
public function getCountryCode()
{
return $this->country_code;
}
/**
* #param mixed $country_code
*/
public function setCountryCode($country_code)
{
$this->country_code = $country_code;
}
Also formfile:
namespace AppBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
use Symfony\Component\Form\Extension\Core\Type\RepeatedType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\FormInterface;
use AppBundle\Entity\Forms\States;
class UserType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('name', TextType::class,
array('label' => false,
'mapped'=>false,
'attr' => array(
'placeholder' => 'FirstName'
)))
->add('lastname', TextType::class,
array('label' => false,
'mapped'=>false,
'attr' => array(
'placeholder' => 'Lastname'
)))
->add('email', EmailType::class,
array('label' => false,
'mapped'=>false,
'attr' => array(
'placeholder' => 'Email'
)))
->add('plainPassword', RepeatedType::class, [
'type' => PasswordType::class,
'mapped'=>false,
'first_options' => ['label' => false,'mapped'=>false,'attr' => array(
'placeholder' => 'Password'
) ],
'second_options' => ['label' => false,'mapped'=>false, 'attr' => array(
'placeholder' => 'Confirm Password'
) ],
])
->add('accType',ChoiceType::class,
array(
'choices' => array(
'Personal' => '1',
'Business' => '2',),
'choices_as_values' => true,
'multiple'=>false,
'expanded'=>true,
'required' =>true,
'data' => true,
'mapped'=>false,
))
->add('city', TextType::class,
array('label' => false,
'mapped'=>false,
'attr' => array(
'placeholder' => 'City'
)))
->add('postcode', TextType::class,
array('label' => false,
'mapped'=>false,
'attr' => array(
'placeholder' => 'Postcode'
)))
->add('CountryName', EntityType::class, array(
'class' => 'AppBundle\Entity\Forms\Countries',
'label' => false,
//'mapped'=>false,
'choice_translation_domain' => true,
))
->add('companyName', TextType::class,
array('label' => false,
'mapped'=>false,
'attr' => array(
'placeholder' => 'Company Name'
)))
->add('companyNumber', TextType::class,
array('label' => false,
'mapped'=>false,
'attr' => array(
'placeholder' => 'Company Number'
)))
->add('companyVat', TextType::class,
array('label' => false,
'mapped'=>false,
'attr' => array(
'placeholder' => 'VAT'
)))
;
$formModifier = function (FormInterface $form, States $states = null) {
$positions = null === $states ? array() : $states->getStates();
$form->add('states', EntityType::class, array(
'class' => 'AppBundle\Entity\Forms\States',
'placeholder' => '',
'choices' => $positions,
));
};
$builder->addEventListener(
FormEvents::PRE_SET_DATA,
function (FormEvent $event) use ($formModifier) {
// this would be your entity, i.e. SportMeetup
$data = $event->getData();
$formModifier($event->getForm(), $data->getCountryName());
}
);
$builder->get('CountryName')->addEventListener(
FormEvents::POST_SUBMIT,
function (FormEvent $event) use ($formModifier) {
// It's important here to fetch $event->getForm()->getData(), as
// $event->getData() will get you the client data (that is, the ID)
$countries = $event->getForm()->getData();
// since we've added the listener to the child, we'll have to pass on
// the parent to the callback functions!
$formModifier($event->getForm()->getParent(), $countries);
}
);
}
}
but stil getting errors:
Type error: Argument 2 passed to AppBundle\Form\UserType::AppBundle\Form\{closure}() must be an instance of AppBundle\Entity\Forms\States, instance of AppBundle\Entity\Forms\Countries given, called in /var/www/hostera.dev/public_html/src/AppBundle/Form/UserType.php on line 139
Uncaught PHP Exception Symfony\Component\Debug\Exception\FatalThrowableError: "Type error: Argument 2 passed to AppBundle\Form\UserType::AppBundle\Form\{closure}() must be an instance of AppBundle\Entity\Forms\States, instance of AppBundle\Entity\Forms\Countries given, called in /var/www/hostera.dev/public_html/src/AppBundle/Form/UserType.php on line 139" at /var/www/hostera.dev/public_html/src/AppBundle/Form/UserType.php line 111
I think something bad with Doctrine Association, but I can't figure out what.

Pass File Validation Constraint to generic FileType entity

I'm creating a bundle which have a file reference object which has no constraints on itself because it will be a generic object. It might store images or any other type of file and I need to keep it as generic as possible.
Other bundle is using my FileType reference and I need to assign the file validation to this object through constraint. How would I force the file validation on the referenced file object?
The Generic FileType:
namespace ICC\FileCabinetBundle\Form;
use ICC\FileCabinetBundle\Entity\FileRef;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\FileType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
/**
* Comment form.
*/
class FileCabinetType extends AbstractType
{
/**
* {#inheritDoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('file', FileType::class, [
'label' => false,
'mapped' => false,
'required' => false
]
)
;
}
/**
* {#inheritDoc}
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => FileRef::class,
]);
}
}
The Entity that is calling my generic FileType, and I need it to validate this generic entity into image validation. Notice that my attempt of creating a constraint does not work there, but it would if I would insert it into my generic object.
namespace ICC\UserBundle\Form;
use ICC\UserBundle\Entity\User;
use ICC\FileCabinetBundle\Form\FileCabinetType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\Extension\Core\Type\DateType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Validator\Constraints\File;
/**
* User Profile form.
*/
class UserProfileType extends AbstractType
{
/**
* {#inheritDoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('fileRef', FileCabinetType::class, [
'attr' => ['class' => 'box__file'],
'label' => 'form.profile.edit.file_ref',
'required' => false,
'constraints' => [
new File([
'maxSize' => '2048k',
'mimeTypes' => [
'image/jpeg',
'image/png'
],
'mimeTypesMessage' => 'icc_filecabinet.file.mime'
])
]
])
->add('firstName', TextType::class, ['label' => 'form.profile.edit.first_name'])
->add('lastName', TextType::class, ['label' => 'form.profile.edit.last_name'])
->add('submit', SubmitType::class, ['label' => 'form.profile.edit.submit']);
}
/**
* {#inheritDoc}
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => User::class,
]);
}
}

Symfony Form Collection error

I have two entities that are connected to each other by doctrine association many-to-one. I created a form collection but when i try to save something it hits me with an error.
The error that i'm getting:
Expected argument of type "Zenith\SurveyBundle\Entity\SurveyOption", "array" given
This is my first form the one that loads the collection.
class TestType extends AbstractType
{
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('option', CollectionType::class, [
'entry_type' => SurveyOptionType::class,
'allow_add' => true,
'allow_delete' => true,
'entry_options' => [
'label' => false,
],
])
->add('submit', SubmitType::class, [
'label' => 'Salveaza',
])
;
}
/**
* #param OptionsResolver $resolver
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => SurveyManager::class
]);
}
}
This is the form loaded by collection:
class SurveyOptionType extends AbstractType
{
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('isEnabled', CheckboxType::class, [
'label' => 'Chestionar Activ',
])
->add('headquarter', EntityType::class, [
'class' => HeadQuarterManager::class,
'multiple' => false,
'expanded' => false,
])
->add('userNumber', IntegerType::class, [
'attr' => [
'min' => '1',
'type' => 'number',
],
'label' => 'Numar Utilizatori',
])
;
}
/**
* #param OptionsResolver $resolver
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => SurveyOption::class
));
}
}
My Controller action:
public function newAction($surveyId, Request $request)
{
$surveyOption = new SurveyOption();
$em = $this->getDoctrine()->getManager();
$surveyRepository = $em->getRepository(SurveyManager::class);
$survey = $surveyRepository->findOneBy(['id' => $surveyId]);
$form = $this->createForm(TestType::class, $survey);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
}
return [
'surveyOption' => $surveyOption,
'form' => $form->createView(),
];
}
The question is useless.. because i'm a hurry and overburned .. i didn't notice few mistakes.. the forms where fine .. :-)

setData with embedded EntityType not working

I have two pages and would like to use one uploadType. When I edit, show the name in the textfield. In NewsController I give the data.
$ EditForm ['upload'] ['filename'] -> setData ($ upload);
This is working. But when i will show the uploadPage and set the data in the uploadType.
'data' => $ build-> getData ()
so is the news textfield empty.
UploadType:
class UploadType extends AbstractType
{
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$data = $builder->getData();
if($this->isFieldEnabled('directory',$options)) {
$builder ->add('directory', null, array(
'label' => 'upload.directory',
'required' => true,
)
);
}
$builder->add('name', FileType::class,array(
'label' => 'upload.choice',
'data_class' => null,
'attr' => array(
'class' => 'hidden'
)
));
if($this->isFieldEnabled('filename',$options)) {
$builder->add('filename', 'text',array(
'label' => 'upload.upload',
'data' => $data, //If set, don't show in the news textfield
'mapped' => false,
));
}
}
/**
* #param OptionsResolver $resolver
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(
array(
'data_class' => 'Maiskolben\UploadBundle\Entity\Upload',
'translation_domain' => 'Maiskolben',
'disableFields' => [],
)
);
$resolver->setOptional([
'disableFields',
]);
}
private function isFieldEnabled($fieldName, $options)
{
if (isset($options['disableFields']) && !empty($options['disableFields'])) {
if (in_array($fieldName, $options['disableFields'])) {
return false;
}
}
return true;
}
}
NewsType:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('title', TextType::class,array(
'label' => 'news.newsTitle',
))
->add('content','textarea',array(
'label' => 'news.content',
))
->add('upload', new UploadType(), array(
'label' => false,
'required' => false,
'disableFields' => array(
'directory',
)
));
}
/**
* #param OptionsResolver $resolver
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Maiskolben\NewsBundle\Entity\News',
'translation_domain' => 'Maiskolben',
));
}
}
NewsController:
public function editAction(Request $request, News $news)
{
$upload = $news->getUpload();
$editForm = $this->createForm(new NewsType, $news);
$editForm['upload']['filename']->setData($upload);
$editForm->handleRequest($request);
if ($editForm->isSubmitted() && $editForm->isValid()) {
$em = $this->getDoctrine()->getManager();
//....
I tryed with "addEventListener" in both site. All the same result.
I hope anyone can help me. :)

Collection of entities (and textarea) in Symfony2

I have a very simple form (ModuleType.php) calling a collection (ModuleControleType.php).
This code works perfectly (add, modify and delete : no problem), but I want to customize the query for find Description (I just want to add a Where) in ModuleControleType.php.
I can do a query_builder with a field of type " Entity ", but not with a field " Collection " type.
ModuleType.php :
class ModuleType extends AbstractType
{
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('point', 'textarea', array(
'label' => 'Point(s) à observer',
'required' => false,
'attr' => array(
'rows' => 5
)
))
->add('controles', 'collection', array(
'label' => false,
'type' => new ModuleControleType(),
'allow_add' => true,
'allow_delete' => true,
'by_reference' => false
))
;
}
ModuleControleType.php :
class ModuleControleType extends AbstractType
{
use Description;
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('description', 'textarea', array(
'label' => 'Description',
'required' => false,
'attr' => array(
'rows' => $rows
)
))
;
}
/**
* #param OptionsResolverInterface $resolver
*/
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AdministrationBundle\Entity\ModuleControle',
'intention' => $this->getName() . '_token'
));
}
/**
* #return string
*/
public function getName()
{
return 'administration_module_controle_form';
}
}

Categories