Skip to content

Commit

Permalink
Merge pull request #983 from MadeWilson/feature/2.3-blog-improvement
Browse files Browse the repository at this point in the history
Fix/filter bundle
  • Loading branch information
lenybernard authored Nov 17, 2017
2 parents fbf15b7 + 40f1411 commit 1f7c77c
Show file tree
Hide file tree
Showing 7 changed files with 199 additions and 63 deletions.
46 changes: 20 additions & 26 deletions Bundle/BlogBundle/Filter/CategoryFilter.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,34 @@
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\Translation\TranslatorInterface;
use Victoire\Bundle\BlogBundle\Entity\Category;
use Victoire\Bundle\FilterBundle\Domain\FilterFormFieldQueryHandler;
use Victoire\Bundle\FilterBundle\Filter\BaseFilter;

/**
* CategoryFilter form type.
* Class CategoryFilter.
*/
class CategoryFilter extends BaseFilter
{
/**
* @var TranslatorInterface
*/
protected $translator;

/**
* @param EntityManager $entityManager
* @param RequestStack $requestStack
* @param TranslatorInterface $translator
* CategoryFilter constructor.
*
* @param EntityManager $entityManager
* @param RequestStack $requestStack
* @param FilterFormFieldQueryHandler $filterQueryHandler
* @param TranslatorInterface $translator
*/
public function __construct(EntityManager $entityManager, RequestStack $requestStack, TranslatorInterface $translator)
{
parent::__construct($entityManager, $requestStack);
public function __construct(
EntityManager $entityManager,
RequestStack $requestStack,
FilterFormFieldQueryHandler $filterQueryHandler,
TranslatorInterface $translator
) {
parent::__construct($entityManager, $requestStack, $filterQueryHandler);
$this->translator = $translator;
}

Expand Down Expand Up @@ -98,26 +109,8 @@ public function getCategoryChildrens(Category $category, $childrenArray)
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$categories = $this->filterQueryHandler->handle($options['widget'], BlogCategory::class);

//getAll categories
$categoryQb = $this->getEntityManager()->getRepository('VictoireBlogBundle:Category')->getAll();
//getAll published articles
$articleQb = $this->getEntityManager()->getRepository('VictoireBlogBundle:Article')->getAll(true);

//get Listing
$listing = $options['widget']->getListing();

$mode = $listing->getMode();
switch ($mode) {
case 'query':
//filter with listingQuery
$articleQb->filterWithListingQuery($listing->getQuery());
break;
}
$categoryQb->filterByArticles($articleQb->getInstance('article'));
$categories = $categoryQb->getInstance('c_category')->getQuery()->getResult();

//the blank value
$categoriesChoices = [];

foreach ($categories as $category) {
Expand All @@ -135,6 +128,7 @@ public function buildForm(FormBuilderInterface $builder, array $options)
$data = $this->getRequest()->query->get('filter')['category_filter']['category'];
}
}

$builder
->add(
'category', ChoiceType::class, [
Expand Down
21 changes: 2 additions & 19 deletions Bundle/BlogBundle/Filter/TagFilter.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use Doctrine\ORM\QueryBuilder;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\FormBuilderInterface;
use Victoire\Bundle\BlogBundle\Entity\Tag;
use Victoire\Bundle\FilterBundle\Filter\BaseFilter;

/**
Expand Down Expand Up @@ -68,25 +69,7 @@ public function buildQuery(QueryBuilder $qb, array $parameters)
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
//getAll tags
$tagQb = $this->getEntityManager()->getRepository('VictoireBlogBundle:Tag')->getAll();
//getAll published articles
$articleQb = $this->getEntityManager()->getRepository('VictoireBlogBundle:Article')->getAll(true);

//get Listing
$listing = $options['widget']->getListing();

$mode = $listing->getMode();
switch ($mode) {
case 'query': //filter with listingQuery
$articleQb->filterWithListingQuery($listing->getQuery());
break;
}
//filter tags with right articles
$tagQb->filterByArticles($articleQb->getInstance('article'));
$tags = $tagQb->getInstance('t_tag')->getQuery()->getResult();
//the blank value
$tagsChoices = [];
$tags = $this->filterQueryHandler->handle($options['widget'], Tag::class);

foreach ($tags as $tag) {
$tagsChoices[$tag->getTitle()] = $tag->getId();
Expand Down
17 changes: 6 additions & 11 deletions Bundle/BlogBundle/Resources/config/services.yml
Original file line number Diff line number Diff line change
Expand Up @@ -120,31 +120,26 @@ services:

#CATEGORY FILTER
victoire_blog.category_filters.form.type:
class: "%victoire_blog_category_filters_form_type_class%"
class: %victoire_blog_category_filters_form_type_class%
parent: victoire_filter_bundle.abstract_base_filter
arguments:
- "@doctrine.orm.entity_manager"
- "@request_stack"
- "@translator"
tags:
- { name: form.type }
- { name: victoire_core.filter }

#TAG FILTER
victoire_blog.tag_filters.form.type:
class: "%victoire_blog_tag_filters_form_type_class%"
arguments:
- "@doctrine.orm.entity_manager"
- "@request_stack"
class: %victoire_blog_tag_filters_form_type_class%
parent: victoire_filter_bundle.abstract_base_filter
tags:
- { name: form.type }
- { name: victoire_core.filter }

#DATE FILTER
victoire_blog.date_filters.form.type:
class: "%victoire_blog_date_filters_form_type_class%"
arguments:
- "@doctrine.orm.entity_manager"
- "@request_stack"
class: %victoire_blog_date_filters_form_type_class%
parent: victoire_filter_bundle.abstract_base_filter
tags:
- { name: form.type }
- { name: victoire_core.filter }
Expand Down
80 changes: 80 additions & 0 deletions Bundle/FilterBundle/Domain/FilterFormFieldQueryHandler.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
<?php

namespace Victoire\Bundle\FilterBundle\Domain;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\EntityManager;
use Victoire\Bundle\QueryBundle\Helper\QueryHelper;
use Victoire\Bundle\WidgetBundle\Entity\Widget;

/**
* Class FilterFormFieldQueryHandler.
*/
class FilterFormFieldQueryHandler
{
/**
* @var QueryHelper
*/
private $queryHelper;
/**
* @var EntityManager
*/
private $entityManager;

/**
* FilterFormFieldQueryHandler constructor.
*
* @param QueryHelper $queryHelper
* @param EntityManager $entityManager
*/
public function __construct(
QueryHelper $queryHelper,
EntityManager $entityManager
) {
$this->queryHelper = $queryHelper;
$this->entityManager = $entityManager;
}

/**
* @param Widget $widgetFilter
* @param $entity
*
* @return array
*/
public function handle(Widget $widgetFilter, $entity)
{
$widgetListing = $widgetFilter->getListing();

/* first we generate the query for the listing widget */
$queryBuilder = $this->queryHelper->getQueryBuilder($widgetListing, $this->entityManager);

$mode = $widgetListing->getMode();

if ($mode == 'query') {
/* if listing widget is in query mode we had a subquery with here parameter */
$queryBuilder = $this->queryHelper->buildWithSubQuery($widgetListing, $queryBuilder, $this->entityManager);
}

$subQuery = $queryBuilder->getQuery();
$subQueryParameters = $queryBuilder->getParameters();

$filterEntityRepo = $this->entityManager->getRepository($entity);

$alias = explode('\\', $entity);
$alias = end($alias);

/* we build a new query for the filter entity */
$queryBuilder = $filterEntityRepo->createQueryBuilder($alias);
/* and give the query for the listing entity has subquery */
$queryBuilder->andWhere($queryBuilder->expr()->in($alias, $subQuery->getDQL()));

$parameters = new ArrayCollection(
array_merge($subQueryParameters->toArray(), $queryBuilder->getParameters()->toArray())
);
$queryBuilder->setParameters($parameters);

$entities = $queryBuilder->getQuery()->getResult();

return $entities;
}
}
36 changes: 30 additions & 6 deletions Bundle/FilterBundle/Filter/BaseFilter.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,25 +8,49 @@
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Victoire\Bundle\FilterBundle\Domain\FilterFormFieldQueryHandler;

/**
* Class BaseFilter.
*/
abstract class BaseFilter extends AbstractType implements BaseFilterInterface
{
/**
* @var EntityManager
*/
protected $entityManager;
/**
* @var RequestStack
*/
private $requestStack;
protected $requestStack;
/**
* @var FilterFormFieldQueryHandler
*/
protected $filterQueryHandler;

/**
* @param EntityManager $em
* @param RequestStack $requestStack
* BaseFilter constructor.
*
* @param EntityManager $entityManager
* @param RequestStack $requestStack
* @param FilterFormFieldQueryHandler $filterQueryHandler
*/
public function __construct(EntityManager $em, RequestStack $requestStack)
{
$this->entityManager = $em;
public function __construct(
EntityManager $entityManager,
RequestStack $requestStack,
FilterFormFieldQueryHandler $filterQueryHandler
) {
$this->entityManager = $entityManager;
$this->requestStack = $requestStack;
$this->filterQueryHandler = $filterQueryHandler;
}

/**
* @param QueryBuilder $qb
* @param array $parameters
*
* @return mixed
*/
abstract public function buildQuery(QueryBuilder $qb, array $parameters);

/**
Expand Down
44 changes: 43 additions & 1 deletion Bundle/FilterBundle/README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,45 @@
Allows to filter any list's results

**MORE DETAILS SOON**
To create a new filter you have to build a Filter class extending the abstract Victoire\FilterBundle\Filter\BaseFilter class

```php
<?php

namespace AppBundle\Filter;

use Victoire\FilterBundle\Filter\BaseFilter;

class TagFilter extends BaseFilter {

/* will be the entry point to generate the result query of a filter */
public function buildQuery(){}

/* BaseFilter is an extension of symfony AbstractType so you can generate a form as usual */
public function buildForm(){}

/* Mandatory since when a filter is apply the WidgetListingContentResolver will identify the good filter with this method */
public function getName(){}

/* Method used in the WidgetListingContentResolver to recover the selected entity */
public function getFilters(){}
}
```
And you have to declare it in your services

```yaml
victoire_blog.tag_filters.form.type:
class: AppBundle\Filter\TagFilter
parent: victoire_filter_bundle.abstract_base_filter
tags:
- { name: form.type }
- { name: victoire_core.filter }
```
If your list has been created in query mode you can use the FilterFormFieldQueryHandler service
wich is accessible in the Base Filter to build your query.
```php
/* he takes the WidgetFilter and the class name of the filtred entity and return an array of that entities */
$this->filterQueryHandler->handle($options['widget'], Tag::class);
```
18 changes: 18 additions & 0 deletions Bundle/FilterBundle/Resources/config/services.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,21 @@
services:
victoire_core.filter_chain:
class: Victoire\Bundle\FilterBundle\Filter\Chain\FilterChain

#############################
######## DOMAIN
############################

victoire_filter_bundle.abstract_base_filter:
class: Victoire\Bundle\FilterBundle\Filter\BaseFilter
abstract: true
arguments:
- "@doctrine.orm.entity_manager"
- "@request_stack"
- "@victoire_filter_bundle.filter_form_field_query.handler"

victoire_filter_bundle.filter_form_field_query.handler:
class: Victoire\Bundle\FilterBundle\Domain\FilterFormFieldQueryHandler
arguments:
- "@victoire_query.query_helper"
- "@doctrine.orm.entity_manager"

0 comments on commit 1f7c77c

Please sign in to comment.