Completed
Push — master ( 2bd64d...2b5c6e )
by Gilles
19:35 queued 14:50
created

ProductSaleElements   B

Complexity

Total Complexity 43

Size/Duplication

Total Lines 268
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 43
eloc 179
dl 0
loc 268
rs 8.96
c 0
b 0
f 0

5 Methods

Rating   Name   Duplication   Size   Complexity  
F buildModelCriteria() 0 128 27
B parseResults() 0 59 9
A doSearch() 0 15 5
A getArgDefinitions() 0 34 1
A getSearchIn() 0 5 1

How to fix   Complexity   

Complex Class

Complex classes like ProductSaleElements often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use ProductSaleElements, and based on these observations, apply Extract Interface, too.

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\BaseLoop;
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\Loop\Argument\Argument;
22
use Thelia\Core\Template\Loop\Argument\ArgumentCollection;
23
use Thelia\Exception\TaxEngineException;
24
use Thelia\Model\Currency as CurrencyModel;
25
use Thelia\Model\CurrencyQuery;
26
use Thelia\Model\Map\ProductSaleElementsTableMap;
0 ignored issues
show
Bug introduced by
The type Thelia\Model\Map\ProductSaleElementsTableMap was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
27
use Thelia\Model\ProductSaleElementsQuery;
28
use Thelia\Type;
29
use Thelia\Type\TypeCollection;
30
31
/**
32
 *
33
 * Product Sale Elements loop
34
 *
35
 * @todo : manage attribute_availability ?
36
 *
37
 * Class ProductSaleElements
38
 * @package Thelia\Core\Template\Loop
39
 * @author Etienne Roudeix <[email protected]>
40
 *
41
 * {@inheritdoc}
42
 * @method int[] getId()
43
 * @method int getCurrency()
44
 * @method int getProduct()
45
 * @method bool getPromo()
46
 * @method bool getNew()
47
 * @method bool getDefault()
48
 * @method string getRef()
49
 * @method int[] getAttributeAvailability()
50
 * @method string[] getOrder()
51
 */
