Completed
Push — master ( 7319a9...e0717a )
by Iurii
01:54
created

Authorize::hookRouteList()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 10
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 5
nc 1
nop 1
1
<?php
2
3
/**
4
 * @package Authorize.Net
5
 * @author Iurii Makukh <[email protected]> 
6
 * @copyright Copyright (c) 2017, Iurii Makukh <[email protected]> 
7
 * @license https://www.gnu.org/licenses/gpl-3.0.en.html GNU General Public License 3.0 
8
 */
9
10
namespace gplcart\modules\authorize;
11
12
use gplcart\core\Module;
13
use gplcart\core\models\Language as LanguageModel;
14
15
/**
16
 * Main class for Authorize.Net module
17
 */
18
class Authorize extends Module
19
{
20
21
    /**
22
     * The current order
23
     * @var array
24
     */
25
    protected $data_order;
26
27
    /**
28
     * Omnipay response instance
29
     * @var object
30
     */
31
    protected $response;
32
33
    /**
34
     * Frontend controller instance
35
     * @var \gplcart\core\controllers\frontend\Controller $controller
36
     */
37
    protected $controller;
38
39
    /**
40
     * Order model instance
41
     * @var \gplcart\core\models\Order $order
42
     */
43
    protected $order;
44
45
    /**
46
     * Language model instance
47
     * @var \gplcart\core\models\Language $language
48
     */
49
    protected $language;
50
51
    /**
52
     * @param LanguageModel $language
53
     */
54
    public function __construct(LanguageModel $language)
55
    {
56
        parent::__construct();
57
58
        $this->language = $language;
59
    }
60
61
    /**
62
     * Implements hook "route.list"
63
     * @param array $routes 
64
     */
65
    public function hookRouteList(array &$routes)
66
    {
67
        // Module settings page
68
        $routes['admin/module/settings/authorize'] = array(
69
            'access' => 'module_edit',
70
            'handlers' => array(
71
                'controller' => array('gplcart\\modules\\authorize\\controllers\\Settings', 'editSettings')
72
            )
73
        );
74
    }
75
76
    /**
77
     * Implements hook "module.enable.before"
78
     * @param mixed $result
79
     */
80
    public function hookModuleEnableBefore(&$result)
81
    {
82
        try {
83
            $this->getGatewayInstance();
84
        } catch (\InvalidArgumentException $ex) {
85
            $result = $ex->getMessage();
86
        }
87
    }
88
89
    /**
90
     * Implements hook "module.install.before"
91
     * @param mixed $result
92
     */
93
    public function hookModuleInstallBefore(&$result)
94
    {
95
        try {
96
            $this->getGatewayInstance();
97
        } catch (\InvalidArgumentException $ex) {
98
            $result = $ex->getMessage();
99
        }
100
    }
101
102
    /**
103
     * Get gateway instance
104
     * @return object
105
     * @throws \InvalidArgumentException
106
     */
107
    protected function getGatewayInstance()
108
    {
109
        /* @var $object \gplcart\modules\omnipay_library\OmnipayLibrary */
110
        $object = $this->getInstance('gplcart\\modules\\omnipay_library\\OmnipayLibrary');
111
112
        if (!$object instanceof \Omnipay\AuthorizeNet\SIMGateway) {
0 ignored issues
show
Bug introduced by
The class Omnipay\AuthorizeNet\SIMGateway does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
113
            throw new \InvalidArgumentException('Object is not instance of Omnipay\AuthorizeNet\SIMGateway');
114
        }
115
116
        return $object->getGatewayInstance('AuthorizeNet_SIM');
117
    }
118
119
    /**
120
     * Implements hook "payment.methods"
121
     * @param array $methods 
122
     */
123
    public function hookPaymentMethods(array &$methods)
124
    {
125
        $methods['authorize_sim'] = array(
126
            'module' => 'authorize',
127
            'image' => 'image/icon.png',
128
            'status' => $this->getStatus(),
129
            'title' => $this->language->text('Authorize.Net'),
130
            'template' => array('complete' => 'pay')
131
        );
132
    }
133
134
    /**
135
     * Returns the current status for the payment method
136
     * @return bool
137
     */
138
    protected function getStatus()
139
    {
140
        return $this->setting('status')//
141
                && $this->setting('apiLoginId')//
142
                && $this->setting('hashSecret')//
143
                && $this->setting('transactionKey');
144
    }
145
146
    /**
147
     * Returns a module setting
148
     * @param string $name
149
     * @param mixed $default
150
     * @return mixed
151
     */
152
    protected function setting($name, $default = null)
153
    {
154
        return $this->config->module('authorize', $name, $default);
155
    }
156
157
    /**
158
     * Implements hook "order.add.before"
159
     * @param array $order
160
     * @param \gplcart\core\models\Order $model
161
     */
162
    public function hookOrderAddBefore(array &$order, $model)
163
    {
164
        // Adjust order status before creation
165
        // We want to get payment in advance, so assign "awaiting payment" status
166
        if ($order['payment'] === 'authorize_sim') {
167
            $order['status'] = $model->getStatusAwaitingPayment();
168
        }
169
    }
170
171
    /**
172
     * Implements hook "order.checkout.complete"
173
     * @param string $message
174
     * @param array $order
175
     */
176
    public function hookOrderCompleteMessage(&$message, $order)
177
    {
178
        if ($order['payment'] === 'authorize_sim') {
179
            $message = ''; // Hide default message
180
        }
181
    }
182
183
    /**
184
     * Implements hook "order.complete.page"
185
     * @param array $order
186
     * @param \gplcart\core\controllers\frontend\Controller $controller
187
     * @param \gplcart\core\models\Order $model
188
     */
189
    public function hookOrderCompletePage(array $order, $controller, $model)
190
    {
191
        if ($order['payment'] !== 'authorize_sim') {
192
            return null;
193
        }
194
195
        $this->order = $model;
196
        $this->data_order = $order;
197
        $this->controller = $controller;
198
199
        if ($this->controller->isPosted('pay')) {
200
            $this->submit();
201
            return null;
202
        }
203
204
        if (!$this->controller->isQuery('authorize_return')) {
205
            return null;
206
        }
207
208
        $gateway = $this->getGatewayInstance();
209
        $this->response = $gateway->completePurchase($this->getPurchaseParams())->send();
210
211
        if ($this->controller->isQuery('cancel')) {
212
            $this->cancelPurchase();
213
            return null;
214
        }
215
216
        $this->finishPurchase();
217
    }
218
219
    /**
220
     * Performs actions when a payment is canceled
221
     */
222
    protected function cancelPurchase()
223
    {
224
        $message = $this->controller->text('Payment has been canceled');
225
        $this->controller->setMessage($message, 'warning');
226
227
        $gateway_message = $this->response->getMessage();
228
229
        if (!empty($gateway_message)) {
230
            $this->controller->setMessage($gateway_message, 'warning');
231
        }
232
    }
233
234
    /**
235
     * Handles submitted payment
236
     */
237
    protected function submit()
238
    {
239
        $gateway = $this->getGatewayInstance();
240
241
        $gateway->setApiLoginId($this->setting('apiLoginId'));
242
        $gateway->setHashSecret($this->setting('hashSecret'));
243
        $gateway->setTestMode((bool) $this->setting('testMode'));
244
        $gateway->setDeveloperMode((bool) $this->setting('testMode'));
245
        $gateway->setTransactionKey($this->setting('transactionKey'));
246
247
        $this->response = $gateway->purchase($this->getPurchaseParams())->send();
248
249
        if ($this->response->isRedirect()) {
250
            $this->response->redirect();
251
        } else if (!$this->response->isSuccessful()) {
252
            $this->redirectError();
253
        }
254
    }
255
256
    /**
257
     * Returns an array of purchase parameters
258
     * @return array
259
     */
260
    protected function getPurchaseParams()
261
    {
262
        return array(
263
            'currency' => $this->data_order['currency'],
264
            'amount' => $this->data_order['total_formatted_number'],
265
            'cancelUrl' => $this->controller->url("checkout/complete/{$this->data_order['order_id']}", array('authorize_return' => true, 'cancel' => true), true),
266
            'returnUrl' => $this->controller->url("checkout/complete/{$this->data_order['order_id']}", array('authorize_return' => true), true)
267
        );
268
    }
269
270
    /**
271
     * Performs final actions on success payment
272
     */
273
    protected function finishPurchase()
274
    {
275
        if ($this->response->isSuccessful()) {
276
            $this->updateOrderStatus();
277
            $this->addTransaction();
278
            $this->redirectSuccess();
279
        } else if ($this->response->isRedirect()) {
280
            $this->response->redirect();
281
        } else {
282
            $this->redirectError();
283
        }
284
    }
285
286
    /**
287
     * Redirect on error payment
288
     */
289
    protected function redirectError()
290
    {
291
        $this->controller->redirect('', $this->response->getMessage(), 'warning', true);
292
    }
293
294
    /**
295
     * Redirect on successful payment
296
     */
297
    protected function redirectSuccess()
298
    {
299
        $vars = array(
300
            '@num' => $this->data_order['order_id'],
301
            '@status' => $this->order->getStatusName($this->data_order['status'])
302
        );
303
304
        $message = $this->controller->text('Thank you! Payment has been made. Order #@num, status: @status', $vars);
305
        $this->controller->redirect('/', $message, 'success', true);
306
    }
307
308
    /**
309
     * Update order status after successful transaction
310
     */
311
    protected function updateOrderStatus()
312
    {
313
        $data = array('status' => $this->setting('order_status_success'));
314
        $this->order->update($this->data_order['order_id'], $data);
315
        $this->data_order = $this->order->get($this->data_order['order_id']);
316
    }
317
318
    /**
319
     * Adds a transaction
320
     */
321
    protected function addTransaction()
322
    {
323
        $transaction = array(
324
            'total' => $this->data_order['total'],
325
            'order_id' => $this->data_order['order_id'],
326
            'currency' => $this->data_order['currency'],
327
            'payment_method' => $this->data_order['payment'],
328
            'gateway_transaction_id' => $this->response->getTransactionReference()
329
        );
330
331
        /* @var $object \gplcart\core\models\Transaction */
332
        $object = $this->getInstance('gplcart\\core\\models\\Transaction');
333
        return $object->add($transaction);
334
    }
335
336
}
337