GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Test Setup Failed
Push — action_getCatTree_order ( 77944b )
by
unknown
23:56
created

CartController::behaviors()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 3

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 8
rs 9.4285
cc 1
eloc 3
nc 1
nop 0
1
<?php
2
3
namespace app\modules\shop\controllers;
4
5
use app\modules\core\behaviors\DisableRobotIndexBehavior;
6
use app\modules\core\helpers\EventTriggeringHelper;
7
use app\modules\core\models\Events;
8
use app\modules\shop\helpers\PriceHelper;
9
use app\modules\shop\events\OrderStageEvent;
10
use app\modules\shop\events\OrderStageLeafEvent;
11
use app\modules\shop\models\Currency;
12
use app\modules\shop\models\Order;
13
use app\modules\shop\models\OrderCode;
14
use app\modules\shop\models\OrderItem;
15
use app\modules\shop\models\OrderStage;
16
use app\modules\shop\models\OrderStageLeaf;
17
use app\modules\shop\models\Product;
18
use app\modules\shop\models\SpecialPriceList;
19
use app\modules\shop\ShopModule;
20
use yii\helpers\Url;
21
use Yii;
22
use yii\helpers\ArrayHelper;
23
use yii\web\BadRequestHttpException;
24
use yii\web\Controller;
25
use yii\web\NotFoundHttpException;
26
use yii\web\Response;
27
28
/**
29
 * Class CartController
30
 * @package app\modules\shop\controllers
31
 * @property ShopModule $module
32
 */
