diff --git a/Bundle/BlogBundle/Filter/CategoryFilter.php b/Bundle/BlogBundle/Filter/CategoryFilter.php index 85d3dd0bc..e1619dca4 100644 --- a/Bundle/BlogBundle/Filter/CategoryFilter.php +++ b/Bundle/BlogBundle/Filter/CategoryFilter.php @@ -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; } @@ -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) { @@ -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, [ diff --git a/Bundle/BlogBundle/Filter/TagFilter.php b/Bundle/BlogBundle/Filter/TagFilter.php index be2bbb9ea..e8ad4ce14 100644 --- a/Bundle/BlogBundle/Filter/TagFilter.php +++ b/Bundle/BlogBundle/Filter/TagFilter.php @@ -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; /** @@ -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(); diff --git a/Bundle/BlogBundle/Resources/config/services.yml b/Bundle/BlogBundle/Resources/config/services.yml index c4ffc0332..4059867cf 100644 --- a/Bundle/BlogBundle/Resources/config/services.yml +++ b/Bundle/BlogBundle/Resources/config/services.yml @@ -120,10 +120,9 @@ 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 } @@ -131,20 +130,16 @@ services: #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 } diff --git a/Bundle/FilterBundle/Domain/FilterFormFieldQueryHandler.php b/Bundle/FilterBundle/Domain/FilterFormFieldQueryHandler.php new file mode 100644 index 000000000..137500551 --- /dev/null +++ b/Bundle/FilterBundle/Domain/FilterFormFieldQueryHandler.php @@ -0,0 +1,80 @@ +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; + } +} diff --git a/Bundle/FilterBundle/Filter/BaseFilter.php b/Bundle/FilterBundle/Filter/BaseFilter.php index cf8785b38..2d9faecba 100644 --- a/Bundle/FilterBundle/Filter/BaseFilter.php +++ b/Bundle/FilterBundle/Filter/BaseFilter.php @@ -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); /** diff --git a/Bundle/FilterBundle/README.md b/Bundle/FilterBundle/README.md index 6b2d41837..0c5294924 100644 --- a/Bundle/FilterBundle/README.md +++ b/Bundle/FilterBundle/README.md @@ -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 + filterQueryHandler->handle($options['widget'], Tag::class); +``` \ No newline at end of file diff --git a/Bundle/FilterBundle/Resources/config/services.yml b/Bundle/FilterBundle/Resources/config/services.yml index b106d0515..32c9fb876 100644 --- a/Bundle/FilterBundle/Resources/config/services.yml +++ b/Bundle/FilterBundle/Resources/config/services.yml @@ -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"