Complex query in Symfony2 form using query builder - symfony

I'm trying to build some kind of complex query using Doctrine Query Builder to use them in a Form Type, see below what I have done:
public function buildForm(FormBuilderInterface $builder, array $options) {
$builder
->add('category', 'entity', array(
'class' => 'CategoryBundle:Category',
'property' => 'name',
'required' => false,
'multiple' => true,
'expanded' => false,
'query_builder' => function(EntityRepository $er) {
$qb = $er->createQueryBuilder('c')
->where($qb->expr()->eq('c.parent', '?1'), $qb->expr()->isNull('c.parent'))
->setParameter(1, 0);
}
))
->add('detail_group', 'entity', array('class' => 'ProductBundle:DetailGroup', 'property' => 'name', 'required' => false, 'multiple' => true, 'expanded' => false))
->add('parent', 'entity', array('class' => 'ProductBundle:ProductDetail', 'property' => 'label', 'required' => false))
->add('label')
->add('field_type', 'choice', ['choices' => \ProductBundle\DBAL\Types\FieldType::getChoices()])
->add('values_text', 'collection', array('type' => 'text', 'allow_add' => true, 'allow_delete' => true, 'by_reference' => false))
->add('description', 'text', array('required' => false))
->add('measure_unit', 'text', array('required' => false))
->add('status', 'choice', ['choices' => \ProductBundle\DBAL\Types\StatusType::getChoices()])
->add('to_product', 'checkbox', array('label' => 'Detalle de Stock?', 'required' => false));
}
I need to get in that query all the rows from category table with parent=NULL or parent=0 but it's not working since I get this error:
FatalErrorException: Error: Call to a member function expr() on a
non-object in
/var/www/html/src/ProductBundle/Form/ProductDetailType.php line
22
What I'm doing wrong?

It's because $qb doesn't exists.
$qb = $er->createQueryBuilder('c');
$qb->where($qb->expr()->eq('c.parent', '?1'), $qb->expr()->isNull('c.parent'))
->setParameter(1, 0);

Related

How to getData() on a collectionType field - Symfony 4

I have a collectionType (Equipements) on a Symfony 4 ORM form (intervention).
For example, this equipement field :
<input type="file" id="intervention_equipements_0_photoGraffiti" name="intervention[equipements][0][photoGraffiti]">
I try to get the data of this field with :
$fileToTransfer = $form['intervention_equipements_0_photoGraffiti']->getData();
or
$fileToTransfer = $form['intervention[equipements][0][photoGraffiti]']->getData();
I have the error Child "intervention[equipements][0][photoGraffiti]" does not exist.
Here is my intervention Type :
$builder
->add('idInstallation', EntityType::class, [
'class' => Installation::class,
'choice_label' => 'numeroInstallation',
'required' => false,
])
->add('equipements', CollectionType::class, array(
'entry_type' => EquipementInterventionType::class,
'entry_options' => array('label' => false),
))
And the equipement entity:
$builder
->add('nom', TextType::class, array(
'error_bubbling' => true,
'required' => false,
'disabled' => true
))
->add('numero', TextType::class, array(
'error_bubbling' => true,
'required' => false,
'disabled' => true
))
->add('etatEquipement', ChoiceType::class, array(
'choices' => $choices_controle,
'expanded' => false,
'multiple' => false,
'required' => false,
'error_bubbling' => true,
))
->add('photoEquipement', FileType::class, array(
'error_bubbling' => true,
'required' => false,
'disabled' => false,
'data_class' => null
))
->add('graffiti', CheckboxType::class, array(
'required' => false,
'error_bubbling' => true,
))
->add('photoGraffiti', FileType::class, array(
'error_bubbling' => true,
'required' => false,
'disabled' => false,
'data_class' => null
))
...
How can I fix this, please ?
Directly use $form->getData(). This will return the array with all your form datas that you are looking for.
in your form controller
$equipements = $intervention->getEquipement();
will return the array of collections then
foreach ($equipements as $equipement) {
$fileToTransfer = $equipement->getPhotoGraffiti()
}
Hope you have getter and setter in your entity class

Symfony query builder with post submit data is not changing the values in EventListener

