My application show this error
Type error: Too few arguments to function AppBundle\Form\ActualiteType::__construct(), 0 passed in /Applications/MAMP/htdocs/SyndicNous/vendor/symfony/symfony/src/Symfony/Component/Form/FormRegistry.php on line 90 and exactly 2 expected
My formType
class ActualiteType extends AbstractType
{
/**
* #var bool $admin
*/
private $admin;
/**
* #var User $user
*/
private $user;
/**
* ActualiteType constructor.
* #param bool|false $admin
*/
public function __construct($admin = false, $user)
{
$this->admin = $admin;
$this->user = $user;
}
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$categories = array(
'Travaux' => 'Travaux',
'Voisinage' => 'Voisinage',
);
$builder
->add('title')
->add('category')
->add('content')
->add('datePublish')
->add('category', ChoiceType::class, array(
'choices' => $categories
)
);
if ($this->user->getResidence() != null) {
$builder->add('residence', EntityType::class, array(
'class' => 'AppBundle:Residence',
'choices' => $this->user->getResidence(),
));
} else {
$builder->add('residence', 'entity', array(
'class' => 'AppBundle:Residence',
'choice_label' => 'name'
));
};
}
/**
* #param OptionsResolver $resolver
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\Actualite'
));
}
/**
* {#inheritdoc}
*/
public function getBlockPrefix()
{
return 'appbundle_actualite';
}
}
Do you have any idea where the problem would come from? Thank you
I do not understand what you're trying to do. You do not need to use the constructor to pass parameters to your formType. There is the second parameter of the buildForm method for this ($options).
In your controller, create your form like this :
$form = $this->createForm(ActualiteType::class, $actualite, [
'admin' => $admin,
'user' => $user
]);
And modify your formType like that :
class ActualiteType extends AbstractType {
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$admin = $options['admin']; // Not used ?
$user = $options['user'];
$categories = array(
'Travaux' => 'Travaux',
'Voisinage' => 'Voisinage',
);
$builder->add('title')
->add('category')
->add('content')
->add('datePublish')
->add('category', ChoiceType::class, array(
'choices' => $categories
)
);
if ($user->getResidence() != null) {
$builder->add('residence', EntityType::class, array(
'class' => 'AppBundle:Residence',
'choices' => $user->getResidence(),
));
} else {
$builder->add('residence', 'entity', array(
'class' => 'AppBundle:Residence',
'choice_label' => 'name'
));
};
}
/**
* #param OptionsResolver $resolver
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\Actualite',
'admin' => null, // Default
'user' => null // Default
));
}
}
Do not forget to put the default values of your options in configureOptions method.
Related
I'm trying to create a form for the creation of a product in sylius. I want to add a collection of "PackItem".
However,only the last item is added and when I add "by_reference" => false I've got this issue
Could not determine access type for property "products".
This is my code
#ProductTypeExtension.php
public function buildForm(FormBuilderInterface $builder, array $options)
{
/** #var PackItem $packItem */
$packItem = new PackItem();
$packItem->setParent($builder->getData());
$builder
->add('products', CollectionType::class, [
'entry_type' => PackItemType::class,
'allow_add' => true,
'allow_delete' => true,
'entry_options' => [
'data' => $packItem
],
'by_reference' => false,
]);
}
/**
* {#inheritdoc}
*/
public function getExtendedType()
{
return ProductType::class;
}
PackItemType.php
#PackItemType.php
final class PackItemType extends AbstractType
{
/**
* {#inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('child', 'entity', [
'label' => 'winzana.ui.token',
'class' => Product::class,
'query_builder' => function(EntityRepository $er) {
$qr = $er->createQueryBuilder('t')
->leftJoin('t.products', 'p')
->having('COUNT(p.parent) = 0')
->groupBy('t.id')
->orderBy('t.code', 'ASC')
;
return $qr;
}
])
->add('quantity', IntegerType::class)
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => PackItem::class
]);
}
Product :
class Product extends BaseProduct
{
/**
* #ORM\OneToMany(targetEntity="XXXX\PackBundle\Entity\PackItem", mappedBy="parent", cascade={"persist"})
* #var ArrayCollection|PackItem $products
*/
private $products;
Thank you for your time
You can try to initialise your products in the __construct() method of your class product
public function __construct()
{
$this->products= new ArrayCollection();
}
if it does not correct the problem, then check if you set correctly the getProducts(), setProducts() and addProduct().
You can check this page for information,
http://symfony.com/doc/current/best_practices/business-logic.html#doctrine-mapping-information
regards.
The problem was solved by this change
/**
* #param ArrayCollection|PackItem[] $products
*/
public function setProducts($products)
{
$this->products = $products;
}
I don't use the setter so I didn't made it however by_references needs it.
Now I've got an other problem, only the last Item is saved.
I just recently updated to 2.8 and now I get the following error when calling the create function of the Form Factory.
Error: Class Symfony\Component\Form\Extension\Core\Type\FormType contains 1
abstract method and must therefore be declared abstract or implement the
remaining methods (Symfony\Component\Form\FormTypeInterface::setDefaultOptions)
The call of the FormFactory looks like this:
$this->formFactory->create(
get_class(new ProductType()),
$product,
[
'method' => 'POST',
'type' => $type,
'locales' => $context->shop->getLocales(),
'product' => $product,
'numberDataTransformer' => $this->numberTransformerFactory->createFromLocale(
$context->user->getLocale(),
$context->shop->getDefaultLocale()
),
'priceType' => $context->shop->getConfiguration()->getProductConfiguration()->getPricesBackend(),
'isShortDescriptionEnabled' => $context->shop->getConfiguration()->getProductConfiguration()->isShortDescriptionEnabled()
]);
I tried several ways to pass the ProductType to the function, but none seems to work. I always get one out of two results: Either the result is that the type cannot be found or the error is returned that the FormType does not implement setDefaultOptions.
What did I miss?
EDIT:
Here are some additional code:
The declaration of the formFactory parameter:
public function __construct(Request $request, FormFactoryInterface $formFactory)
{
$this->request = $request;
$this->formFactory = $formFactory;
}
The ProductType class
<?php
namespace CustomNamespace\BackendBundle\Product\Form;
use CustomNamespace\BackendBundle\Common\NumberDataTransformer;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use CustomNamespace\BackendBundle\Product\Form\ImageType;
use ShopwareEasy\BackendBundle\Product\Form\AttachmentType;
use Symfony\Component\Validator\Exception\InvalidOptionsException;
/**
* Form element type for products.
*/
class ProductType extends AbstractType
{
/**
* #var string
*/
private $method;
/**
* #var string
*/
private $type;
/**
* #var array
*/
private $locales;
/**
* #var Product
*/
private $product;
/**
* #var \CustomNamespace\BackendBundle\Common\NumberDataTransformer
*/
private $numberDataTransformer;
/**
* #var string
*/
private $priceType;
/**
* #var bool
*/
private $isShortDescriptionEnabled;
/**
* #param FormBuilderInterface $builder
* #param array $options
* #return void
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
parent::buildForm($builder, $options);
$builder->setMethod($this->method);
$regionType = new RegionShippingTimeType();
if ($this->type == 'download') {
$regionType->enableForDownloadableProduct();
}
$builder->add('regions', 'collection', array(
'type' => $regionType,
'label' => false,
'options' => array(
'required' => false,
'attr' => array('class' => 'email-box')
),
));
$builder->add('vendor', 'text', ['label' => 'form_product_vendor']);
if ($this->type == 'normal') {
$builder->add(
'mainVariant',
new MainVariantNormalType(
$this->method,
$this->locales,
$this->product,
$this->numberDataTransformer,
$this->priceType,
$this->isShortDescriptionEnabled
),
['error_bubbling' => false, 'label' => false]
);
} elseif ($this->type == 'download') {
$builder->add(
'mainVariant',
new MainVariantDownloadType(
$this->method,
$this->locales,
$this->product,
$this->numberDataTransformer,
$this->priceType,
$this->isShortDescriptionEnabled
),
['error_bubbling' => false, 'label' => false]
);
} elseif ($this->type == 'variant') {
$builder->add(
'mainVariant',
new MainVariantVariantType(
$this->method,
$this->locales,
$this->product,
$this->numberDataTransformer,
$this->priceType,
$this->isShortDescriptionEnabled
),
['error_bubbling' => false, 'label' => false]
);
}
if ($this->method == 'PUT') {
$builder->add(
'images',
new ImageType(),
['error_bubbling' => true, 'label' => false]
);
$builder->add(
'attachments',
new AttachmentType(),
['error_bubbling' => true, 'label' => false]
);
}
}
/**
* #param \Symfony\Component\OptionsResolver\OptionsResolverInterface $resolver
*/
public function configureOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(
array(
'data_class' => 'CustomNamespace\\BackendBundle\\Product\\Product',
'csrf_protection' => false,
'error_bubbling' => false,
'cascade_validation' => true,
'method' => 'POST',
'type' => 'normal'
)
);
parent::configureOptions($resolver);
}
public function setDefaultOptions(OptionsResolverInterface $resolver) {
/** #var OptionResolver $resolver */
$this->configureOptions($resolver);
}
public function getName() {
return get_class($this);
}
}
The problem was produced by files that were not updated at all.. The implementation of setDefaultOptions should still exist in the Symfony 2.8 classes - but they didn't.
After destroying my vagrant and recreating it again, everything worked just fine.
But thanks everyone for the help!
When I send my form I get :
An exception occurred while executing 'INSERT INTO Post (content, date_creation, date_modif, user_id, topic_id) VALUES (?, ?, ?, ?, ?)' with params ["<p>AA\/BB\/CC<\/p>", "2015-09-01 17:11:28", "2015-09-01 17:11:28", null, null]:
SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'user_id' cannot be null
Normal, cause I have a relationship mapping between several entities (Topic.php, Post.php and User.php)
PostType.php:
<?php
namespace BISSAP\ForumBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
class PostType extends AbstractType
{
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('content', 'ckeditor', array(
'label' => 'Votre message',
'config_name' => 'my_custom_config',
'config' => array('language' => 'fr')))
;
}
/**
* #param OptionsResolverInterface $resolver
*/
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'BISSAP\ForumBundle\Entity\Post'
));
}
/**
* #return string
*/
public function getName()
{
return 'bissap_forumbundle_post';
}
}
TopicType.php:
<?php
namespace BISSAP\ForumBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
class TopicType extends AbstractType
{
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('title', 'text', array(
'label' => 'Titre'))
->add('posts','collection', array( 'type' => new PostType(), 'label' => false, 'allow_add' => true,))
->add('save', 'submit', array(
'attr' => array(
'class' => 'btn right-flt')))
;
}
/**
* #param OptionsResolverInterface $resolver
*/
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'BISSAP\ForumBundle\Entity\Topic'
));
}
/**
* #return string
*/
public function getName()
{
return 'bissap_forumbundle_topic';
}
}
Part of my Controller that use form:
public function categoryAction(Request $request)
{
//Arguments recovery from url
$URL = $request->getPathInfo();
$element_URL = explode("/", $URL);
$catId = $element_URL[3];
(isset ($element_URL[4]))?$pageId = $element_URL[4]:$pageId = '1';
$em = $this->getDoctrine()->getManager();
//Pagination
$findListTopics = $em->getRepository('BISSAPForumBundle:Topic')->findByForum($catId);
$listTopics = $this->get('knp_paginator')
->paginate($findListTopics,$pageId/*page number*/,8/*limite per page*/)
//Form
$topic = new \BISSAP\ForumBundle\Entity\Topic();
$form = $this->createForm(new TopicType(), $topic);
$user = $this->getUser();
$forum = $em->getRepository('BISSAPForumBundle:Forum')->find(1);
print_r($form->getData());
if ($form->handleRequest($request)->isValid()) {
$topic->setUser($user);
$topic->setForum($forum);
$topic->setViewCount(23);
$topic->setContent("content a sup");
$topic->setReplyCount(123);
$topic->setLastPost(25);
$topic->setSlug('slug_sluggg');
$topic->setGenre('genre');
$em->persist($topic);
$em->flush();
$request->getSession()->getFlashBag()->add('notice', 'Sujet bien enregistrée.');
return $this->redirect($this->generateUrl('bissap_forum_topic', array('topic_id' => $topic->getId())));
//return $this->render('BISSAPForumBundle:F:topic-forum.html.twig', array('topicId' => $topic->getId(), 'user' => $user, 'topic' => $topic, 'firstDisplay' => true));
}
return $this->render('BISSAPForumBundle:F:category-forum.html.twig', array('listTopics' => $listTopics, 'catId' => $catId, 'form' => $form->createView(), 'user' => $user));
}
So, i would like to get to $post object to access the setTopic() and setUser() just before flush()...I thought to use $form->getData(), but I don't know how use it to get secondary object ($post).
When i submit the form two object are persisted, Topic and Post, sorry but i don't see the problem with the topic title..?!
I have a Timeslot functionality where the user has to be able to edit the start and end of each slot.
So I would like to create one form that contains alle timeslots. I based my code on this article in symfony docs: http://symfony.com/doc/current/cookbook/form/form_collections.html
The problem is that in this article, there's some kind of parent entity to which the collection instances should be assigned to. In my case, the timeslots are standalone and do not have a relation with another entity (that is relevent at this stage).
So.. my question: How do I create a collection of forms with my timeslots?
Controller.php
/**
* #Route("/settings", name="settings")
* #Template()
*/
public function settingsAction()
{
$timeslots = $this->getDoctrine()->getRepository("ScheduleBundle:Timeslot")->findAll();
$timeslots_form = $this->createFormBuilder()
->add('timeslots', 'collection', array(
'type' => new TimeslotType(),
))
->add('save', 'submit')
->getForm();
return array(
'timeslots' => $timeslots_form->createView()
);
}
TimeslotType.php:
class TimeslotType extends AbstractType
{
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('start', 'time', array(
'input' => 'datetime',
'widget' => 'choice',
))
->add('end', 'time', array(
'input' => 'datetime',
'widget' => 'choice',
))
;
}
/**
* #param OptionsResolverInterface $resolver
*/
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Oggi\ScheduleBundle\Entity\Timeslot'
));
}
/**
* #return string
*/
public function getName()
{
return 'timeslot';
}
}
Any thoughts?
thanks in advance!
Pass an array instead of an entity to your form. The form can process either just fine.
$timeslots = $this->getDoctrine()->getRepository("ScheduleBundle:Timeslot")->findAll();
$formData = array('timeslots' => $timeslots);
$timeslots_form = $this->createFormBuilder($formData) ...
I've been stuck on this for quite some time now. I read quite some answers here on SO but I couldn't get it running.
My controller contains
$series = $this->getDoctrine()->getRepository('DemoDemoBundle:Series')->createQueryBuilder('series')
->where('series.type = 1')
->getQuery()->getResult();
$magazine = new Magazine();
$content = array(
'series' => $series
);
$form = $this->createForm(new MagazineType($this->get('translator'), $content), $magazine);
$form->handleRequest($request);
I would like to pass the variable $content to the form so that 'series' can be used in some selectboxes. MagazineType extends PublicationType. The same goes for the underlying entities. Here's how MagazineType looks:
class MagazineType extends PublicationType
{
function __construct($translator, array $series = null)
{
parent::__construct($translator, $series); //$series);
}
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
// TODO: Refactor constant out
parent::buildForm($builder, $options)
// ->add('dateSubmitted')
// ->add('userSubmitted')
// ->add('file')
->add('issueNumber')
->add('save', 'submit');
}
/**
* #param OptionsResolverInterface $resolver
*/
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(
array(
'data_class' => 'Demo\DemoBundle\Entity\Magazine',
'series' => $this->translator->trans('addPublication.noSeries')
)
);
}
and PublicationType
class PublicationType extends AbstractType
{
protected $series, $translator;
public function __construct($translator, $series)
{
$this->translator = $translator;
$this->series = $series;
}
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options){
$builder
->add('name', 'text', array(
'label' => $this->translator->trans('addPublication.name')
))
// ->add('dateSubmitted')
// ->add('userSubmitted')
// ->add('file')
->add('series', 'choice', $this->series);//$formOptions['series']);
;
return $builder;
}
/**
* #param OptionsResolverInterface $resolver
*/
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Demo\DemoBundle\Entity\Publication',
'series' => $this->translator->trans('addPublication.noSeries')
));
}
Maybe I'm accessing the series variable the wrong way, but I'm not even getting any further than constructing MagazineType (option series not allowed) even though I've set it in DefaultOptions as stated on http://symfony.com/doc/current/components/options_resolver.html#configure-allowed-types. I'm probably missing something here though similar questions, since I'm stuck on this the entire day.
Thx for any help!