Completed
Push — master ( c6b5de...db50e7 )
by Dmitry
04:45
created

src/cart/CartCalculator.php (1 issue)

Check for undocumented magic property with write access

Documentation Minor

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
/**
3
 * Finance module for HiPanel
4
 *
5
 * @link      https://github.com/hiqdev/hipanel-module-finance
6
 * @package   hipanel-module-finance
7
 * @license   BSD-3-Clause
8
 * @copyright Copyright (c) 2015-2019, HiQDev (http://hiqdev.com/)
9
 */
10
11
namespace hipanel\modules\finance\cart;
12
13
use hipanel\modules\finance\logic\Calculator;
14
use hipanel\modules\finance\models\Calculation;
15
use hipanel\modules\finance\models\Value;
16
use hiqdev\yii2\cart\ShoppingCart;
17
use Yii;
18
use yz\shoppingcart\CartActionEvent;
19
20
/**
21
 * Class CartCalculator provides API to calculate [[cart]] positions value.
22
 *
23
 * Usage:
24
 *
25
 * ```php
26
 * $calculator = new CartCalculator([
27
 *     'cart' => $this->cart
28
 * ]);
29
 *
30
 * $calculator->run(); // will calculate prices for all cart positions and update them
31
 * ```
32
 *
33
 * Also can be bound to some cart event as handler:
34
 *
35
 * ```php
36
 * $cart->on(Cart::EVENT_UPDATE, [CartCalculator::class, 'handle']);
37
 * ```
38
 */
39
final class CartCalculator extends Calculator
40
{
41
    /**
42
     * @var array
43
     */
44
    private static $ignoreIds = [];
45
46
    /**
47
     * @var AbstractCartPosition[]
48
     */
49
    protected $models;
50
51
    /**
52
     * @var ShoppingCart
53
     */
54
    public $cart;
55
56
    /**
57
     * @var CartActionEvent
58
     */
59
    public $event;
60
61
    /**
62
     * Creates the instance of the object and runs the calculation.
63
     *
64
     * @param CartActionEvent $event The event
65
     * @void
66
     */
67
    public static function handle($event)
68
    {
69
        /** @var ShoppingCart $cart */
70
        $cart = $event->sender;
71
72
        $calculator = new static($cart);
73
74
        return $calculator->execute();
75
    }
76
77
    /**
78
     * @param ShoppingCart $cart
79
     */
80
    public function __construct(ShoppingCart $cart)
81
    {
82
        $this->cart = $cart;
83
84
        parent::__construct($this->cart->positions);
85
    }
86
87
    /**
88
     * {@inheritdoc}
89
     */
90
    public function execute()
91
    {
92
        parent::execute();
93
94
        $this->applyCalculations();
95
96
        return $this->calculations;
97
    }
98
99
    /**
100
     * Updates positions using the calculations provided with [[getCalculation]].
101
     */
102
    private function applyCalculations()
103
    {
104
        $currency = Yii::$app->params['currency'];
105
106
        foreach ($this->models as $position) {
107
            $id = $position->id;
0 ignored issues
show
The property id does not exist on object<hipanel\modules\f...t\AbstractCartPosition>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
108
            if (in_array($id, array_values(self::$ignoreIds))) {
109
                throw new ErrorMultiCurrencyException(Yii::t('cart', 'Sorry, but now it is impossible to add the position with different currencies to the cart. Pay the current order to add this item to the cart.'), $position->getPurchaseModel());
110
            }
111
112
            $calculation = $this->getCalculation($id);
113
            if (!$calculation instanceof Calculation) {
114
                Yii::error('Cart position "' . $position->getName() . '" was removed from the cart because of failed value calculation. Normally this should never happen.', 'hipanel.cart');
115
                $this->cart->removeById($position->id);
116
                break;
117
            }
118
119
            /** @var Value $value */
120
            $value = $calculation->forCurrency($currency);
121
            if (!$value instanceof Value) {
122
                Yii::error('Cart position "' . $position->getName() . '" was removed from the cart because calculation for currency "' . $value->currency . '" is not available', 'hipanel.cart');
123
                $this->cart->removeById($position->id);
124
                break;
125
            }
126
            if ($this->cart->getCurrency() && $value->currency !== $this->cart->getCurrency()) {
127
                self::$ignoreIds[] = $id;
128
                $this->cart->removeById($id);
129
                Yii::error('Cart position "' . $position->getName() . '" was removed from the cart because multi-currency cart is not available for now', 'hipanel.cart');
130
                break;
131
            }
132
133
            $position->setPrice($value->price);
134
            $position->setValue($value->value);
135
            $position->setCurrency($value->currency);
136
        }
137
    }
138
}
139