I have a filter form which is filtering for markets, types and airlines. When submitted, I'd like another dropdown (documentlist) to be filtered after the selected values. Therefore I created a post_submit eventlistener which is working (I dumped the values as you can see in the following code). But when then trying to update the documentlist values through a query builder and with the data from my filters, it's not working. Any ideas:
<?php
namespace DocumentBundle\Form\Document;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Doctrine\ORM;
use Doctrine\ORM\EntityRepository;
use Symfony\Bundle\FrameworkBundle\Controller;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use DocumentBundle\Form\Document\DocumentFilterType;
class DocumentDeactivationType extends DocumentFilterType {
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('type', 'choice', array('choices' => array(
'document_types.contract' => 1,
'document_types.general'=>2,
'document_types.goodwill_policy'=>3,
'document_types.pricesheet'=>4,
'document_types.yq_update'=>5,
'document_types.contract_addendum'=>6),
'choices_as_values' => true, 'label' => 'label.types',
'expanded' => false, 'multiple' => true,
'label' => 'label.type', 'required' => false,
'translation_domain' => 'Documents'))
->add('airlines', 'entity', array(
'class' => 'AppBundle:Airline', 'property' => 'id',
'query_builder' => function (EntityRepository $er){
return $er->createQueryBuilder('a')
->addOrderBy('a.id', 'ASC');
},
'choice_value' => 'id',
'choice_label' => 'id', 'label' => 'label.airlines',
'expanded' => false, 'multiple' => true, 'required' => false,
'translation_domain' => 'Documents'))
->add('markets', 'entity', array(
'class' => 'AppBundle:Market', 'property' => 'id',
'query_builder' => function (EntityRepository $er){
return $er->createQueryBuilder('m')
->addOrderBy('m.id', 'ASC');
},
'choice_value' => 'id',
'choice_label' => 'id', 'label' => 'label.markets',
'expanded' => false, 'multiple' => true, 'required' => false,
'translation_domain' => 'Documents'))
->add('documentlist', EntityType::class, array(
'class' => 'DocumentBundle:Document',
'property' => 'name',
'expanded' => false, 'multiple' => true,
'label' => 'label.document_list',
'empty_value' => "Select document",
'required' => false,
'mapped' => false,
'translation_domain' => 'Documents'));
$builder->addEventListener(FormEvents::POST_SUBMIT, function (FormEvent $event) use ($builder)
{
$form = $event->getForm();
$data = $event->getData();
$markets = $data['markets'];
$type = $data['type'];
$airlines = $data['airlines'];
dump($markets, $type);
$builder
->add('documentlist', EntityType::class, array(
'class' => 'DocumentBundle:Document',
'property' => 'name',
'expanded' => false, 'multiple' => true,
'label' => 'label.document_list',
'empty_value' => "Select document",
'required' => false,
'mapped' => false,
'translation_domain' => 'Documents',
'query_builder' => function (EntityRepository $er) use ($markets, $type, $airlines){
return $er->createQueryBuilder('e')
->where('e.markets = :markets')
->andWhere('e.airlines IN (:airlines)')
->andWhere('e.products IN (:products)')
->setParameter('e.markets', $markets)
->setParameter('e.airlines', $airlines)
->setParameter('e.type', $type);
},
));
});
}
public function getName()
{
return 'document_deactivation';
}
}
You cannot change the form (add or remove fields) in a POST_SUBMIT event. But you can in a PRE_SUBMIT event, so you just need to change POST_SUBMIT with PRE_SUBMIT.
But be careful because your form data won't be normalized in PRE_SUBMIT, so you will have to work with raw data from your form (an array), or to normalize manually your data.

[sonataAdmin]: test the select imput value

