Last active
October 10, 2015 14:17
-
-
Save merk/3703011 to your computer and use it in GitHub Desktop.
Use of a FormType to build a filter for a list of entities
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace Ibms\JobBundle\Controller; | |
class JobController extends BaseJobController | |
{ | |
/** | |
* Job list. | |
* | |
* @param \Symfony\Component\HttpFoundation\Request $request | |
* @return \Symfony\Component\HttpFoundation\Response | |
*/ | |
public function listAction(Request $request) | |
{ | |
$qb = $this->getJobManager()->queryAll('j'); | |
$filter = $this->getJobFilter(); | |
$filter->filter($qb); | |
$paginator = $this->container->get('knp_paginator'); | |
$jobs = $paginator->paginate( | |
$qb, | |
$request->query->get('page', 1), | |
$request->query->get('pp', 15) | |
); | |
return $this->render('IbmsJobBundle:Job:list.html.twig', array( | |
'filter' => $filter->getView(), | |
'jobs' => $jobs, | |
)); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace Ibms\JobBundle\Filter; | |
use Doctrine\ORM\QueryBuilder; | |
use Doctrine\ORM\Query\Expr\Andx; | |
use Ibms\JobBundle\Entity\Status; | |
use Symfony\Component\Form\FormInterface; | |
use Symfony\Component\HttpFoundation\Request; | |
class JobFilter | |
{ | |
/** | |
* @var \Symfony\Component\Form\FormInterface | |
*/ | |
private $form; | |
/** | |
* The constructor | |
* | |
* @param \Symfony\Component\HttpFoundation\Request $request | |
* @param \Symfony\Component\Form\FormInterface $form | |
*/ | |
public function __construct(Request $request, FormInterface $form) | |
{ | |
$this->form = $form; | |
$this->form->setData(new JobFilterModel); | |
if ($request->query->count() > 0) { | |
$this->form->bind($request); | |
} | |
} | |
/** | |
* @return \Symfony\Component\Form\FormView | |
*/ | |
public function getView() | |
{ | |
return $this->form->createView(); | |
} | |
/** | |
* @param \Doctrine\ORM\QueryBuilder $qb | |
*/ | |
public function filter(QueryBuilder $qb) | |
{ | |
/** @var $data JobFilterModel */ | |
$data = $this->form->getData(); | |
$conditions = new Andx; | |
if ($data->warrantySupplier) { | |
$qb->leftJoin('j.appliances', 'ja'); | |
$conditions->add($qb->expr()->andX( | |
$qb->expr()->isNotNull('ja.warrantyClass'), | |
$qb->expr()->eq('IDENTITY(ja.warrantySupplier)', ':supplierId'), | |
'SIZE(j.appliances) > 0' | |
)); | |
$qb->setParameter('supplierId', $data->warrantySupplier->getId()); | |
} | |
if ($data->statuses->count()) { | |
$conditions->add($qb->expr()->in('IDENTITY(j.status)', | |
$data->statuses->map(function (Status $status) { | |
return $status->getId(); | |
})->toArray() | |
)); | |
} else { | |
$conditions->add($qb->expr()->neq('s.constant', ':cancelled')); | |
$qb->setParameter('cancelled', 'CANCELLED'); | |
} | |
if ($data->scheduled) { | |
$day = $data->scheduled; | |
$conditions->add($qb->expr()->eq('j.scheduled', ':date')); | |
$qb->setParameter('date', $day->format('Y-m-d')); | |
} | |
if ($data->workshop) { | |
$conditions->add($qb->expr()->isNull('j.address')); | |
} | |
if ($data->unassigned) { | |
$conditions->add($qb->expr()->orX( | |
$qb->expr()->isNull('j.technician'), | |
$qb->expr()->eq('t.holding', ':holding')) | |
); | |
$qb->setParameter('holding', 1); | |
} elseif ($data->technician) { | |
$conditions->add($qb->expr()->eq('IDENTITY(j.technician)', ':technicianId')); | |
$qb->setParameter('technicianId', $data->technician->getId()); | |
} | |
if ($conditions->count()) { | |
$qb->andWhere($conditions); | |
} | |
} | |
/** | |
* @return bool | |
*/ | |
public function isSingleTechAndDay() | |
{ | |
$data = $this->form->getData(); | |
return $data->scheduled && $data->technician; | |
} | |
/** | |
* @return bool | |
*/ | |
public function isWorkshopDay() | |
{ | |
$data = $this->form->getData(); | |
return $data->scheduled && !$data->technician && $data->workshop; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace Ibms\JobBundle\Filter; | |
use \Doctrine\Common\Collections\ArrayCollection; | |
class JobFilterModel | |
{ | |
/** | |
* @var \Doctrine\Common\Collections\Collection<\Ibms\JobBundle\Entity\Status> | |
*/ | |
public $statuses; | |
/** | |
* @var \DateTime|null | |
*/ | |
public $scheduled; | |
/** | |
* @var Boolean | |
*/ | |
public $workshop = false; | |
/** | |
* @var \Ibms\SupplierBundle\Entity\Supplier|null | |
*/ | |
public $warrantySupplier; | |
/** | |
* @var \Ibms\UserBundle\Entity\Technician|null | |
*/ | |
public $technician; | |
/** | |
* @var bool | |
*/ | |
public $unassigned = false; | |
public function __construct() | |
{ | |
$this->statuses = new ArrayCollection; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace Ibms\JobBundle\Filter; | |
use Doctrine\ORM\EntityRepository; | |
use Symfony\Component\Form\AbstractType; | |
use Symfony\Component\Form\FormBuilderInterface; | |
use Symfony\Component\OptionsResolver\OptionsResolverInterface; | |
class JobFilterType extends AbstractType | |
{ | |
/** | |
* @param \Symfony\Component\Form\FormBuilderInterface $builder | |
* @param array $options | |
*/ | |
public function buildForm(FormBuilderInterface $builder, array $options) | |
{ | |
$builder->add('statuses', 'entity', array( | |
'class' => 'Ibms\\JobBundle\\Entity\\Status', | |
'expanded' => true, | |
'multiple' => true, | |
'property' => 'name', | |
'query_builder' => function (EntityRepository $er) { | |
return $er->createQueryBuilder('s')->addOrderBy('s.name'); | |
}, | |
'required' => false, | |
)); | |
$builder->add('scheduled', 'date', array( | |
'required' => false, | |
'widget' => 'single_text', | |
)); | |
$builder->add('workshop', 'checkbox', array( | |
'required' => false, | |
)); | |
$builder->add('warrantySupplier', 'entity', array( | |
'class' => 'Ibms\\SupplierBundle\\Entity\\Supplier', | |
'empty_value' => 'None Selected', | |
'property' => 'name', | |
'query_builder' => function (EntityRepository $er) { | |
return $er->createQueryBuilder('s')->addOrderBy('s.name'); | |
}, | |
'required' => false, | |
)); | |
$builder->add('technician', 'entity', array( | |
'class' => 'Ibms\\UserBundle\\Entity\\Technician', | |
'empty_value' => 'None Selected', | |
'property' => 'user.fullName', | |
'query_builder' => function (EntityRepository $er) { | |
return $er->createQueryBuilder('t') | |
->addSelect('u') | |
->leftJoin('t.user', 'u') | |
->andWhere('u IS NOT NULL') | |
->orderBy('u.lastName') | |
->addOrderBy('u.firstName'); | |
}, | |
'required' => false, | |
)); | |
$builder->add('unassigned', 'checkbox', array( | |
'required' => false, | |
)); | |
} | |
/** | |
* @param \Symfony\Component\OptionsResolver\OptionsResolverInterface $resolver | |
*/ | |
public function setDefaultOptions(OptionsResolverInterface $resolver) | |
{ | |
$resolver->setDefaults(array( | |
'data_class' => 'Ibms\\JobBundle\\Filter\\JobFilterModel', | |
'csrf_protection' => false, | |
)); | |
} | |
/** | |
* @return string | |
*/ | |
public function getName() | |
{ | |
return 'filter_job'; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{# ... #} | |
{% set filterModel = filter.vars.value %} | |
{% block body %} | |
<form id="filter" class="well" action="" method="get" {{ form_enctype(filter) }}> | |
<div class="row"> | |
{% if app.user.actuallyTechnician %} | |
<div class="span3"> | |
{{ form_row(filter.technician) }} | |
</div> | |
<div class="span3"> | |
{{ form_row(filter.scheduled, { | |
label: 'Date Scheduled' | |
}) }} | |
</div> | |
{% else %} | |
<div class="span3"> | |
{{ form_row(filter.statuses, { | |
label: 'Job Statuses' | |
}) }} | |
</div> | |
<div class="span3"> | |
{{ form_row(filter.scheduled, { | |
label: 'Date Scheduled' | |
}) }} | |
{{ form_row(filter.unassigned, { | |
label: 'Unassigned jobs only', | |
attr: { | |
'data-toggle-visible': '#technician-toggle', | |
'data-toggle-opposite': '' | |
} | |
}) }} | |
<div id="technician-toggle"> | |
{{ form_row(filter.technician) }} | |
</div> | |
{{ form_row(filter.workshop, { | |
label: 'Show workshop jobs', | |
}) }} | |
</div> | |
<div class="span3"> | |
{{ form_row(filter.warrantySupplier, { | |
help: 'Selecting a warranty supplier will list warranty jobs for that supplier', | |
label: 'Warranty Supplier' | |
}) }} | |
</div> | |
{% endif %} | |
</div> | |
<div class="row"> | |
<button type="submit" class="pull-right btn btn-primary"><i class="icon-list-alt icon-white"></i> Update List</button> | |
{% if not app.user.technician %}<a href="{{ path('ibms_job_list') }}" class="pull-right btn"><i class="icon-share-alt"></i> Remove Filters</a>{% endif %} | |
</div> | |
</form> | |
{# ... #} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<service id="ibms_job.filter.job" class="Ibms\JobBundle\Filter\JobFilter" scope="request"> | |
<argument type="service" id="request" /> | |
<argument type="service" id="ibms_job.filter.job_form" /> | |
</service> | |
<service id="ibms_job.filter.job_form" factory-method="createNamed" factory-service="form.factory" class="Symfony\Component\Form\Form"> | |
<argument></argument> | |
<argument>filter_job</argument> | |
</service> | |
<service id="ibms_job.filter.job_form_type" class="Ibms\JobBundle\Filter\JobFilterType"> | |
<tag name="form.type" alias="filter_job" /> | |
</service> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment