Symfony2 - QueryBuilder error message - php

So, I'm going to try and explain the problem I have here :)
Catchable Fatal Error: Argument 1 passed to AppBundle\Controller\MunkakController::AppBundle\Controller{closure}() must be an instance of AppBundle\Controller\EntityRepository, instance of Doctrine\ORM\EntityRepository given
This is the error message I get. This is the code that I try to run:
$formbe = $this->createFormBuilder($ujbeszab, ['attr' => ['id' => 'ujbeszabid']])
->setAction($this->generateUrl('uj-beszab', array('szabid' => $szabid)))
->setMethod('POST')
->add('munkatipusok', 'entity', array('class' => 'AppBundle:Munkatipusok', 'query_builder' => function(EntityRepository $rep) {
$qb = $rep->createQueryBuilder('u');
return $qb->orderBy('u.munkatipusok', 'ASC');
}, 'empty_value' => null, 'label' => "Munkatípus", 'required' => false))
->add('idopont', 'date', array('label' => "Időpontja", 'format' => 'yyyy.MM.dd', 'years' => range(date('Y') -10, date('Y') +10), 'required' => true))
->add('megjegyzes', 'textarea', array('label' => "Megjegyzés", 'required' => false))
->add('submit', 'submit', array('label' => 'Létrehozás'))
->getForm();
It has some Hungarian variable names, basicly I'm trying to add a job to a database. You have to select the job type from a dropdown, enter the date('idopont'), you can also add a comment('megjegyzes'). The job types come from a different table, they come from the 'munkatipusok' table. So, what i'm trying to do is to be able to filter the shown jobs. I know I could show all the job types and then remove them from the select field with javascript, but that is risky, in case jscript doesn't run on the computer. So I want to filter server side, with a QueryBuilder.

Related

Nested CollectionType Save Entity in ArrayCollection

i want to store some data
class Offer
{
/**
* #ORM\Column(type="array")
*/
private $meterPoints;
public function __construct()
{
$this->meterPoints = new ArrayCollection();
}
}
for an offer as a CollectionType.
class OfferType extends AbstractType
{
$builder
->add('meterPoints', CollectionType::class, array(
'entry_type' => OfferMeterPointType::class,
'allow_add' => true,
'allow_delete' => true,
'prototype' => true,
'prototype_name' => '__mp_name__',
))
}
In the OfferMeterPointType I also have an EntityType
class OfferMeterPointType extends AbstractType
{
$builder
->add('meterPoint', EntityType::class, array(
'attr' => array(
'class' => 'chosen-select'
),
'class' => 'AppBundle:MeterPoint',
'choice_label' => 'meterPoint',
))
->add('billData', CollectionType::class, array(
'label' => false,
'entry_type' => OfferBillType::class,
'allow_add' => true,
'allow_delete' => true,
'entry_options' => array(
'label' => false
)
));
}
Now when I persist that entity the whole AppBundle:MeterPoint object get serialized and not just the id. I kind of understand why doctrine does that but can I change it such that just the id will be stored?
Also when I want to edit an Offer
$offer = $em->getRepository('AppBundle:Offer')->findOneById(2);
$form = $this->createForm(OfferType::class, $offer);
i get an Exception
Entities passed to the choice field must be managed. Maybe persist them in the entity manager?
I guess a solution would be to create an Entity for the OfferMeterPointType but I don't really want to do that. Because I allmost never need that data.
Update
I tried like martin suggested. now the exception is gone but it still saves the complete object
$meterPoints = $this->em->getRepository('AppBundle:MeterPoint')->findAll();
//dump($meterPoints);
$builder
->add('meterPoint', ChoiceType::class, array(
'label' => 'offerMeterPoint.meterPoint',
'attr' => array(
'class' => 'chosen-selesct',
'placeholder' => 'ob.to'
),
'choices' => $meterPoints,
'choice_label' => function($meterPoint) {
return $meterPoint->getMeterPoint();
},
'choice_value' => function($meterPoint) {
if($meterPoint === null){
return null;
}
dump($meterPoint);
return $meterPoint->getId();
},
'placeholder' => 'global.plz_select'
))
Update 2
Got it working
changed the ChoiceType
$meterPoints = $this->em->getRepository('AppBundle:MeterPoint')->findAll();
$mps = array();
foreach($meterPoints as $mp){
$mps [$mp->getMeterPoint()] = $mp->getId();
}
//dump($meterPoints);
$builder
->add('meterPoint', ChoiceType::class, array(
'label' => 'offerMeterPoint.meterPoint',
'attr' => array(
'class' => 'chosen-selesct',
'placeholder' => 'ob.to'
),
'choices' => $mps,
'placeholder' => 'global.plz_select'
))
You get a object serialized because your column type is array and EntityType automatically replaces choice values with objects.
There's however choice_value that accepts also a callable so I'd try fiddling with it and maybe you can get it to return just the id (maybe force string type?).
If this doesn't help then probably use just ChoiceType and handle the logic yourself.
This happens because Doctrine automatically deserializes the objects from $meterPoints that you try to use as entities with EntityType. These objects are obviously not managed by the Doctrine Entity manager. Thus the error.
I think you'll have to convert the $meterPoints to database entities before using $this->createForm(...) yourselves if you want to avoid creating more relations. Eventually and maybe even easier approach would be writing a custom Doctrine type that could do this for you:
http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/cookbook/custom-mapping-types.html

