Completed
Push — master ( 21ad1f...a6f32b )
by Dmitry
17:56
created

Module   A

Complexity

Total Complexity 29

Size/Duplication

Total Lines 290
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 7

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
wmc 29
lcom 1
cbo 7
dl 0
loc 290
ccs 0
cts 72
cp 0
rs 10
c 0
b 0
f 0

19 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 6 1
A setCollection() 0 4 1
A getPurchaseRequestCollection() 0 8 1
A getAvailableCurrenciesCollection() 0 7 1
A getPurchaseRequest() 0 4 1
A hasPurchaseRequest() 0 4 1
A prepareRequestData() 0 8 1
A setUsername() 0 4 1
A getUsername() 0 15 4
A buildUrl() 0 17 2
A localizePage() 0 4 3
A getPage() 0 11 3
A rememberUrl() 0 4 1
A previousUrl() 0 4 1
A getPayController() 0 8 2
A renderDeposit() 0 4 1
A saveTransaction() 0 4 1
A insertTransaction() 0 6 1
A findTransaction() 0 8 2
1
<?php
2
/**
3
 * Yii2 extension for payment processing with Omnipay, Payum and more later.
4
 *
5
 * @link      https://github.com/hiqdev/yii2-merchant
6
 * @package   yii2-merchant
7
 * @license   BSD-3-Clause
8
 * @copyright Copyright (c) 2015-2017, HiQDev (http://hiqdev.com/)
9
 */
10
11
namespace hiqdev\yii2\merchant;
12
13
use hiqdev\yii2\merchant\models\DepositForm;
14
use hiqdev\yii2\merchant\controllers\PayController;
15
use hiqdev\yii2\merchant\models\DepositRequest;
16
use hiqdev\yii2\merchant\models\PurchaseRequest;
17
use hiqdev\yii2\merchant\transactions\Transaction;
18
use hiqdev\yii2\merchant\transactions\TransactionException;
19
use hiqdev\yii2\merchant\transactions\TransactionRepositoryInterface;
20
use Yii;
21
use yii\base\InvalidConfigException;
22
use yii\helpers\Url;
23
24
/**
25
 * Merchant Module.
26
 *
27
 * Example application configuration:
28
 *
29
 * ```php
30
 * 'modules' => [
31
 *     'merchant' => [
32
 *         'class'         => 'hiqdev\yii2\merchant\Module',
33
 *         'notifyPage'    => '/my/notify/page',
34
 *         'collection'    => [
35
 *             'PayPal' => [
36
 *                 'purse'     => $params['paypal_purse'],
37
 *                 'secret'    => $params['paypal_secret'],   /// NEVER keep secret in source control
38
 *             ],
39
 *             'webmoney_usd' => [
40
 *                 'gateway'   => 'WebMoney',
41
 *                 'purse'     => $params['webmoney_purse'],
42
 *                 'secret'    => $params['webmoney_secret'], /// NEVER keep secret in source control
43
 *             ],
44
 *         ],
45
 *     ],
46
 * ],
47
 * ```
48
 *
49
 * @var string returns username for usage in merchant
50
 */
