Completed
Push — master ( 28284e...eaa9bf )
by
unknown
12:07
created

CategoriesController   A

Complexity

Total Complexity 27

Size/Duplication

Total Lines 262
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Importance

Changes 0
Metric Value
wmc 27
lcom 1
cbo 3
dl 0
loc 262
rs 10
c 0
b 0
f 0

11 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A getStaticFilters() 0 4 1
A show() 0 10 2
C applyFilter() 0 27 8
A applyStaticFilter() 0 12 3
B applyDynamicFilter() 0 36 2
A clearStaticFilters() 0 10 2
A clearDynamicFilters() 0 16 4
A separateFilters() 0 17 2
A parseDynamicFilter() 0 8 1
A isDynamicFilter() 0 8 1
1
<?php
2
3
namespace App\Http\Controllers;
4
5
use App\Category;
6
use App\Lot;
7
use App\Product;
8
use App\Repositories\CategoryRepository;
9
use App\Repositories\TagRepository;
10
use Illuminate\Http\Request;
11
12
class CategoriesController extends Controller
13
{
14
    const FILTER_DYNAMIC = 'dynamic';
15
16
    const FILTER_STATIC = 'static';
17
18
    /**
19
     * @var CategoryRepository
20
     */
21
    protected $categories;
22
23
    /**
24
     * @var TagRepository
25
     */
26
    protected $tags;
27
28
    /**
29
     * CategoriesController constructor.
30
     * @param CategoryRepository $categoryRepository
31
     * @param TagRepository $tagRepository
32
     */
33
    public function __construct(CategoryRepository $categoryRepository, TagRepository $tagRepository)
34
    {
35
        $this->categories = $categoryRepository;
36
        $this->tags = $tagRepository;
37
    }
38
39
    /**
40
     * Get list of unchanged/static filters.
41
     *
42
     * @return array
43
     */
44
    final static public function getStaticFilters()
0 ignored issues
show
Coding Style introduced by
As per PSR2, the static declaration should come after the visibility declaration.
Loading history...
45
    {
46
        return [ 'price_min', 'price_max' ];
47
    }
48
49
    /**
50
     * Show action for category.
51
     *
52
     * @param Request $request
53
     * @param $category
54
     * @param $subcategory
55
     *
56
     * @return $this
57
     */
58
    public function show(Request $request, $category, $subcategory = null)
59
    {
60
        $groups = $this->tags->getCategoryTagGroups($category, $subcategory);
61
62
        $filtered = $this->applyFilter($request, $category, $subcategory, 12);
63
64
        return view(($request->ajax()) ? 'categories.partials.filter_result' : 'categories.index', [
65
            'category' => $category, 'products' => $filtered, 'groups' => $groups
66
        ]);
67
    }
68
69
    /**
70
     * Apply filters for category scope.
71
     *
72
     * @param Request $request
73
     * @param $category
74
     * @param $subcategory
75
     * @param $perPage
76
     *
77
     * @return mixed
78
     */
79
    protected function applyFilter(Request $request, $category, $subcategory, $perPage = 12)
80
    {
81
        if($filters = $request->all() ? : false)
82
            list($static, $dynamic) = $this->separateFilters($filters);
83
84
        $query = $category->products()
85
            ->getQuery()->select('products.*');
86
87
        if(isset($static) && $static = $this->clearStaticFilters($static))
88
            $query = $this->applyStaticFilter($query, $static);
89
90
        if(isset($dynamic) && $dynamic = $this->clearDynamicFilters($dynamic, $category))
91
            $query = $this->applyDynamicFilter($query, $dynamic);
92
93
        $query->join('lots', 'lots.id', '=', 'products.lot_id')
94
            ->where('lots.status', Lot::STATUS_COMPLETE)
95
            ->where('lots.verify_status', Lot::STATUS_VERIFY_ACCEPTED);
96
97
        if($subcategory)
98
        {
99
            // todo: fix it, subcategory don;t incoming..
100
            $query = $query->where('products.sub_category_id', $subcategory->id);
101
//            $query->where('products.sub_category_id', $subcategory->id);
0 ignored issues
show
Unused Code Comprehensibility introduced by
70% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
102
        }
103
104
        return $query->where('products.active', 1)->paginate($perPage);
105
    }
106
107
    /**
108
     * Apply static filters.
109
     *
110
     * @param $query
111
     * @param array|null $filters
112
     *
113
     * @return \Illuminate\Database\Eloquent\Builder
114
     */
115
    protected function applyStaticFilter($query, array $filters = null)
116
    {
117
        /** Price range static filter. */
118
        if(isset($filters['price_min']) && isset($filters['price_max']))
119
        {
120
            $query->where(function($q) use ($filters){
121
                $q->whereBetween('products.price', array($filters['price_min'], $filters['price_max']));
122
            });
123
        }
124
125
        return $query;
126
    }
127
128
    /**
129
     * Apply static filters.
130
     *
131
     * @param $query
132
     * @param array|null $filters
133
     *
134
     * @return \Illuminate\Database\Eloquent\Builder
135
     */
136
    protected function applyDynamicFilter($query, array $filters = null)
137
    {
138
        $tags = '';
139
        $i = 1;
140
        $dynamic_count = count($filters);
141
        array_walk($filters, function($filter_val, $filter) use (&$query, &$tags, $filters, $dynamic_count, &$i){
142
            list($group, $tag) = $this->parseDynamicFilter($filter);
0 ignored issues
show
Unused Code introduced by
The assignment to $group is unused. Consider omitting it like so list($first,,$third).

This checks looks for assignemnts to variables using the list(...) function, where not all assigned variables are subsequently used.

Consider the following code example.

<?php

function returnThreeValues() {
    return array('a', 'b', 'c');
}

list($a, $b, $c) = returnThreeValues();

print $a . " - " . $c;

Only the variables $a and $c are used. There was no need to assign $b.

Instead, the list call could have been.

list($a,, $c) = returnThreeValues();
Loading history...
143
144
            if($i !== $dynamic_count)
145
            {
146
                $tags .= sprintf('%s,', $tag);
147
            } else {
148
                $tags .= $tag;
149
            }
150
151
            $i++;
152
        });
153
154
        /**
155
         * Query tags scopes..
156
         *
157
         * Model::withAllTags('apple,banana,cherry');
158
         *  - returns models that are tagged with all 3 of those tags
159
         *
160
         * Model::withAnyTags('apple,banana,cherry');
161
         *  - returns models with any one of those 3 tags
162
         *
163
         * Model::withAnyTags();
164
         * - returns models with any tags at all
165
         *
166
         * @attention: for more info. check https://github.com/cviebrock/eloquent-taggable docs.
167
         */
168
        $query->withAllTags($tags);
169
170
        return $query;
171
    }
172
173
    /**
174
     * Clear static filters.
175
     *
176
     * @param $filters
177
     *
178
     * @return array|null
179
     */
180
    protected function clearStaticFilters($filters)
181
    {
182
        $available_filters = array_flip($this->getStaticFilters());
183
184
        $filters = array_filter($filters, function($filter_v, $filter_k) use ($available_filters){
185
            return isset($available_filters[$filter_k]);
186
        }, ARRAY_FILTER_USE_BOTH);
187
188
        return (!empty($filters)) ? $filters : null;
189
    }
190
191
    /**
192
     * Clean dynamic filters.
193
     *
194
     * @param $filters
195
     * @param \App\Category $category
196
     *
197
     * @return array|null
198
     */
199
    protected function clearDynamicFilters($filters, $category)
200
    {
201
        $available_filters = $this->tags->getAvailableDynamicFilters($category);
202
203
        $filters = array_filter($filters, function($filter) use ($available_filters){
204
            if($this->isDynamicFilter($filter))
205
            {
206
                list($group, $tag) = $this->parseDynamicFilter($filter);
207
208
                if (isset($available_filters[$group]))
209
                    return in_array($tag, $available_filters[$group]);
210
            }
211
        }, ARRAY_FILTER_USE_KEY);
212
213
        return (!empty($filters)) ? $filters : null;
214
    }
215
216
    /**
217
     * Separate filters.
218
     *
219
     * @param $filters
220
     *
221
     * @return array
222
     */
223
    protected function separateFilters($filters)
224
    {
225
        $static_filters = $this->getStaticFilters();
226
227
        $static = [];
228
        $dynamic = $filters;
229
        array_walk($static_filters, function($static_filter) use (&$static, &$dynamic){
230
            if(isset($dynamic[$static_filter]))
231
            {
232
                $static[$static_filter] = $dynamic[$static_filter];
233
234
                unset($dynamic[$static_filter]);
235
            }
236
        });
237
238
        return [ $static, $dynamic ];
239
    }
240
241
    /**
242
     * Parse dynamic filter. First element must be an a group,
243
     * and the second is a tag.
244
     *
245
     * @param $filter
246
     *
247
     * @return array
248
     */
249
    public function parseDynamicFilter($filter)
250
    {
251
        $separator = $this->tags->getDynamicFilterSeparator();
252
253
        list($group, $tag) = explode($separator, $filter, 2);
254
255
        return [ $group, $tag ];
256
    }
257
258
    /**
259
     * Check if first argument is dynamic filter.
260
     * (todo: rework it. hardcoded)
261
     *
262
     * @param $filter
263
     * @return bool
264
     */
265
    public function isDynamicFilter($filter)
266
    {
267
        $separator = $this->tags->getDynamicFilterSeparator();
268
269
        $result = explode($separator, $filter, 2);
270
271
        return count($result) == 2;
272
    }
273
}