Adding a default value along with entity in form type of Symfony2

I am a totally new in symfony2. I met a situation which I can't solve till now.
I have a controller, formtype and eventsubscriber in my project. The form builds by binding the entities. In that case for a particular entity I need to add a default value along with an ID in one of the form fields. My form type is
$builder->add('breed', EntityType::class, array(
'label' => 'Breed',
'class' => 'AppBundle:Masters\Breed',
'placeholder' => '----Select Breed----',
'query_builder' => function (EntityRepository $er) {
return $er->createQueryBuilder('b')
->orderBy('b.sortOrder', 'DESC');
},
'choice_label' => 'breed',
));
$builder->addEventSubscriber(new BreedSubscriber($factory));
My Event Subscriber is
private function addBreed($form, $breedmasterId) {
$form->add($this->factory->createNamed('breed',EntityType::class,null, array(
'class' => 'AppBundle:Masters\Breed',
'placeholder' => '----Select Breed--------',
'choice_label' => 'breed',
'required' => TRUE,
'mapped' => false,
'query_builder' => function (EntityRepository $repository) use ($breedmasterId) {
$qb = $repository->createQueryBuilder('bm')
->where('bm.breed = :breedmasterId')
->setParameter('breedmasterId', $breedmasterId);
return $qb;
},
'auto_initialize' => false
)));
}
I need to add a default value such as "General" along with an "id" in the addBreed subscriber and it need to be validate on formsubmission. Thanks in advance for the help.
You can add the following 'data' key in the array you configure your form:
$builder->add('breed',null, array(
'label' => 'Breed',
'data' => 'Sih Tzu'
))

Access properties and methods of a class while configuring EntityType in Formbuilder::add()

