I am building a website with quite some nested objects. Slowly but surely as the database grows larger the Doctrine associations are starting to really show. One of the most important issue I have is the fact that I need to create dropdowns so the users can relate some of these entities. The code below is part of one of my FormTypes used to generate my forms.
$builder
->add('sidebarcontent')
->add('publicAgenda')
->add('assets')
->add('structure')
->add('history')
->add('emblem')
->add('demonym')
->add('type', EntityType::Class, array(
'class' => 'ContentBundle\Entity\OrganizationType',
'choice_label' => 'name',
'empty_data' => '',
'required' => false,
'query_builder' =>function (EntityRepository $er) use ( $world ) {
return $er->createQueryBuilder('c')
->orderBy('c.name', 'ASC');
}))
->add('geographicLocation', EntityType::Class, array(
'class' => 'ContentBundle\Entity\Location',
'choice_label' => 'title',
'empty_data' => '',
'required' => false,
'query_builder' =>function (EntityRepository $er) use ( $world ) {
return $er->createQueryBuilder('c')
->where('c.world = ?1')
->setParameter(1, $world)
->andWhere('c.state != ?2')
->setParameter(2, 'archived')
->orderBy('c.title', 'ASC');
}
))
->add('parent', EntityType::Class, array(
'class' => 'ContentBundle\Entity\Organization',
'choice_label' => 'title',
'empty_data' => '',
'required' => false,
'query_builder' =>function (EntityRepository $er) use ( $world ) {
return $er->createQueryBuilder('c')
->where('c.world = ?1')
->setParameter(1, $world)
->andWhere('c.state != ?2')
->setParameter(2, 'archived')
->orderBy('c.title', 'ASC');
}
))
->add('ethnicities', EntityType::Class, array(
'class' => 'ContentBundle\Entity\Ethnicity',
'choice_label' => 'title',
'empty_data' => '',
'multiple' => true,
'expanded' => true,
'required' => false,
'query_builder' =>function (EntityRepository $er) use ( $world ) {
return $er->createQueryBuilder('c')
->where('c.world = ?1')
->setParameter(1, $world)
->andWhere('c.state != ?2')
->setParameter(2, 'archived')
->orderBy('c.title', 'ASC');
}
));
Is there a way to fetch these entities down to the bare minimum (uuid, title) and not Hydrate them? I am not even sure if this is the right question to be asking. I am just trying to lower the loading time I have right now.
EntityType form field required entity object and you cannot select only required fields because otherwise, it wouldn't know what to persist in an entity relation.
If you really need to pull only certain fields you have to use ChoiceType fields. But remember, while persisting an entity it would require to have objects for the related entities.
As another option, You can also try using choices parameter with doctrine query results found and that way you can cache your query and/or query results.
For example:
replace query_builder parameter with choices parameter in form.
$choices = $this->createQueryBuilder('c')
->where('c.world = ?1')
->setParameter(1, $world)
->andWhere('c.state != ?2')
->setParameter(2, 'archived')
->orderBy('c.title', 'ASC');
->getQuery()
->useQueryCache(true)
->useResultCache(true, 3600) // this will cache most common results for a while.
->execute();
And then the field would be as follow.
->add('geographicLocation', EntityType::Class, array(
'class' => 'ContentBundle\Entity\Location',
'choice_label' => 'title',
'empty_data' => '',
'required' => false,
'choices' => $choices
))
Related
In my Form type I have a select choice which list my team entities.
When I do this
$builder->add('teams');
it lists all my teams on my form AND an empty choice, so it's possible to have no team or to remove the team (and that behavior is great for what I have to do).
But when I use a query_builder
$builder->add('teams', EntityType::class, array(
'class' => Team::class,
'query_builder' => function (EntityRepository $er) {
return $er->getTeamsNotRestrictedByAdmin();
},
'choice_label' => '_name'
)
);
it returns the entities I want but I don't have that null choice anymore. How could I get it back properly ?
Go with :
$builder->add('teams', EntityType::class, array(
'class' => Team::class,
'query_builder' => function (EntityRepository $er) {
return $er->getTeamsNotRestrictedByAdmin();
},
'choice_label' => '_name',
'required' => false,
'empty_data' => ''
)
);
I am using sonata admin to set up an admin class with four filters. These filters are multiple choice and related to other entities. I want to make these filters dependent and run one filter query to filter the data considering all selected filter values. So far I just used sonata callback filter, but it can not filter when I select two or three fields to filter data. Is there a technique to override the query sonata run for filters?
$datagridMapper
->add('campaign', null, array(), 'entity', array(
'class' => 'AppPolioDbBundle:Campaign',
'choice_label' => 'campaignName', 'multiple' => true,
'query_builder' => function (EntityRepository $er) {
return $er->createQueryBuilder('u')
->groupBy('u.campaignName');
},
))
->add('region', 'doctrine_orm_callback', array(
'callback' => array($this, 'callbackFilterRegion'),
'field_type' => 'checkbox'
),
'choice',
array('choices' => $this -> getRegionList(), 'multiple' => true))
->add('district.districtCode', null, array(), 'entity', array(
'class' => 'AppPolioDbBundle:District',
'choice_label' => 'districtName', 'multiple' => true,
'query_builder' => function (EntityRepository $er) {
return $er->createQueryBuilder('u')
->groupBy('u.districtName');
},
))
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'
))
I'm working with the Sonata AdminBundle and I would like to set the selected value of my select list.
I have a Category with fields: CategoryID, parentID, tag. The parentID can be NULL.
The code how I build my form:
// Fields to be shown on create/edit forms
protected function configureFormFields(FormMapper $formMapper)
{
// If edit -> get tag and id from tag
if($this->subject->getCategoryId() !== null)
{
$tag_current = $this->subject->getCategoryId()->getTag();
$tag_current_id = $this->subject->getCategoryId()->getParentid()->getCategoryid();
}
$formMapper
->add('tag', 'text', array('label' => 'Tag'))
->add('name', 'text', array('label' => 'Naam'))
->add('nameEN', 'text', array('label' => 'Naam Engels', 'required' => false, 'data' => 'test'))
->add('parentcategory', 'entity', array(
'class' => 'DX\MyBundle\Entity\Category',
'empty_data' => null,
'empty_value' => "GEEN PARENT CATEGORIE",
'required' => false,
'data' => $tag_current_id,
'query_builder' => function(EntityRepository $er) use ($tag_current) {
return $er->createQueryBuilder('c')
->where('c.parentid IS NULL')
->andWhere('c.tag != :tag')
->andWhere('c.tag != :tag_current')
->setParameter('tag', 'FOTOGRAAF')
->setParameter('tag_current', $tag_current);
}
))
;
}
As you see I've tried to set data property with no result. The empty value NO PARENT CATEGORY is always selected on page load.
My $tag_current_id is an integer, in this case: 11 . And my select list looks like this:
<select id="s54ff22c20ca39_parentcategory" name="s54ff22c20ca39[parentcategory]" class="select2-offscreen" tabindex="-1" title="Parentcategory">
<option value="">GEEN PARENT CATEGORIE</option>
<option value="1">THEMA</option>
<option value="11">FREEM SELECTIE</option>
</select>
But still not selected. What am I doing wrong?
Your query builder should return all the available values, it will select automatically your database value :
$formMapper->add('parentcategory', 'entity', array(
'class' => 'DX\MyBundle\Entity\Category',
'empty_data' => null,
'empty_value' => "GEEN PARENT CATEGORIE",
'required' => false,
'query_builder' => function(EntityRepository $er) {
return $er->createQueryBuilder('c')
->where('c.parentid IS NULL')
->andWhere('c.tag != :tag')
->setParameter('tag', 'FOTOGRAAF')
}
))
Update:
This is what i'm doing in my project :
$formMapper->add('supplier', 'entity', array(
'class' => 'AcmeCoreBundle:ShopSupplier',
'empty_value' => 'None',
'empty_data' => null,
'query_builder' => function(EntityRepository $er) {
return $er->createQueryBuilder('ss')
->orderBy('ss.name', 'ASC');
}
))
It selects automatically the database value and set the empty_value when none is selected. If it doesn't work in your project, i have no idea.
Is it possible to generate select list where options will be retrieved from database and there will be option (with JS) to multiply field ?
I've copied my code, maybe it will help.
$builder->add('device', 'collection', array(
'type' => 'entity',
'label' => ' ',
'options' => array(
'class' => 'TrashTrashAdminBundle:DeviceType',
'property' => 'name',
'query_builder' => function(EntityRepository $er) {
return $er->createQueryBuilder('d')
->where('d.isLighting = 1');
},
),
'attr' => array('class' => 'form-control device')
))
You are trying to work with collection field type in way as you would work with entity field type. You should change collection for entity:
$builder->add('device', 'entity', array(
'options' => array(
'class' => 'TrashTrashAdminBundle:DeviceType',
'property' => 'name',
'query_builder' => function(EntityRepository $er) {
return $er->createQueryBuilder('d')
->where('d.isLighting = 1');
},
),
'attr' => array(
'class' => 'form-control device'
))
);
After the select box is generated, you can make changes, which you mentioned, at your will.