Completed
Push — master ( db50e7...7354ed )
by Dmitry
15:54 queued 13:20
created

src/cart/CartFinisher.php (1 issue)

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 hiqdev\yii2\cart\ShoppingCart;
14
use Yii;
15
use yii\base\BaseObject;
16
17
class CartFinisher extends BaseObject
18
{
19
    /**
20
     * @var ShoppingCart
21
     */
22
    public $cart;
23
24
    /**
25
     * @var PurchaseStrategyInterface[]
26
     */
27
    protected $purchasers = [];
28
29
    /**
30
     * @var AbstractPurchase[] array of successful purchases
31
     */
32
    protected $_success = [];
33
34
    /**
35
     * @var ErrorPurchaseException[] array of failed purchases
36
     */
37
    protected $_error = [];
38
39
    /**
40
     * @var PendingPurchaseException[] array of purchases that are pending
41
     */
42
    protected $_pending = [];
43
44
    /**
45
     * Getter for array of successful purchases.
46
     * @return AbstractPurchase[]
47
     */
48
    public function getSuccess()
49
    {
50
        return $this->_success;
51
    }
52
53
    /**
54
     * Getter for array of failed purchases.
55
     * @return ErrorPurchaseException[]
56
     */
57
    public function getError()
58
    {
59
        return $this->_error;
60
    }
61
62
    /**
63
     * Getter for array of failed purchases.
64
     * @return PendingPurchaseException[]
65
     */
66
    public function getPending()
67
    {
68
        return $this->_pending;
69
    }
70
71
    /**
72
     * Runs the purchase.
73
     * Purchases the positions in the [[cart]].
74
     */
75
    public function run()
76
    {
77
        if ($this->cart->isEmpty) {
78
            return;
79
        }
80
81
        $this->ensureCanBeFinished();
82
        $this->createPurchasers();
83
84
        foreach ($this->purchasers as $purchaser) {
85
            $purchaser->run();
86
87
            $this->_success = array_merge($this->_success, $purchaser->getSuccessPurchases());
88
            foreach ($purchaser->getSuccessPurchases() as $purchase) {
89
                $this->cart->remove($purchase->position);
90
            }
91
            $this->_pending = array_merge($this->_pending, $purchaser->getPendingPurchaseExceptions());
92
            foreach ($purchaser->getPendingPurchaseExceptions() as $exception) {
93
                $this->cart->remove($exception->position);
94
            }
95
            $this->_error = array_merge($this->_error, $purchaser->getErrorPurchaseExceptions());
96
        }
97
    }
98
99
    protected function ensureCanBeFinished()
100
    {
101
        /** @var PositionPurchasabilityValidatorInterface[] $validators */
102
        $validators = [];
103
104
        foreach ($this->cart->positions as $position) {
105
            $purchase = $position->getPurchaseModel();
106
107
            foreach ($purchase->getPurchasabilityRules() as $validator) {
108
                if (!isset($validators[$validator])) {
109
                    $validators[$validator] = Yii::createObject($validator);
110
                }
111
            }
112
        }
113
114
        try {
115
            foreach ($validators as $validator) {
116
                $validator->validate($this->cart->positions);
117
            }
118
        } catch (NotPurchasablePositionException $e) {
119
            $e->resolve();
0 ignored issues
show
The call to the method hipanel\modules\finance\...ionException::resolve() seems un-needed as the method has no side-effects.

PHP Analyzer performs a side-effects analysis of your code. A side-effect is basically anything that might be visible after the scope of the method is left.

Let’s take a look at an example:

class User
{
    private $email;

    public function getEmail()
    {
        return $this->email;
    }

    public function setEmail($email)
    {
        $this->email = $email;
    }
}

If we look at the getEmail() method, we can see that it has no side-effect. Whether you call this method or not, no future calls to other methods are affected by this. As such code as the following is useless:

$user = new User();
$user->getEmail(); // This line could safely be removed as it has no effect.

On the hand, if we look at the setEmail(), this method _has_ side-effects. In the following case, we could not remove the method call:

$user = new User();
$user->setEmail('email@domain'); // This line has a side-effect (it changes an
                                 // instance variable).
Loading history...
120
        }
121
    }
122
123
    protected function createPurchasers()
124
    {
125
        foreach ($this->cart->positions as $position) {
126
            if ($position instanceof BatchPurchasablePositionInterface) {
127
                $purchaser = $this->getPurchaser(get_class($position), $position->getBatchPurchaseStrategyClass());
128
            } else {
129
                $purchaser = $this->getPurchaser(get_class($position), OneByOnePurchaseStrategy::class);
130
            }
131
132
            $purchaser->addPosition($position);
133
        }
134
    }
135
136
    /**
137
     * @param string $positionClass
138
     * @param string $purchaserClass
139
     * @return PurchaseStrategyInterface
140
     */
141
    protected function getPurchaser($positionClass, $purchaserClass)
142
    {
143
        if (!isset($this->purchasers[$positionClass])) {
144
            $this->purchasers[$positionClass] = new $purchaserClass($this->cart);
145
        }
146
147
        return $this->purchasers[$positionClass];
148
    }
149
}
150