51
class Module extends \yii\base\Module
52
{
53
    /**
54
     * The URL prefix that will be used as a key to save current URL in the session.
55
     *
56
     * @see rememberUrl()
57
     * @see previousUrl()
58
     * @see \yii\helpers\BaseUrl::remember()
59
     * @see \yii\helpers\BaseUrl::previous()
60
     */
61
    const URL_PREFIX = 'merchant_url_';
62
63
    /**
64
     * @var string merchant collection class name. Defaults to [[Collection]]
65
     */
66
    public $purchaseRequestCollectionClass = Collection::class;
67
    /**
68
     * @var string currencies collection class name. Defaults to [[Collection]]
69
     */
70
    public $currenciesCollectionClass;
71
    /**
72
     * @var string Deposit model class name. Defaults to [[DepositForm]]
73
     */
74
    public $depositFromClass = DepositForm::class;
75
    /**
76
     * @var TransactionRepositoryInterface
77
     */
78
    protected $transactionRepository;
79
80
    public function __construct($id, $parent = null, TransactionRepositoryInterface $transactionRepository, array $config = [])
81
    {
82
        parent::__construct($id, $parent, $config);
83
84
        $this->transactionRepository = $transactionRepository;
85
    }
86
87
    public function setCollection(array $collection)
88
    {
89
        $this->_collection = $collection;
0 ignored issues
show
Documentation introduced by
The property _collection does not exist on object<hiqdev\yii2\merchant\Module>. 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...
90
    }
91
92
    /**
93
     * @param DepositRequest $depositRequest
94
     * @return Collection
95
     * @throws InvalidConfigException
96
     */
97
    public function getPurchaseRequestCollection($depositRequest = null)
98
    {
99
        return Yii::createObject([
100
            'class'  => $this->purchaseRequestCollectionClass,
101
            'module' => $this,
102
            'depositRequest' => $depositRequest,
103
        ]);
104
    }
105
106
    /**
107
     * @return Currencies
108
     * @throws InvalidConfigException
109
     */
110
    public function getAvailableCurrenciesCollection(): Currencies
111
    {
112
        return Yii::createObject([
113
            'class'  => $this->currenciesCollectionClass,
114
            'module' => $this,
115
        ]);
116
    }
117
118
    /**
119
     * @param string $merchant_name merchant id
120
     * @param DepositRequest $depositRequest
121
     * @return PurchaseRequest merchant instance
122
     */
123
    public function getPurchaseRequest($merchant_name, DepositRequest $depositRequest)
124
    {
125
        return $this->getPurchaseRequestCollection($depositRequest)->get($merchant_name);
126
    }
127
128
    /**
129
     * Checks if merchant exists in the hub.
130
     *
131
     * @param string $id merchant id
132
     * @return bool whether merchant exist
133
     */
134
    public function hasPurchaseRequest($id)
135
    {
136
        return $this->getPurchaseRequestCollection()->has($id);
137
    }
138
139
    /**
140
     * Method builds data for merchant request.
141
     *
142
     * @param DepositRequest $depositRequest
143
     * @return array
144
     */
145
    public function prepareRequestData($depositRequest)
146
    {
147
        $depositRequest->username = $this->getUsername();
148
        $depositRequest->notifyUrl = $this->buildUrl('notify', $depositRequest);
149
        $depositRequest->returnUrl = $this->buildUrl('return', $depositRequest);
150
        $depositRequest->cancelUrl = $this->buildUrl('cancel', $depositRequest);
151
        $depositRequest->finishUrl = $this->buildUrl('finish', $depositRequest);
152
    }
153
154
    /**
155
     * @var string client login
156
     */
157
    protected $_username;
158
159
    /**
160
     * Sets [[_username]].
161
     *
162
     * @param $username
163
     */
164
    public function setUsername($username)
165
    {
166
        $this->_username = $username;
167
    }
168
169
    /**
170
     * Gets [[_username]] when defined, otherwise - `Yii::$app->user->identity->username`,
171
     * otherwise `Yii::$app->user->identity->getId()`.
172
     * @throws InvalidConfigException
173
     * @return string
174
     */
175
    public function getUsername()
176
    {
177
        if (isset($this->_username)) {
178
            return $this->_username;
179
        } elseif (($identity = Yii::$app->user->identity) !== null) {
180
            if ($identity->hasProperty('username')) {
181
                $this->_username = $identity->username;
182
            } else {
183
                $this->_username = $identity->getId();
184
            }
185
186
            return $this->_username;
187
        }
188
        throw new InvalidConfigException('Unable to determine username');
189
    }
190
191
    /**
192
     * @var string|array the URL that will be used for payment system notifications. Will be passed through [[Url::to()]]
193
     */
194
    public $notifyPage = 'notify';
195
    /**
196
     * @var string|array the URL that will be used to redirect client from the merchant after the success payment.
197
     * Will be passed through [[Url::to()]]
198
     */
199
    public $returnPage = 'return';
200
    /**
201
     * @var string|array the URL that will be used to redirect client from the merchant after the failed payment.
202
     * Will be passed through [[Url::to()]]
203
     */
204
    public $cancelPage = 'cancel';
205
    /**
206
     * @var string|array the URL that might be used to redirect used from the success or error page to the finish page.
207
     * Will be passed through [[Url::to()]]
208
     */
209
    public $finishPage = 'finish';
210
211
    /**
212
     * Builds URLs that will be passed in the request to the merchant.
213
     *
214
     * @param string $destination `notify`, `return`, `cancel`
215
     * @param DepositRequest $depositRequest
216
     * @return string URL
217
     */
218
    public function buildUrl($destination, DepositRequest $depositRequest)
219
    {
220
        $page = [
221
            $this->getPage($destination, $depositRequest),
222
            'username'      => $depositRequest->username,
223
            'merchant'      => $depositRequest->merchant,
224
            'transactionId' => $depositRequest->id,
225
        ];
226
227
        if (is_array($page)) {
228
            $page[0] = $this->localizePage($page[0]);
229
        } else {
230
            $page = $this->localizePage($page);
231
        }
232
233
        return Url::to($page, true);
234
    }
235
236
    /**
237
     * Builds url to `this_module/pay/$page` if page is not /full/page.
238
     * @param mixed $page
239
     * @return mixed
240
     */
241
    public function localizePage($page)
242
    {
243
        return is_string($page) && $page[0] !== '/' ? ('/' . $this->id . '/pay/' . $page) : $page;
244
    }
245
246
    public function getPage($destination, DepositRequest $depositRequest)
247
    {
248
        $property = $destination . 'Url';
249
        if ($depositRequest->$property) {
250
            return $depositRequest->$property;
251
        }
252
253
        $name = $destination . 'Page';
254
255
        return $this->hasProperty($name) ? $this->{$name} : $destination;
256
    }
257
258
    /**
259
     * Saves the $url to session with [[URL_PREFIX]] key, trailed with $name.
260
     *
261
     * @param array|string $url
262
     * @param string $name the trailing part for the URL save key. Defaults to `back`
263
     * @void
264
     */
265
    public function rememberUrl($url, $name = 'back')
266
    {
267
        Url::remember($url, static::URL_PREFIX . $name);
268
    }
269
270
    /**
271
     * Extracts the URL from session storage, saved with [[URL_PREFIX]] key, trailed with $name.
272
     *
273
     * @param string $name the trailing part for the URL save key. Defaults to `back`
274
     * @return string
275
     */
276
    public function previousUrl($name = 'back')
277
    {
278
        return Url::previous(static::URL_PREFIX . $name);
279
    }
280
281
    /**
282
     * @var PayController The Payment controller
283
     */
284
    protected $_payController;
285
286
    /**
287
     * @throws InvalidConfigException
288
     *
289
     * @return PayController
290
     */
291
    public function getPayController()
292
    {
293
        if ($this->_payController === null) {
294
            $this->_payController = $this->createControllerById('pay');
295
        }
296
297
        return $this->_payController;
298
    }
299
300
    /**
301
     * Renders page, that contains list of payment systems, that might be choosen by user.
302
     * Should be implemented in `PayController`.
303
     *
304
     * @param DepositForm $form
305
     * @return \yii\web\Response
306
     */
307
    public function renderDeposit($form)
308
    {
309
        return $this->getPayController()->renderDeposit($form);
310
    }
311
312
    /**
313
     * @param Transaction $transaction
314
     * @return Transaction
315
     */
316
    public function saveTransaction($transaction)
317
    {
318
        return $this->transactionRepository->save($transaction);
319
    }
320
321
    public function insertTransaction($id, $merchant, $data)
322
    {
323
        $transaction = $this->transactionRepository->create($id, $merchant, $data);
324
325
        return $this->transactionRepository->insert($transaction);
326
    }
327
328
    /**
329
     * @param string $id transaction ID
330
     * @return Transaction|null
331
     */
332
    public function findTransaction($id)
333
    {
334
        try {
335
            return $this->transactionRepository->findById($id);
336
        } catch (TransactionException $e) {
337
            return null;
338
        }
339
    }
340
}
341