I`ve got a dropdown list in my Symfony2 form like this:
$builder->add('categories','entity', array(
'class' => 'MyBundle:Myentity',
'property' => 'name',
'label' => 'Mylabel',
'expanded' => false,
'multiple' => false,
'label_attr' => array ( 'class' => 'control-label' ),
'attr' => array ( 'class' => 'form-control',
'placeholder' => 'Placeholder',
'title' => "Mytitle",
'data-toggle' => 'tooltip',
'data-myidfromDB' => '????',
'data-mynamefromDB'=>'????' etc. )));
So I am getting a list of MyBundle:Myentity objects and when I choose one I want to show all its properties (like ID, name, etc.) which are stored in my DB and described in Entity class, in different html data-* fields. If I select another one from the list I want to see all information related to my newly selected option in HTML (to change dynamically). Any ideas how to do that?
Since Symfony 2.7 you can set the option choice_attr to ChoiceType and set it a callable receiving the choice as an argument.
EntityType inherits this option and the choice in that case is the instantiated entity, so you can write something like :
$builder->add('categories','entity', array(
'class' => 'MyBundle:MyEntity',
'property' => 'name',
'label' => 'Mylabel',
'attr' => array('class' => 'form-control'),
'label_attr' => array('class' => 'control-label'),
'choice_attr' => function (\AppBundle\Entity\MyEntity $myEntity) {
return array(
'data-private-property' => $entity->getPrivateProperty(),
'data-some-value' => $entity->someMethod(),
);
},
);
You can't do that in easy way.
But you can put more information in select label.
Look on
http://symfony.com/doc/current/reference/forms/types/entity.html#choice-label
Yout can put here more field details and get it from your javascript.

Symfony2 Form field Entity with 170k of results

I have a form with a field of relationship entity.
The problem is that that entity tien a lot of records, over 170,000 and render the view form the server is saturated and no load.
What solutions are there to this?
This is the form field
->add('stream', 'genemu_jqueryselect2_entity', array(
'class' => 'AcmeBundle:Stream',
'property' => 'name',
'choice_label' => 'name',
'multiple' => false,
'required' => false,
'configs' => array(
'multiple' => false,
)
)
)
IMPORTANT
I found something.
Stream entity is related to another entity under a bidirectional one-to-one.
Doctrine is running a query for each record to grab the data from that relationship.
Is there any way to tell Doctrine to not spread relationships and take "real" data Stream entity?
If I correctly understand you, you shoud look to query_builder options what allow you to fetch Streams what sutisfy some condition. E.g.:
->add('stream', 'genemu_jqueryselect2_entity', array(
'class' => 'AcmeBundle:Stream',
'property' => 'name',
'choice_label' => 'name',
'multiple' => false,
'required' => false,
'configs' => array(
'multiple' => false,
)
'query_builder' => function (StreamRepository $repository) {
return $repository->findStreamsWhatSatisfySomeCondition();
}
)
you can use external parameters like:
'query_builder' => function (StreamRepository $repository) use ($param) {
}
Detailed info you can find in doc. Hope that will help find solution :)

Force Uppercase on Symfony2 form text field

I've inherited a Symfony2 project that has a form built as such:
$builder
->add('Status', 'choice', array(
'choices' => array('' => '', 'PASS' => 'PASS', 'FAIL' => 'FAIL', 'INCOMPLETE' => 'INCOMPLETE', 'DROPPED' => 'DROPPED',),
'required' => FALSE,
))
->add('First_Name', 'text', array('label'=>'First Name',
'required' => FALSE))
->add('Last_Name', 'text', array('label'=>'Last Name',
'required' => FALSE))
->add('PID', 'text', array('label'=>'License Number',
'required' => FALSE))
;
I need to have any letters entered in the PID field to be forced to uppercase. However I cannot find a option/attribute/... to do this.
Is there any way to do this?
If you use bootstrap this should work:
$builder
->add('Status', 'choice', array( 'choices' => array('' => '', 'PASS' => 'PASS', 'FAIL' => 'FAIL', 'INCOMPLETE' => 'INCOMPLETE', 'DROPPED' => 'DROPPED',),
'required' => FALSE,
'attr' => array( 'class' => 'text-uppercase' ),
))
I’m not sure if you ask for server-side validation or assistance for client-side uppercase input. In case of the latter: you could add a CSS class or a data-* attribute (something like ->add('PID', 'text', ['label'=>'License Number', 'required' => FALSE, 'attr' => ['data-behavior' => 'uppercase']])) to the PID element. Then, you could add a JavaScript event handler in the form (preferably using jQuery or some other framework) to automatically convert lowercase to uppercase letters on blur/change. (I would prefer the data-* attribute, as this has nothing to do with CSS.)
To enforce that on the server-side, you could use a #Assert\Regex annotation.

Categories