I want to retrieve the value of select input and make the test on this value. If this value corresponds to what I am looking for in my case "freelance" I display a block if no I display another
this is my code:
$emr = $this->modelManager->getEntityManager('PivotalBOBundle:Role');
$queryr = $kernel->getContainer()->get('doctrine')->getRepository('PivotalBOBundle:Role')->findAll();
$choises=array();
foreach ($queryr as $res){
$choises[$res->getRole()]=$res->getRole();
}
->tab('Spécifique')
->with('Type d\'utilisateur', array('class' => 'col-md-12'))
->add('type', 'choice', array('label' => 'Type',
'choices' => $choises))
->end()
->with('Freelancer', array('class' => 'col-md-12 Freelancer'))
->add('type', 'checkbox', array('required' => false, 'label' => 'Freelancer'))
->add('categories', 'sonata_type_model', array(
"multiple" => true,
'label' => 'Catégorie',
'required' => true,
'query' => $query))
->add('outilsEtTechnologie', 'sonata_type_model', array(
'required' => false,
"multiple" => true,
'label' => 'Outils et Technologie'))
->add('niveauCompetences', 'sonata_type_collection', array(
'required' => false,
'label' => 'Niveau des compétences',
'by_reference' => true), array(
'edit' => 'inline',
'inline' => 'table'
))
->add('niveauLangue', 'sonata_type_collection', array(
'required' => false,
'label' => 'Niveau des langues',
'by_reference' => false), array(
'edit' => 'inline',
'inline' => 'table'
))
->add('formation', 'sonata_type_collection', array(
'required' => false,
'label' => 'Formations',
'by_reference' => false), array(
'edit' => 'inline',
'inline' => 'table'
))
->add('mobilite', 'entity', array(
'class' => 'Pivotal\BOBundle\Entity\Mobilite',
'required' => true,
'label' => 'Mobilite'
))
->add('frequence', 'entity', array(
'class' => 'Pivotal\BOBundle\Entity\Frequence',
'required' => true,
'label' => 'Frequence'
))
->add('niveauExperience', 'entity', array(
'class' => 'Pivotal\BOBundle\Entity\NiveauExperience',
'required' => true,
'label' => 'Niveau Experience'))
->add('missionetranger', 'entity', array(
'class' => 'Pivotal\BOBundle\Entity\Missionetranger',
'required' => true,
'label' => 'Mission Etranger'))
->add('note', null, array('label' => 'Note'))
->end()
->with('Jobowner ', array('class' => 'col-md-12 Jobowner'))
->add('type', 'checkbox', array('required' => false, 'label' => 'Jobowner'))
->add('societe', 'entity', array(
'class' => 'Pivotal\BOBundle\Entity\Societe',
'property' => 'nom',
'label' => 'Societe',
'required' => false,
))
->end();
this is an image of my render the case 1
and this is my objectif :
the freelancer option
the jobowner option
You can access the current subject with $this->getSubject().
So you could modify your Form by using:
$subject = $this->getSubject();
// with "Type d'utilisateur"
if ($subject && $subject->getType() === 'freelance') {
// with "Freelancer"
}
// other tabs/form-fields
This only works if you gonna re-open your form view. If you need to instantly modify your form if you select "freelance" without reloading the page, you need to write it in Javascript. Depending on your needs, this varies a lot (e.g. hiding the tab/with-section and show it via Javascript).
to do this we should use a java script code like this :
->tab('Spécifique')
->with('Type d\'utilisateur', array('class' => 'col-md-12'))
->add('type', 'choice', array('label' => 'Type',
'choices' => $choises))
->end()
->with('Freelancer', array('class' => 'col-md-12 userFreelancer'))
->add('categories', 'sonata_type_model', array(
"multiple" => true,
'label' => 'Catégorie',
'required' => true,
'query' => $query))
->add('outilsEtTechnologie', 'sonata_type_model', array(
'required' => false,
"multiple" => true,
'label' => 'Outils et Technologie'))
->add('niveauCompetences', 'sonata_type_collection', array(
'required' => false,
'label' => 'Niveau des compétences',
'by_reference' => true), array(
'edit' => 'inline',
'inline' => 'table'
))
->add('niveauLangue', 'sonata_type_collection', array(
'required' => false,
'label' => 'Niveau des langues',
'by_reference' => false), array(
'edit' => 'inline',
'inline' => 'table'
))
->add('formation', 'sonata_type_collection', array(
'required' => false,
'label' => 'Formations',
'by_reference' => false), array(
'edit' => 'inline',
'inline' => 'table'
))
->add('mobilite', 'entity', array(
'class' => 'Pivotal\BOBundle\Entity\Mobilite',
'required' => true,
'label' => 'Mobilite'
))
->add('frequence', 'entity', array(
'class' => 'Pivotal\BOBundle\Entity\Frequence',
'required' => true,
'label' => 'Frequence'
))
->add('niveauExperience', 'entity', array(
'class' => 'Pivotal\BOBundle\Entity\NiveauExperience',
'required' => true,
'label' => 'Niveau Experience'))
->add('missionetranger', 'entity', array(
'class' => 'Pivotal\BOBundle\Entity\Missionetranger',
'required' => true,
'label' => 'Mission Etranger'))
->add('note', null, array('label' => 'Note'))
->end();
$formMapper->with('Societe', array('class' => 'col-md-12 Societe'))
->add('societe', 'entity', array(
'class' => 'Pivotal\BOBundle\Entity\Societe',
'property' => 'nom',
'label' => 'Societe',
'required' => false,
))
->end()
->end();
and we should overide the template
like that :
public function getTemplate($name)
{
if ($name == "edit") {
return 'admin/edit.html.twig';
}
return parent::getTemplate($name);
}
and add a javascript code in edit.html.twig :
<script type="text/javascript">
$(document).ready(function () {
var type = $("#{{ admin.uniqId }}_type");
var freelancer = $(".userFreelancer");
var jobowner = $(".userJobowner");
var redacteur = $(".userRedacteur");
var Supperjobowner = $(".userSupperjobowner");
var Nactif = $(".userNactif");
var Societe = $(".Societe");
hideUserBlock()
type.change(function () {
displayUserBlock();
}); // Bind the function to displayBlock
type.change(); // Manual trigger to display block.
function displayUserBlock() {
hideUserBlock();
var type =$("#{{ admin.uniqId }}_type").val()
switch(type) {
case 'Freelancer':
freelancer.css("display", "block");
freelancer.trigger("create");
break;
case 'Jobowner':
Societe.css("display", "block");
Societe.trigger("create");
break;
case 'Super Jobowner':
Societe.css("display", "block");
Societe.trigger("create");
break;
case 'Jobowner non actif':
Societe.css("display", "block");
Societe.trigger("create");
break;
case 'Rédacteur':
Societe.css("display", "block");
Societe.trigger("create");
break;
}
}
function hideUserBlock() {
freelancer.css("display", "none");
freelancer.trigger("create");
Societe.css("display", "none");
Societe.trigger("create");
}
});
</script>