52
class ProductSaleElements extends BaseLoop implements PropelSearchLoopInterface, SearchLoopInterface
53
{
54
    protected $timestampable = true;
55
56
    /**
57
     * @return ArgumentCollection
58
     */
59
    protected function getArgDefinitions()
60
    {
61
        return new ArgumentCollection(
62
            Argument::createIntListTypeArgument('id'),
63
            Argument::createIntTypeArgument('currency'),
64
            Argument::createIntTypeArgument('product'),
65
            Argument::createBooleanTypeArgument('promo'),
66
            Argument::createBooleanTypeArgument('new'),
67
            Argument::createBooleanTypeArgument('default'),
68
            Argument::createAnyTypeArgument('ref'),
69
            new Argument(
70
                'attribute_availability',
71
                new TypeCollection(
72
                    new Type\IntToCombinedIntsListType()
73
                )
74
            ),
75
            new Argument(
76
                'order',
77
                new TypeCollection(
78
                    new Type\EnumListType(
79
                        array(
80
                            'id', 'id_reverse',
81
                            'ref', 'ref_reverse',
82
                            'quantity', 'quantity_reverse',
83
                            'min_price', 'max_price',
84
                            'promo', 'new',
85
                            'weight', 'weight_reverse',
86
                            'created', 'created_reverse',
87
                            'updated', 'updated_reverse',
88
                            'random'
89
                        )
90
                    )
91
                ),
92
                'random'
93
            )
94
        );
95
    }
96
97
    public function buildModelCriteria()
98
    {
99
        $search = ProductSaleElementsQuery::create();
100
101
        $id = $this->getId();
102
        $product = $this->getProduct();
103
        $ref = $this->getRef();
104
105
        if (! is_null($id)) {
0 ignored issues
show
introduced by
The condition is_null($id) is always false.
Loading history...
106
            $search->filterById($id, Criteria::IN);
107
        }
108
109
        if (! is_null($product)) {
0 ignored issues
show
introduced by
The condition is_null($product) is always false.
Loading history...
110
            $search->filterByProductId($product, Criteria::EQUAL);
111
        }
112
113
        if (! is_null($ref)) {
0 ignored issues
show
introduced by
The condition is_null($ref) is always false.
Loading history...
114
            $search->filterByRef($ref, Criteria::EQUAL);
115
        }
116
117
        $promo = $this->getPromo();
118
119
        if (null !== $promo) {
0 ignored issues
show
introduced by
The condition null !== $promo is always true.
Loading history...
120
            $search->filterByPromo($promo);
121
        }
122
123
        $new = $this->getNew();
124
125
        if (null !== $new) {
0 ignored issues
show
introduced by
The condition null !== $new is always true.
Loading history...
126
            $search->filterByNewness($new);
127
        }
128
129
        $default = $this->getDefault();
130
131
        if (null !== $default) {
0 ignored issues
show
introduced by
The condition null !== $default is always true.
Loading history...
132
            $search->filterByIsDefault($default);
133
        }
134
135
        $orders  = $this->getOrder();
136
137
        foreach ($orders as $order) {
138
            switch ($order) {
139
                case "id":
140
                    $search->orderById(Criteria::ASC);
141
                    break;
142
                case "id_reverse":
143
                    $search->orderById(Criteria::DESC);
144
                    break;
145
                case "ref":
146
                    $search->orderByRef(Criteria::ASC);
147
                    break;
148
                case "ref_reverse":
149
                    $search->orderByRef(Criteria::DESC);
150
                    break;
151
                case "quantity":
152
                    $search->orderByQuantity(Criteria::ASC);
153
                    break;
154
                case "quantity_reverse":
155
                    $search->orderByQuantity(Criteria::DESC);
156
                    break;
157
                case "min_price":
158
                    $search->addAscendingOrderByColumn('price_FINAL_PRICE');
159
                    break;
160
                case "max_price":
161
                    $search->addDescendingOrderByColumn('price_FINAL_PRICE');
162
                    break;
163
                case "promo":
164
                    $search->orderByPromo(Criteria::DESC);
165
                    break;
166
                case "new":
167
                    $search->orderByNewness(Criteria::DESC);
168
                    break;
169
                case "weight":
170
                    $search->orderByWeight(Criteria::ASC);
171
                    break;
172
                case "weight_reverse":
173
                    $search->orderByWeight(Criteria::DESC);
174
                    break;
175
                case "created":
176
                    $search->addAscendingOrderByColumn('created_at');
177
                    break;
178
                case "created_reverse":
179
                    $search->addDescendingOrderByColumn('created_at');
180
                    break;
181
                case "updated":
182
                    $search->addAscendingOrderByColumn('updated_at');
183
                    break;
184
                case "updated_reverse":
185
                    $search->addDescendingOrderByColumn('updated_at');
186
                    break;
187
                case "random":
188
                    $search->clearOrderByColumns();
189
                    $search->addAscendingOrderByColumn('RAND()');
190
                    break(2);
191
            }
192
        }
193
194
        $currencyId = $this->getCurrency();
195
        if (null !== $currencyId) {
0 ignored issues
show
introduced by
The condition null !== $currencyId is always true.
Loading history...
196
            $currency = CurrencyQuery::create()->findPk($currencyId);
197
            if (null === $currency) {
198
                throw new \InvalidArgumentException('Cannot found currency id: `' . $currency . '` in product_sale_elements loop');
199
            }
200
        } else {
201
            $currency = $this->getCurrentRequest()->getSession()->getCurrency();
202
        }
203
204
        $defaultCurrency = CurrencyModel::getDefaultCurrency();
205
        $defaultCurrencySuffix = '_default_currency';
206
207
        $search->joinProductPrice('price', Criteria::LEFT_JOIN)
208
            ->addJoinCondition('price', '`price`.`currency_id` = ?', $currency->getId(), null, \PDO::PARAM_INT);
209
210
        $search->joinProductPrice('price' . $defaultCurrencySuffix, Criteria::LEFT_JOIN)
211
            ->addJoinCondition('price_default_currency', '`price' . $defaultCurrencySuffix . '`.`currency_id` = ?', $defaultCurrency->getId(), null, \PDO::PARAM_INT);
212
213
        /**
214
         * rate value is checked as a float in overloaded getRate method.
215
         */
216
        $priceSelectorAsSQL = 'CASE WHEN ISNULL(`price`.PRICE) OR `price`.FROM_DEFAULT_CURRENCY = 1 THEN `price_default_currency`.PRICE * ' . $currency->getRate() . ' ELSE `price`.PRICE END';
217
        $promoPriceSelectorAsSQL = 'CASE WHEN ISNULL(`price`.PRICE) OR `price`.FROM_DEFAULT_CURRENCY = 1 THEN `price_default_currency`.PROMO_PRICE  * ' . $currency->getRate() . ' ELSE `price`.PROMO_PRICE END';
218
        $search->withColumn($priceSelectorAsSQL, 'price_PRICE')
219
            ->withColumn($promoPriceSelectorAsSQL, 'price_PROMO_PRICE')
220
            ->withColumn('CASE WHEN ' . ProductSaleElementsTableMap::COL_PROMO . ' = 1 THEN ' . $promoPriceSelectorAsSQL . ' ELSE ' . $priceSelectorAsSQL . ' END', 'price_FINAL_PRICE');
221
222
        $search->groupById();
223
224
        return $search;
225
    }
226
227
    public function parseResults(LoopResult $loopResult)
228
    {
229
        $taxCountry = $this->container->get('thelia.taxEngine')->getDeliveryCountry();
230
        /** @var \Thelia\Core\Security\SecurityContext $securityContext */
231
        $securityContext = $this->container->get('thelia.securityContext');
232
        $discount = 0;
233
234
        if ($securityContext->hasCustomerUser() && $securityContext->getCustomerUser()->getDiscount() > 0) {
235
            $discount = $securityContext->getCustomerUser()->getDiscount();
236
        }
237
238
        /** @var \Thelia\Model\ProductSaleElements $PSEValue */
239
        foreach ($loopResult->getResultDataCollection() as $PSEValue) {
240
            $loopResultRow = new LoopResultRow($PSEValue);
241
242
            $price = $PSEValue->getPrice('price_PRICE', $discount);
243
            try {
244
                $taxedPrice = $PSEValue->getTaxedPrice(
245
                    $taxCountry,
246
                    'price_PRICE',
247
                    $discount
248
                );
249
            } catch (TaxEngineException $e) {
250
                $taxedPrice = null;
251
            }
252
253
            $promoPrice = $PSEValue->getPromoPrice('price_PROMO_PRICE', $discount);
254
            try {
255
                $taxedPromoPrice = $PSEValue->getTaxedPromoPrice(
256
                    $taxCountry,
257
                    'price_PROMO_PRICE',
258
                    $discount
259
                );
260
            } catch (TaxEngineException $e) {
261
                $taxedPromoPrice = null;
262
            }
263
264
            $loopResultRow
265
                ->set("ID", $PSEValue->getId())
266
                ->set("QUANTITY", $PSEValue->getQuantity())
267
                ->set("IS_PROMO", $PSEValue->getPromo() === 1 ? 1 : 0)
268
                ->set("IS_NEW", $PSEValue->getNewness() === 1 ? 1 : 0)
269
                ->set("IS_DEFAULT", $PSEValue->getIsDefault() ? 1 : 0)
270
                ->set("WEIGHT", $PSEValue->getWeight())
271
                ->set("REF", $PSEValue->getRef())
272
                ->set("EAN_CODE", $PSEValue->getEanCode())
273
                ->set("PRODUCT_ID", $PSEValue->getProductId())
274
                ->set("PRICE", $price)
275
                ->set("PRICE_TAX", $taxedPrice - $price)
276
                ->set("TAXED_PRICE", $taxedPrice)
277
                ->set("PROMO_PRICE", $promoPrice)
278
                ->set("PROMO_PRICE_TAX", $taxedPromoPrice - $promoPrice)
279
                ->set("TAXED_PROMO_PRICE", $taxedPromoPrice);
280
281
            $this->addOutputFields($loopResultRow, $PSEValue);
282
            $loopResult->addRow($loopResultRow);
283
        }
284
285
        return $loopResult;
286
    }
287
288
    /**
289
     * @return array of available field to search in
290
     */
291
    public function getSearchIn()
292
    {
293
        return [
294
            "ref",
295
            "ean_code"
296
        ];
297
    }
298
299
    /**
300
     * @param ProductSaleElementsQuery $search
301
     * @param $searchTerm
302
     * @param $searchIn
303
     * @param $searchCriteria
304
     */
305
    public function doSearch(&$search, $searchTerm, $searchIn, $searchCriteria)
306
    {
307
        $search->_and();
308
309
        foreach ($searchIn as $index => $searchInElement) {
310
            if ($index > 0) {
311
                $search->_or();
312
            }
313
            switch ($searchInElement) {
314
                case "ref":
315
                    $search->filterByRef($searchTerm, $searchCriteria);
316
                    break;
317
                case "ean_code":
318
                    $search->filterByEanCode($searchTerm, $searchCriteria);
319
                    break;
320
            }
321
        }
322
    }
323
}
324