Completed
Push — master ( 4de43c...7a7d43 )
by Paul
06:26
created

CategoryFilter   A

Complexity

Total Complexity 19

Size/Duplication

Total Lines 157
Duplicated Lines 45.22 %

Coupling/Cohesion

Components 1
Dependencies 10

Importance

Changes 0
Metric Value
wmc 19
lcom 1
cbo 10
dl 71
loc 157
rs 10
c 0
b 0
f 0

6 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
C buildQuery() 19 38 7
A getCategoryChildrens() 0 11 2
B buildForm() 52 52 7
A getFilters() 0 4 1
A getName() 0 4 1

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
3
namespace Victoire\Bundle\BlogBundle\Filter;
4
5
use Doctrine\ORM\EntityManager;
6
use Doctrine\ORM\QueryBuilder;
7
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
8
use Symfony\Component\Form\FormBuilderInterface;
9
use Symfony\Component\HttpFoundation\Request;
10
use Symfony\Component\Translation\TranslatorInterface;
11
use Victoire\Bundle\BlogBundle\Entity\Category;
12
use Victoire\Bundle\FilterBundle\Filter\BaseFilter;
13
14
/**
15
 * CategoryFilter form type.
16
 */
17
class CategoryFilter extends BaseFilter
18
{
19
    protected $translator;
20
21
    /**
22
     * @param EntityManager       $entityManager
23
     * @param Request             $request
24
     * @param TranslatorInterface $translator
25
     */
26
    public function __construct(EntityManager $entityManager, Request $request, TranslatorInterface $translator)
27
    {
28
        parent::__construct($entityManager, $request);
29
        $this->translator = $translator;
30
    }
31
32
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$qb" missing
Loading history...
33
     * Build the query.
34
     *
35
     * @param QueryBuilder &$qb
0 ignored issues
show
introduced by
Doc comment for parameter &$qb does not match actual variable name $qb
Loading history...
36
     * @param array        $parameters
37
     *
38
     * @return QueryBuilder
39
     */
40
    public function buildQuery(QueryBuilder $qb, array $parameters)
41
    {
42 View Code Duplication
        if (!is_array($parameters['category'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
43
            $parameters['category'] = [$parameters['category']];
44
        }
45
        $childrenArray = [];
46
        //clean the parameters from the blank value
47
        foreach ($parameters['category'] as $index => $parameter) {
48
            //the blank value is removed
49
            if ($parameter === '') {
50
                unset($parameters['category'][$index]);
51
            } else {
52
                $parentCategory = $this->getEntityManager()->getRepository('VictoireBlogBundle:Category')->findOneById($parameter);
53
                $childrenArray = array_merge($childrenArray, $this->getCategoryChildrens($parentCategory, []));
54
            }
55
        }
56
57
        if (count($childrenArray) > 0) {
58 View Code Duplication
            if (array_key_exists('strict', $parameters)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
59
                $repository = $this->getEntityManager()->getRepository('VictoireBlogBundle:Article');
60
                foreach ($childrenArray as $index => $category) {
61
                    $parameter = ':category'.$index;
62
                    $subquery = $repository->createQueryBuilder('article_'.$index)
63
                        ->join('article_'.$index.'.category', 'category_'.$index)
64
                        ->where('category_'.$index.' = '.$parameter);
65
                    $qb->andWhere($qb->expr()->in('main_item', $subquery->getDql()))
66
                        ->setParameter($parameter, $category);
67
                }
68
            } else {
69
                $qb = $qb
70
                    ->join('main_item.category', 'c')
71
                    ->andWhere('c.id IN (:category)')
72
                    ->setParameter('category', $childrenArray);
73
            }
74
        }
75
76
        return $qb;
77
    }
78
79
    public function getCategoryChildrens(Category $category, $childrenArray)
0 ignored issues
show
introduced by
Missing function doc comment
Loading history...
80
    {
81
        $childrenArray[] = $category->getId();
82
        $childrens = $category->getChildren();
83
84
        foreach ($childrens as $children) {
85
            $childrenArray = $this->getCategoryChildrens($children, $childrenArray);
86
        }
87
88
        return $childrenArray;
89
    }
90
91
    /**
92
     * define form fields.
93
     *
94
     * @param FormBuilderInterface $builder
95
     * @param array                $options
96
     *
97
     * @SuppressWarnings checkUnusedFunctionParameters
98
     */
99 View Code Duplication
    public function buildForm(FormBuilderInterface $builder, array $options)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
100
    {
101
102
        //getAll categories
103
        $categoryQb = $this->getEntityManager()->getRepository('VictoireBlogBundle:Category')->getAll();
104
        //getAll published articles
105
        $articleQb = $this->getEntityManager()->getRepository('VictoireBlogBundle:Article')->getAll(true);
106
107
        //get Listing
108
        $listing = $options['widget']->getListing();
109
110
        $mode = $listing->getMode();
111
        switch ($mode) {
112
            case 'query':
113
                //filter with listingQuery
114
                $articleQb->filterWithListingQuery($listing->getQuery());
115
                break;
116
        }
117
        $categoryQb->filterByArticles($articleQb->getInstance('article'));
118
        $categories = $categoryQb->getInstance('c_category')->getQuery()->getResult();
119
120
        //the blank value
121
        $categoriesChoices = [];
122
123
        foreach ($categories as $category) {
124
            $categoriesChoices[$category->getId()] = $category->getTitle();
125
        }
126
127
        $data = null;
128
        if ($this->getRequest()->query->has('filter') && array_key_exists('category_filter', $this->getRequest()->query->get('filter'))) {
129
            if ($options['multiple']) {
130
                $data = [];
131
                foreach ($this->getRequest()->query->get('filter')['category_filter']['category'] as $id => $selectedCategory) {
132
                    $data[$id] = $selectedCategory;
133
                }
134
            } else {
135
                $data = $this->getRequest()->query->get('filter')['category_filter']['category'];
136
            }
137
        }
138
        $builder
139
            ->add(
140
                'category', ChoiceType::class, [
141
                    'label'       => false,
142
                    'choices'     => $categoriesChoices,
143
                    'required'    => false,
144
                    'expanded'    => true,
145
                    'multiple'    => $options['multiple'],
146
                    'empty_value' => $this->translator->trans('blog.category_filter.empty_value.label'),
147
                    'data'        => $data,
148
                ]
149
            );
150
    }
151
152
    /**
153
     * Get the filters.
154
     *
155
     * @param array $filters
156
     *
157
     * @return array The filters
158
     */
159
    public function getFilters($filters)
160
    {
161
        return $this->getEntityManager()->getRepository('VictoireBlogBundle:Category')->findById($filters['category']);
162
    }
163
164
    /**
165
     * get name.
166
     *
167
     * @return string name
168
     */
169
    public function getName()
170
    {
171
        return 'category_filter';
172
    }
173
}
174