Symfony2 FOSUserbundle add user to group

i'm using FOSUserBundle Groups.
Now i want to add the groups to my user (when adding a new)
I tried to load the groups to my form but failed.
Here the form:
$builder
->add('enabled','checkbox',array(
'required' => false))
->add('locked','checkbox',array(
'required' => false))
->add('username','text',array(
'required' => true))
->add('email','email',array(
'required' => true))
->add('password','password',array(
'required' => true))
->add('roles', 'choice', array(
'choices' => array('ROLE_ADMIN' => 'Admin', 'ROLE_USER' => 'Benutzer'),
'required' => true,
'multiple' => true
))
->add('groups', 'choice',array(
'choices' => $this->getGroups(),
'multiple' => true
))
->add('save','submit')
;
}
Also i tried
$builder
->add('enabled','checkbox',array(
'required' => false))
->add('locked','checkbox',array(
'required' => false))
->add('username','text',array(
'required' => true))
->add('email','email',array(
'required' => true))
->add('password','password',array(
'required' => true))
->add('roles', 'choice', array(
'choices' => array('ROLE_ADMIN' => 'Admin', 'ROLE_USER' => 'Benutzer'),
'required' => true,
'multiple' => true
))
->add('groups', 'collection', array(
'type' => 'choice',
))
->add('save','submit')
;
Thanks for your help :)
I now get the output with:
->add('groups','entity',array(
'class' => 'UniteUserBundle:usergroup' ,
'property' => 'name' ,
'multiple' => true ,
))
Not the next problem... it don't persist to my table 'fos_user_user_group' :(
Have you tried creating a GroupType and instantiating that type in the collection?
->add('groups', 'collection', array(
'type' => new Name\Space\To\GroupType(),
))
For example your GroupType might look like the following code. Notice it's mapped to the Group entity.
<?php
namespace Name\Space\To\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
class GroupType extends AbstractType
{
public $group;
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('group', 'hidden', array(
'error_bubbling' => false,
'required' => false,
));
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Name\Space\To\Entity\Group',
));
}
public function getName()
{
return 'namespaceto_grouptype';
}
}

More advance entity join in FormBuilder Symfony2

I have two entities. First is Clinic an second is ClinicOpeningHours.
ClinicOpeningHours is mapped by Clinic id, but not in revers. I'm trying to find solution to get whole (7) records (mon - sun) and join it in ClinicFormType to have all this in one form.
$clinic = $em->getRepository('MyEntity:Clinic')->findOneBy(array(etc));
$form = $this->createForm(new ClinicFormType(), $clinic);
My form type:
public function buildForm(FormBuilderInterface $builder, array $options) {
$builder->add('name', 'text', array('label' => 'Name'));
$builder->add('services', 'entity', array(
'class' => 'MyEntity:Service',
'property' => 'name',
'label' => 'Services',
'required' => false,
'multiple' => true,
'attr' => array(
'data-placeholder' => "Choose one...",
'multiple' => 'multiple',
'class' => "chzn-select"
)
))
->add('WEEK DAYS', 'entity', array(
'label' => 'Property Language',
'class' => 'MyEntity:ClinicOpeningHours',
'query_builder' => SEVER RECORDS FROM DB MAPPED BY ID
},
));
}

Resources