Completed
Pull Request — master (#2356)
by zzuutt
09:04
created

Category::parseResults()   D

Complexity

Conditions 14
Paths 31

Size

Total Lines 84
Code Lines 53

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 84
rs 4.9516
cc 14
eloc 53
nc 31
nop 1

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/*************************************************************************************/
3
/*      This file is part of the Thelia package.                                     */
4
/*                                                                                   */
5
/*      Copyright (c) OpenStudio                                                     */
6
/*      email : [email protected]                                                       */
7
/*      web : http://www.thelia.net                                                  */
8
/*                                                                                   */
9
/*      For the full copyright and license information, please view the LICENSE.txt  */
10
/*      file that was distributed with this source code.                             */
11
/*************************************************************************************/
12
13
namespace Thelia\Core\Template\Loop;
14
15
use Propel\Runtime\ActiveQuery\Criteria;
16
use Thelia\Core\Template\Element\BaseI18nLoop;
17
use Thelia\Core\Template\Element\LoopResult;
18
use Thelia\Core\Template\Element\LoopResultRow;
19
use Thelia\Core\Template\Element\PropelSearchLoopInterface;
20
use Thelia\Core\Template\Element\SearchLoopInterface;
21
use Thelia\Core\Template\Element\StandardI18nFieldsSearchTrait;
22
use Thelia\Core\Template\Loop\Argument\ArgumentCollection;
23
use Thelia\Core\Template\Loop\Argument\Argument;
24
use Thelia\Model\CategoryQuery;
25
use Thelia\Type\TypeCollection;
26
use Thelia\Type;
27
use Thelia\Type\BooleanOrBothType;
28
use Thelia\Model\ProductQuery;
29
use Thelia\Model\Category as CategoryModel;
30
31
/**
32
 *
33
 * Category loop, all params available :
34
 *
35
 * - id : can be an id (eq : 3) or a "string list" (eg: 3, 4, 5)
36
 * - parent : categories having this parent id
37
 * - current : current id is used if you are on a category page
38
 * - not_empty : if value is 1, category and subcategories must have at least 1 product
39
 * - visible : default 1, if you want category not visible put 0
40
 * - order : all value available :  'alpha', 'alpha_reverse', 'manual' (default), 'manual_reverse', 'random'
41
 * - exclude : all category id you want to exclude (as for id, an integer or a "string list" can be used)
42
 *
43
 * Class Category
44
 * @package Thelia\Core\Template\Loop
45
 * @author Manuel Raynaud <[email protected]>
46
 * @author Etienne Roudeix <[email protected]>
47
 *
48
 * {@inheritdoc}
49
 * @method int[] getId()
50
 * @method int[] getParent()
51
 * @method int[] getExcludeParent()
52
 * @method int[] getProduct()
53
 * @method int[] getExcludeProduct()
54
 * @method int[] getContent()
55
 * @method bool getCurrent()
56
 * @method bool getNotEmpty()
57
 * @method bool getWithPrevNextInfo()
58
 * @method bool getNeedCountChild()
59
 * @method bool getNeedProductCount()
60
 * @method bool|string getVisible()
61
 * @method int[] getExclude()
62
 * @method string[] getOrder()
63
 */
64
class Category extends BaseI18nLoop implements PropelSearchLoopInterface, SearchLoopInterface
65
{
66
    use StandardI18nFieldsSearchTrait;
67
68
    protected $timestampable = true;
69
    protected $versionable = true;
70
71
    /**
72
     * @return ArgumentCollection
73
     */
74
    protected function getArgDefinitions()
75
    {
76
        return new ArgumentCollection(
77
            Argument::createIntListTypeArgument('id'),
78
            Argument::createIntListTypeArgument('parent'),
79
            Argument::createIntListTypeArgument('exclude_parent'),
80
            Argument::createIntListTypeArgument('product'),
81
            Argument::createIntListTypeArgument('exclude_product'),
82
            Argument::createIntListTypeArgument('content'),
83
            Argument::createBooleanTypeArgument('current'),
84
            Argument::createBooleanTypeArgument('not_empty', 0),
85
            Argument::createBooleanTypeArgument('with_prev_next_info', false),
86
            Argument::createBooleanTypeArgument('need_count_child', false),
87
            Argument::createBooleanTypeArgument('need_product_count', false),
88
            Argument::createBooleanTypeArgument('product_count_visible_only', false),
89
            Argument::createBooleanOrBothTypeArgument('visible', 1),
90
            new Argument(
91
                'order',
92
                new TypeCollection(
93
                    new Type\EnumListType([
94
                        'id', 'id_reverse',
95
                        'alpha', 'alpha_reverse',
96
                        'manual', 'manual_reverse',
97
                        'visible', 'visible_reverse',
98
                        'created','created_reverse',
99
                        'updated', 'updated_reverse',
100
                        'random'
101
                    ])
102
                ),
103
                'manual'
104
            ),
105
            Argument::createIntListTypeArgument('exclude')
106
        );
107
    }
108
109
    /**
110
     * @return array of available field to search in
111
     */
112
    public function getSearchIn()
113
    {
114
        return $this->getStandardI18nSearchFields();
115
    }
116
117
    /**
118
     * @param CategoryQuery $search
119
     * @param string $searchTerm
120
     * @param array $searchIn
121
     * @param string $searchCriteria
122
     */
123
    public function doSearch(&$search, $searchTerm, $searchIn, $searchCriteria)
124
    {
125
        $search->_and();
126
    
127
        $this->addStandardI18nSearch($search, $searchTerm, $searchCriteria);
128
    }
129
130
    public function buildModelCriteria()
131
    {
132
        $search = CategoryQuery::create();
133
134
        /* manage translations */
135
        $this->configureI18nProcessing($search, array('TITLE', 'CHAPO', 'DESCRIPTION', 'POSTSCRIPTUM', 'META_TITLE', 'META_DESCRIPTION', 'META_KEYWORDS'));
136
137
        $id = $this->getId();
138
139
        if (!is_null($id)) {
140
            $search->filterById($id, Criteria::IN);
141
        }
142
143
        $parent = $this->getParent();
144
145
        if (null !== $parent) {
146
            $search->filterByParent($parent, Criteria::IN);
147
            $positionOrderAllowed = true;
0 ignored issues
show
Unused Code introduced by
$positionOrderAllowed is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
148
        } else {
149
            $positionOrderAllowed = false;
0 ignored issues
show
Unused Code introduced by
$positionOrderAllowed is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
150
        }
151
    
152
        $excludeParent = $this->getExcludeParent();
153
154
        if (!is_null($excludeParent)) {
155
            $search->filterByParent($excludeParent, Criteria::NOT_IN);
156
        }
157
158
        $current = $this->getCurrent();
159
160
        if ($current === true) {
161
            $search->filterById($this->getCurrentRequest()->get("category_id"));
162
        } elseif ($current === false) {
163
            $search->filterById($this->getCurrentRequest()->get("category_id"), Criteria::NOT_IN);
164
        }
165
166
        $exclude = $this->getExclude();
167
168
        if (!is_null($exclude)) {
169
            $search->filterById($exclude, Criteria::NOT_IN);
170
        }
171
172
        $visible = $this->getVisible();
173
174
        if ($visible !== BooleanOrBothType::ANY) {
175
            $search->filterByVisible($visible ? 1 : 0);
176
        }
177
178
        $products = $this->getProduct();
179
180
        if ($products != null) {
181
            $obj = ProductQuery::create()->findPks($products);
182
183
            if ($obj != null) {
184
                $search->filterByProduct($obj, Criteria::IN);
185
            }
186
        }
187
188
        $excludeProducts = $this->getExcludeProduct();
189
190
        if ($excludeProducts != null) {
191
            $obj = ProductQuery::create()->findPks($excludeProducts);
192
193
            if ($obj != null) {
194
                $search->filterByProduct($obj, Criteria::NOT_IN);
195
            }
196
        }
197
198
        $contentId = $this->getContent();
199
200
        if ($contentId != null) {
201
            $search->useCategoryAssociatedContentQuery()
202
                ->filterByContentId($contentId, Criteria::IN)
203
                ->endUse()
204
            ;
205
        }
206
207
        $orders = $this->getOrder();
208
209
        foreach ($orders as $order) {
210
            switch ($order) {
211
                case "id":
212
                    $search->orderById(Criteria::ASC);
213
                    break;
214
                case "id_reverse":
215
                    $search->orderById(Criteria::DESC);
216
                    break;
217
                case "alpha":
218
                    $search->addAscendingOrderByColumn('i18n_TITLE');
219
                    break;
220
                case "alpha_reverse":
221
                    $search->addDescendingOrderByColumn('i18n_TITLE');
222
                    break;
223
                case "manual_reverse":
224
                    $search->orderByPosition(Criteria::DESC);
225
                    break;
226
                case "manual":
227
                    $search->orderByPosition(Criteria::ASC);
228
                    break;
229
                case "visible":
230
                    $search->orderByVisible(Criteria::ASC);
231
                    break;
232
                case "visible_reverse":
233
                    $search->orderByVisible(Criteria::DESC);
234
                    break;
235
                case "created":
236
                    $search->addAscendingOrderByColumn('created_at');
237
                    break;
238
                case "created_reverse":
239
                    $search->addDescendingOrderByColumn('created_at');
240
                    break;
241
                case "updated":
242
                    $search->addAscendingOrderByColumn('updated_at');
243
                    break;
244
                case "updated_reverse":
245
                    $search->addDescendingOrderByColumn('updated_at');
246
                    break;
247
                case "random":
248
                    $search->clearOrderByColumns();
249
                    $search->addAscendingOrderByColumn('RAND()');
250
                    break(2);
251
                    break;
0 ignored issues
show
Unused Code introduced by
break; does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
252
            }
253
        }
254
255
        return $search;
256
    }
257
258
    public function parseResults(LoopResult $loopResult)
259
    {
260
        /** @var CategoryModel $category */
261
        foreach ($loopResult->getResultDataCollection() as $category) {
262
            /*
263
             * no cause pagination lost :
264
             * if ($this->getNotEmpty() && $category->countAllProducts() == 0) continue;
265
             */
266
267
            $loopResultRow = new LoopResultRow($category);
268
269
            $loopResultRow
270
                ->set("ID", $category->getId())
271
                ->set("IS_TRANSLATED", $category->getVirtualColumn('IS_TRANSLATED'))
272
                ->set("LOCALE", $this->locale)
273
                ->set("TITLE", $category->getVirtualColumn('i18n_TITLE'))
274
                ->set("CHAPO", $category->getVirtualColumn('i18n_CHAPO'))
275
                ->set("DESCRIPTION", $category->getVirtualColumn('i18n_DESCRIPTION'))
276
                ->set("POSTSCRIPTUM", $category->getVirtualColumn('i18n_POSTSCRIPTUM'))
277
                ->set("PARENT", $category->getParent())
278
                ->set("ROOT", $category->getRoot($category->getId()))
279
                ->set("URL", $this->getReturnUrl() ? $category->getUrl($this->locale) : null)
280
                ->set("META_TITLE", $category->getVirtualColumn('i18n_META_TITLE'))
281
                ->set("META_DESCRIPTION", $category->getVirtualColumn('i18n_META_DESCRIPTION'))
282
                ->set("META_KEYWORDS", $category->getVirtualColumn('i18n_META_KEYWORDS'))
283
                ->set("VISIBLE", $category->getVisible() ? "1" : "0")
284
                ->set("POSITION", $category->getPosition())
285
                ->set("TEMPLATE", $category->getDefaultTemplateId());
286
287
            if ($this->getNeedCountChild()) {
288
                $loopResultRow->set("CHILD_COUNT", $category->countChild());
289
            }
290
291
            if ($this->getNeedProductCount()) {
292
                if ($this->getProductCountVisibleOnly()) {
0 ignored issues
show
Documentation Bug introduced by
The method getProductCountVisibleOnly does not exist on object<Thelia\Core\Template\Loop\Category>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
293
                    $loopResultRow->set("PRODUCT_COUNT", $category->countAllProductsVisibleOnly());
294
                }
295
                else {
296
                    $loopResultRow->set("PRODUCT_COUNT", $category->countAllProducts());
297
                }
298
            }
299
300
            $isBackendContext = $this->getBackendContext();
301
302
            if ($this->getWithPrevNextInfo()) {
303
                // Find previous and next category
304
                $previousQuery = CategoryQuery::create()
305
                    ->filterByParent($category->getParent())
306
                    ->filterByPosition($category->getPosition(), Criteria::LESS_THAN);
307
308
                if (! $isBackendContext) {
309
                    $previousQuery->filterByVisible(true);
310
                }
311
312
                $previous = $previousQuery
313
                    ->orderByPosition(Criteria::DESC)
314
                    ->findOne();
315
316
                $nextQuery = CategoryQuery::create()
317
                    ->filterByParent($category->getParent())
318
                    ->filterByPosition($category->getPosition(), Criteria::GREATER_THAN);
319
320
                if (! $isBackendContext) {
321
                    $nextQuery->filterByVisible(true);
322
                }
323
324
                $next = $nextQuery
325
                    ->orderByPosition(Criteria::ASC)
326
                    ->findOne();
327
328
                $loopResultRow
329
                    ->set("HAS_PREVIOUS", $previous != null ? 1 : 0)
330
                    ->set("HAS_NEXT", $next != null ? 1 : 0)
331
                    ->set("PREVIOUS", $previous != null ? $previous->getId() : -1)
332
                    ->set("NEXT", $next != null ? $next->getId() : -1);
333
            }
334
335
            $this->addOutputFields($loopResultRow, $category);
336
337
            $loopResult->addRow($loopResultRow);
338
        }
339
340
        return $loopResult;
341
    }
342
}
343