Ok it is probably something simple but i just cant find where the problem is.
I have tried with but no match for my problem
I am trying to create from but from form class, not create form in controller..
here is the code..
this is from controller
/**
* #Route("login", name="login")
*/
public function loginAction (Request $request) {
$registration = new Registration();
$form = $this->createForm(LoginForm::class, $registration, array(
'method' => 'POST'
));
return $this->render(
'admin/login.html.twig',
array('form' => $form->createView())
);
}
Inside controller i used USE to defind LoginForm i use in part createForm, so that is not problem
this is from FORM class
<?php
namespace AppBundle\AppForm;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
class LoginForm extends AbstractType {
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('name')
->add('password')
->add('save', SubmitType::class);
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(
array(
'data_class' => 'AppBundle\Entity\Registration'
));
}
public function getName()
{
}
}
Your problem in Symfony version. You use code from Symfony3 while really have Symfony2.
Change SubmitType::class to submit, LoginForm::class to new LoginForm() and all will work fine.
Or you can update your Symfony version and all will work fine with your current code.
Related
I'm using Symfony 5.0.11 trying to render a form. For some reason on the $form->createView() call it throws the error 'Failed to start the session: already started by PHP.' It is only happening on this form, my other forms are working fine. Other routes in this class are working as well. Here's my code...
Controller method:
<?php
namespace App\Controller;
use App\Entity\Site;
use App\Form\SiteType;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
class SitesController extends AbstractController
{
/**
* #Route("/sites/add", name="app_sites_add")
*/
public function site_add(EntityManagerInterface $em, Request $request)
{
$form = $this->createForm(SiteType::class);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$site = $form->getData();
$em->persist($site);
$em->flush();
$this->addFlash('success', 'Site Successfully Added!');
return $this->redirectToRoute('sites');
} else {
return $this->render('sites/form.html.twig', ['siteForm' => $form->createView()]);
}
}
}
Form Method:
<?php
namespace App\Form;
use App\Entity\Site;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class SiteType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('name')
->add('url')
->add('type')
->add('is_active')
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => Site::class,
]);
}
}
Here's the trace:
/app/vendor/symfony/http-foundation/Session/Storage/NativeSessionStorage.php:148
/app/vendor/symfony/http-foundation/Session/Session.php:57
/app/vendor/symfony/security-csrf/TokenStorage/SessionTokenStorage.php:77
/app/vendor/symfony/security-csrf/CsrfTokenManager.php:72
/app/vendor/symfony/form/Extension/Csrf/Type/FormTypeCsrfExtension.php:77
/app/vendor/symfony/form/ResolvedFormType.php:168
/app/vendor/symfony/form/Extension/DataCollector/Proxy/ResolvedTypeDataCollectorProxy.php:111
/app/vendor/symfony/form/ResolvedFormType.php:161
/app/vendor/symfony/form/Extension/DataCollector/Proxy/ResolvedTypeDataCollectorProxy.php:111
/app/vendor/symfony/form/Form.php:1039
/app/src/Controller/SitesController.php:98
App\Controller\SitesController->site_edit(Site $id, EntityManagerInterface $em, Request $request) …
return $this->render('sites/form.html.twig', [
'siteForm' => $form->createView()
]);
}
/app/vendor/symfony/http-kernel/HttpKernel.php:157
/app/vendor/symfony/http-kernel/HttpKernel.php:79
/app/vendor/symfony/http-kernel/Kernel.php:191
/app/public/index.php:25
}```
Thanks for your help.
I found the issue. It was in the security configuration. I'm using the guard authenticator and I hadn't setup a firewall rule for these forms.
Firstly, let me admit that I am an amateur in symfony forms. Any help would be really appreciated. I am not allowed to share the actual code and hence I am using some example code to demonstrate the use case.
Given below is the use case,
I have an entity called testEntity,
class testEntity {
private $property1;
private $property2;
private $property3;
//with setters and getters
}
I have a form type called formType1,
class formType1 extends AbstractType {
public function buildForm(FormBuilderInterface $builder, array $options) {
$builder
->add('property2')
->add('property3)
;
}
public function buildView() {
// Code that create view vars
}
}
And I have a form type for testEntity,
class testEntityType extends AbstractType {
public function buildForm(FormBuilderInterface $builder, array $options) {
$builder->add('property1)
....
}
public function configureOptions(OptionsResolver $resolver) {
$resolver->setDefaults([
'data_class' => testEntity::class
]);
}
}
formType1 is a form type with out data class and with it's own template and will be used by itself. What I want to do is to re-use formType1 in testEntityType as formType1 has the fields that map to testEntity's properties so that when submitted I could get testEntity object with the form data and I can also get formType1's view in my final form.
Controller action has this,
$testEntity = new testEntity();
$form = $this->createForm(PostType::class, $testEntity);
so that when, the form submits I get $testEntity with the data from form
Apologies in advance, if I haven't framed the question well enough to be understood.
Got this working by doing this,
class testEntityType extends AbstractType {
public function buildForm(FormBuilderInterface $builder, array $options) {
$builder->add('property1')
->add('formType1', formType1::class, [
'mapped' => false,
'data' => $options['data']
])
....
}
public function configureOptions(OptionsResolver $resolver) {
$resolver->setDefaults([
'data_class' => testEntity::class
]);
}
}
Passed data via options and sett mapped to false.
In fact your formType1 is just a custom type.
So the only thing you have to do is to import your Type you want to use and add it in your builder just like you'll do with a non-custom Type (ChoiceType, TextType etc.).
use YourBundle\Type\formType1;
class testEntityType extends AbstractType {
public function buildForm(FormBuilderInterface $builder, array $options) {
$builder->add('property1')
->add('formType1', formType1::class, [
'data_class' => testEntity::class, //line edited
])
....
}
public function configureOptions(OptionsResolver $resolver) {
$resolver->setDefaults([
'data_class' => testEntity::class
]);
}
}
PS : Watch out about the naming convention of your classes
My RegistrationType class code:
<?php
namespace AppBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
/**
* Форма регистрации пользователя
*/
class RegistrationType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('adress');
$builder->add('mobileNumber');
}
public function getParent()
{
return 'FOS\UserBundle\Form\Type\RegistrationFormType';
}
public function getBlockPrefix()
{
return 'app_user_registration';
}
}
It give me standart form with added fields "adress" and "mobileNumber".
Where can I choose which standart fields I want to use?
What should I change to get only "adress" and "mobileNumber" fields?
Thank you!
If your question is "How to remove fields from a form" then:
Solution 1:
You can remove any field from a form with that builder method
$builder->remove('your_field_name')
Maybe you should also override the FOSUser controller to fill the mandatory fields of your user entity. It depends how you modify your user entity.
Solution 2:
Using Form Options
Take a look here https://knpuniversity.com/screencast/question-answer-day/remove-form-field
There is a very good article on this topic:
Overriding Default FOSUserBundle Forms
Have you defined your forma as a service via form.type tag? Have you told FOS about your form type in services.yml (via fos_user.registration.form key)?
This is my example of code, which I write with your advices. I hope it helps someone) Thanks to all!
<?php
namespace AppBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
/**
* Форма регистрации пользователя
*/
class RegistrationType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('address', null, [
'label' => 'Адрес дома',
'attr'=> [
'placeholder' => 'placeholder-text'
]
]);
$builder->add('mobileNumber', null, [
'label' => 'Мобильный телефон',
'attr'=> [
'placeholder' => '+7 (999) 123-45-67'
]
]);
$builder->add('username', null, [
'label' => 'ФИО',
'attr'=> [
'placeholder' => 'Иванов Иван Иванович'
]
]);
$builder->remove('email');
$builder->remove('plainPassword');
}
public function getParent()
{
// return 'fos_user_registration';
return 'FOS\UserBundle\Form\Type\RegistrationFormType';
}
public function getName()
{
return $this->getBlockPrefix();
}
public function getBlockPrefix()
{
return 'app_user_registration';
}
}
I have a Filter and FilterCollection object. The FilterCollection holds a collection of Filters, just like the name indicate.
Now I need to validate everything, so I created a FilterType and FilterTypeCollection Forms. In the FilterCollectionType I have:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('filters', CollectionType::class, array(
'entry_type' => FilterType::class
));
}
And in the FilterCollection definition I have the following:
/**
* #var array
* #Assert\Valid()
*/
private $filters = [];
I created a paramConverter so I could convert elements from my request into FilterCollection ones. In the apply method I try to validate everything by using:
public function apply(Request $request, ParamConverter $configuration)
$filterCollection = new FilterCollection();
$form = $this->formFactory->create(
FilterTypeCollection::class,
$filterCollection
);
$form->submit($request->query->all());
if ($form->isSubmitted() && $form->isValid()) {
$request->attributes->set($configuration->getName(), $filterCollection);
return true;
} else {
throw new FormValidationException($form);
}
}
I was expecting that the validation not only validates the FilterCollection but also the Filters. But the validations I have in my Filter definition, are not working, even if I have validations that should fail, it still passes. I think the validator is not passing on the Filter elements.
Any idea on what might be happening?
I finally got it to work. Perhaps you made the same mistake as me, forgetting to add "data_class" in the configureOptions in the formType.
Anyway, here's the code that works (on fresh install of Symfony 3.3)
DefaultController.php
<?php
namespace AppBundle\Controller;
use AppBundle\Entity\Filter;
use AppBundle\Entity\FilterCollection;
use AppBundle\Form\FilterCollectionType;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
class DefaultController extends Controller
{
/**
* #Route("/", name="homepage")
*/
public function indexAction(Request $request)
{
// add first filter, so we don't have to implement the collection javascript etc to test quickly
$collection = new FilterCollection();
$collection->filters[] = new Filter();
$form = $this->createForm(FilterCollectionType::class, $collection);
$form->handleRequest($request);
if ($form->isSubmitted()) {
if ($form->isValid()) {
echo "valid input"; // we don't want to see this ;)
}
}
// replace this example code with whatever you need
return $this->render('default/index.html.twig', [
'form' => $form->createView()
]);
}
}
Filter.php
<?php
namespace AppBundle\Entity;
use Symfony\Component\Validator\Constraints as Assert;
class Filter {
/**
* #var string
* #Assert\NotBlank()
* #Assert\Regex(pattern="/[0-9]+/")
*/
public $name;
}
FilterCollection.php
<?php
namespace AppBundle\Entity;
use Symfony\Component\Validator\Constraints as Assert;
class FilterCollection {
/**
* #var Filter[]
* #Assert\Valid()
*/
public $filters = [];
}
FilterType.php
<?php
namespace AppBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class FilterType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('name', TextType::class);
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => 'AppBundle\Entity\Filter'
]);
}
}
FilterCollectionType
<?php
namespace AppBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class FilterCollectionType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('filters', CollectionType::class, [
'entry_type' => FilterType::class,
]);
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => 'AppBundle\Entity\FilterCollection',
]);
}
public function getName()
{
return 'app_bundle_filter_collection_type';
}
}
Note: I didn't make a ParamConverter like you did, but that seems beside the point of the question. You can change the code to use a ParamConverter easily.
In refference to my question I asked a few hours ago, I will try to ask more specific question now.
I have followed guidelines from official cookbook, and this article.
I have added new class MyType extends AbstractType in Me\MyBundle\Controller\Form\Type direcory.
I have created a template for that custom field type.
I have added proper entry in config.yml in order to use new template in forms.
But how can I use that custom field?
Let's say I have controller which looks like this:
namespace Me\MyBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Me\MyBundle\Form\Type\MyType;
class DefaultController extends Controller
{
public function indexAction()
{
$form = $this->createFormBuilder()
->add('my_type', new MyType(), array('param' => 0))
->getForm()
;
return $this->render('MyBundle::index.html.twig', array(
'form' => $form->createView(),
));
}
}
Line ->add('my_type', new MyType(), array('param' => 0)) does not seem to have any affect on generating form. There is also no errors.
How can I make my custom field to be reused in the same form multiple times, with different params?
Edit:
MyType class looks like this:
class MyType extends AbstractType
{
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'param' => 1,
)
));
}
public function getParent()
{
return 'text';
}
public function getName()
{
return 'my_type';
}
}
May try to implements buildForm method :
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options
{
$builder->add(...);
}