33
class CartController extends Controller
34
{
35
    public function behaviors()
36
    {
37
        return [
38
            [
39
                'class' => DisableRobotIndexBehavior::className(),
40
            ]
41
        ];
42
    }
43
44
    /**
45
     * Get Order.
46
     * @param bool $create Create order if it does not exist
47
     * @param bool $throwException Throw exception if it does not exist
48
     * @return null|Order
49
     * @throws NotFoundHttpException
50
     */
51
    protected function loadOrder($create = false, $throwException = true)
52
    {
53
        $model = Order::getOrder($create);
54
        if (is_null($model) && $throwException) {
55
            throw new NotFoundHttpException;
56
        }
57
        return $model;
58
    }
59
60
    /**
61
     * Get OrderItem.
62
     * @param int $id
63
     * @param bool $checkOrderAttachment
64
     * @return OrderItem
0 ignored issues
show
Documentation introduced by
Should the return type not be array|boolean? Also, consider making the array more specific, something like array<String>, or String[].

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

If the return type contains the type array, this check recommends the use of a more specific type like String[] or array<String>.

Loading history...
65
     * @throws NotFoundHttpException
66
     */
67
    protected function loadOrderItem($id, $checkOrderAttachment = true)
68
    {
69
        /** @var OrderItem $orderItemModel */
70
        $orderModel = $checkOrderAttachment ? $this->loadOrder() : null;
71
        $orderItemModel = OrderItem::findOne($id);
72
        if (is_null($orderItemModel)
73
            || ($checkOrderAttachment && (is_null($orderModel) || $orderItemModel->order_id != $orderModel->id))
74
        ) {
75
            throw new NotFoundHttpException;
76
        }
77
        return $orderItemModel;
78
    }
79
80
    protected function addProductsToOrder($products, $parentId = 0)
81
    {
82
        if (!is_array($products)) {
83
            throw new BadRequestHttpException;
84
        }
85
        $order = $this->loadOrder(true);
86
        $result = [
87
            'errors' => [],
88
            'itemModalPreview' => '',
89
        ];
90
        foreach ($products as $product) {
91
            if (!isset($product['id']) || is_null($productModel = Product::findById($product['id']))) {
92
                $result['errors'][] = Yii::t('app', 'Product not found.');
93
                continue;
94
            }
95
            /** @var Product $productModel */
96
            $quantity = isset($product['quantity']) && (double) $product['quantity'] > 0
97
                ? (double) $product['quantity']
98
                : 1;
99
            $quantity = $productModel->measure->ceilQuantity($quantity);
100
            if ($this->module->allowToAddSameProduct
101
                || is_null($orderItem = OrderItem::findOne(['order_id' => $order->id, 'product_id' => $productModel->id, 'parent_id' => 0]))
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 140 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
102
            ) {
103
                $orderItem = new OrderItem;
104
                $orderItem->attributes = [
105
                    'parent_id' => $parentId,
106
                    'order_id' => $order->id,
107
                    'product_id' => $productModel->id,
108
                    'quantity' => $quantity,
109
                    'price_per_pcs' =>  PriceHelper::getProductPrice(
110
                        $productModel,
111
                        $order,
112
                        1,
113
                        SpecialPriceList::TYPE_CORE
114
                    ),
115
                ];
116
            } else {
117
                /** @var OrderItem $orderItem */
118
                $orderItem->quantity += $quantity;
119
            }
120
            if (!$orderItem->save()) {
121
                $result['errors'][] = Yii::t('app', 'Cannot save order item.');
122
            } else {
123
                // refresh order
124
                Order::clearStaticOrder();
125
                $order = $this->loadOrder(false);
126
            }
127
            if (isset($product['children'])) {
128
                $result = ArrayHelper::merge(
129
                    $result,
130
                    $this->addProductsToOrder($product['children'], $orderItem->id)
131
                );
132
            }
133
            if ($parentId === 0) {
134
                $result['itemModalPreview'] .= $this->renderPartial(
135
                    'item-modal-preview',
136
                    [
137
                        'order' => $order,
138
                        'orderItem' => $orderItem,
139
                        'product' => $product,
140
                    ]
141
                );
142
            }
143
        }
144
        if ($parentId === 0) {
145
            $order->calculate(true);
146
        }
147
        $mainCurrency = Currency::getMainCurrency();
148
        return ArrayHelper::merge(
149
            $result,
150
            [
151
                'itemsCount' => $order->items_count,
152
                'success' => true, // @todo Return true success value
0 ignored issues
show
Coding Style Best Practice introduced by
Comments for TODO tasks are often forgotten in the code; it might be better to use a dedicated issue tracker.
Loading history...
153
                'totalPrice' => $mainCurrency->format($order->total_price),
154
            ]
155
        );
156
    }
157
158
    public function actionAdd()
159
    {
160
        Yii::$app->response->format = Response::FORMAT_JSON;
161
        if (!is_array(Yii::$app->request->post('products', null))) {
162
            throw new BadRequestHttpException;
163
        }
164
        $order = $this->loadOrder(true);
165
        if (is_null($order->stage) || $order->stage->immutable_by_user == 1) {
166
            throw new BadRequestHttpException;
167
        }
168
        return $this->addProductsToOrder(Yii::$app->request->post('products'));
169
    }
170
171
    public function actionChangeQuantity()
172
    {
173
        Yii::$app->response->format = Response::FORMAT_JSON;
174
        $id = Yii::$app->request->post('id');
175
        $quantity = Yii::$app->request->post('quantity');
176
        if (is_null($id) || is_null($quantity) || (double) $quantity <= 0) {
177
            throw new BadRequestHttpException;
178
        }
179
        $orderItem = $this->loadOrderItem($id);
180
        $order = $this->loadOrder();
181
        if (is_null($order->stage) || $order->stage->immutable_by_user == 1) {
182
            throw new BadRequestHttpException;
183
        }
184
        $orderItem->quantity = $orderItem->product->measure->ceilQuantity($quantity);
185
        // @todo Consider lock_product_price ?
0 ignored issues
show
Coding Style Best Practice introduced by
Comments for TODO tasks are often forgotten in the code; it might be better to use a dedicated issue tracker.
Loading history...
186
        if ($orderItem->lock_product_price == 0) {
187
            $orderItem->price_per_pcs = PriceHelper::getProductPrice(
188
                $orderItem->product,
189
                $order,
190
                1,
191
                SpecialPriceList::TYPE_CORE
192
            );
193
        }
194
        $orderItem->save();
0 ignored issues
show
Bug introduced by
The method save cannot be called on $orderItem (of type array|boolean).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
195
        $mainCurrency = Currency::getMainCurrency();
196
        if ($order->calculate(true)) {
197
            return [
198
                'success' => true,
199
                'itemsCount' => $order->items_count,
200
                'itemPrice' => $mainCurrency->format($orderItem->total_price),
201
                'totalPrice' => $mainCurrency->format($order->total_price),
202
                'calculatedQuantity' => $orderItem->quantity,
203
            ];
204
        } else {
205
            return [
206
                'success' => false,
207
                'message' => Yii::t('app', 'Cannot change quantity'),
208
            ];
209
        }
210
    }
211
212
    /**
213
     * Delete OrderItem action.
214
     * @param int $id
215
     * @throws NotFoundHttpException
216
     * @throws \Exception
217
     * @return array
218
     */
219
    public function actionDelete($id)
220
    {
221
        Yii::$app->response->format = Response::FORMAT_JSON;
222
        $order = $this->loadOrder();
223
        if (is_null($order->stage) || $order->stage->immutable_by_user == 1) {
224
            throw new BadRequestHttpException;
225
        }
226
        if ($this->loadOrderItem($id)->delete() && $order->calculate(true)) {
0 ignored issues
show
Bug introduced by
The method delete cannot be called on $this->loadOrderItem($id) (of type array|boolean).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
227
            $mainCurrency = Currency::getMainCurrency();
228
            return [
229
                'success' => true,
230
                'itemsCount' => $order->items_count,
231
                'totalPrice' => $mainCurrency->format($order->total_price),
232
                'itemModalPreview' => $this->renderPartial("item-modal-preview",
233
                    [
234
                        "order" => $order,
235
                        "orderItem" => null,
236
                        "product" => null
237
                    ]
238
                )
239
            ];
240
        } else {
241
            return [
242
                'success' => false,
243
                'message' => Yii::t('app', 'Cannot change additional params'),
244
            ];
245
        }
246
    }
247
248
    public function actionClear()
249
    {
250
        Yii::$app->response->format = Response::FORMAT_JSON;
251
        $order = $this->loadOrder();
252
        foreach ($order->items as $item) {
253
            $item->delete();
254
        }
255
        $order->calculate(true);
256
        return ['success' => true,];
257
    }
258
259
    public function actionIndex()
260
    {
261
        $model = $this->loadOrder(false, false);
262
        $orderCode = null;
263
        if (!is_null($model)) {
264
            $orderCode = OrderCode::find()
265
                ->where(
266
                    [
267
                        'order_id' => $model->id,
268
                        'status' => 1
269
                    ]
270
                )
271
                ->one();
272
273
            if ($orderCode === null) {
274
                $orderCode = new OrderCode();
275
276
                if (Yii::$app->request->isPost) {
277
                    $orderCode->load(Yii::$app->request->post());
278
                    $orderCode->order_id = $model->id;
279
                    if ($orderCode->save()) {
280
                        $this->refresh();
281
                    }
282
                }
283
            }
284
            $model->calculate();
285
        }
286
        return $this->render('index', ['model' => $model, 'orderCode' => $orderCode]);
287
    }
288
289
    /**
290
     * @return string|Response
291
     * @throws NotFoundHttpException
292
     */
293
    public function actionStage()
294
    {
295
        $order = $this->loadOrder(false, false);
296
        if (empty($order) || $order->getImmutability(Order::IMMUTABLE_USER)) {
297
            return $this->redirect(Url::to(['index']));
298
        }
299
300
        /** @var OrderStage $orderStage */
301
        $orderStage = $order->stage;
302
        $eventData = ['order' => $order];
303
304
        if (0 === intval($orderStage->is_in_cart)) {
305
            Yii::$app->session->remove('orderId');
306
            $order->in_cart = 0;
307
            $order->save();
308
            Order::clearStaticOrder();
309
        }
310
        if (1 === intval($orderStage->become_non_temporary)) {
311
            $order->temporary = 0;
312
            $order->save();
313
        }
314
315
//        if (null !== Yii::$app->session->get('OrderStageReach')) {
0 ignored issues
show
Unused Code Comprehensibility introduced by
60% 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...
316
        /** @var Events $eventClass */
317
        $eventClass = Events::findByName($orderStage->event_name);
318
        if (!empty($eventClass) && is_subclass_of($eventClass->event_class_name, OrderStageEvent::className())) {
0 ignored issues
show
Bug introduced by
Due to PHP Bug #53727, is_subclass_of might return inconsistent results on some PHP versions if \app\modules\shop\events...StageEvent::className() can be an interface. If so, you could instead use ReflectionClass::implementsInterface.
Loading history...
319
            /** @var OrderStageEvent $event */
320
            $event = new $eventClass->event_class_name;
321
            $event->setEventData($eventData);
322
            EventTriggeringHelper::triggerSpecialEvent($event);
323
            $eventData = $event->eventData();
324
325
            if (!empty($eventData['__redirect'])) {
326
                return $this->redirect($eventData['__redirect']);
327
            }
328
        }
329
        Yii::$app->session->remove('OrderStageReach');
330
//        }
331
332
        return $this->render(
333
            'stage',
334
            [
335
                'order' => $order,
336
                'stage' => $orderStage,
337
                'eventData' => $eventData,
338
            ]
339
        );
340
    }
341
342
    /**
343
     * @param null $id
344
     * @return Response
345
     * @throws NotFoundHttpException
346
     * @throws \yii\base\Exception
347
     */
348
    public function actionStageLeaf($id = null)
349
    {
350
        if (empty($id)) {
351
            return $this->redirect(Url::to(['stage']));
352
        }
353
        /** @var OrderStageLeaf $orderStageLeaf */
354
        $orderStageLeaf = OrderStageLeaf::findOne(['id' => $id]);
355
        if (empty($orderStageLeaf)) {
356
            return $this->redirect(Url::to(['stage']));
357
        }
358
359
        $order = $this->loadOrder(false, false);
360
        if (empty($order)) {
361
            return $this->redirect(Url::to(['index']));
362
        }
363
364
        $orderStage = $order->stage;
365
        if ($orderStage->id !== $orderStageLeaf->stage_from_id && $orderStage->id !== $orderStageLeaf->stage_to_id) {
366
            return $this->redirect(Url::to(['stage']));
367
        }
368
369
        if (null !== Yii::$app->request->get('previous') && 1 !== intval($orderStageLeaf->stageFrom->immutable_by_user)) {
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 122 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
370
            $order->order_stage_id = $orderStageLeaf->stageFrom->id;
371
            $order->save();
372
        } else {
373
            /** @var Events $eventClassName */
374
            $eventClassName = Events::findByName($orderStageLeaf->event_name);
375
            if (!empty($eventClassName) && is_subclass_of($eventClassName->event_class_name, OrderStageLeafEvent::className())) {
0 ignored issues
show
Bug introduced by
Due to PHP Bug #53727, is_subclass_of might return inconsistent results on some PHP versions if \app\modules\shop\events...eLeafEvent::className() can be an interface. If so, you could instead use ReflectionClass::implementsInterface.
Loading history...
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 129 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
376
                /** @var OrderStageLeafEvent $event */
377
                $event = new $eventClassName->event_class_name;
378
                EventTriggeringHelper::triggerSpecialEvent($event);
379
                if ($event->getStatus()) {
380
                    $order->order_stage_id = $order->order_stage_id == $orderStageLeaf->stage_to_id
381
                        ? $orderStageLeaf->stage_from_id
382
                        : $orderStageLeaf->stage_to_id;
383
                    $order->save();
384
385
                    Yii::$app->session->set('OrderStageReach', true);
386
                }
387
            }
388
        }
389
390
        return $this->redirect(Url::to(['stage']));
391
    }
392
}
393