Completed
Push — master ( 724599...24f1ab )
by Iurii
03:27
created

Module::hookPaymentMethods()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 7

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 7
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\Container,
13
    gplcart\core\Module as CoreModule;
14
15
/**
16
 * Main class for Authorize.Net module
17
 */
18
class 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
     * Module class instance
47
     * @var \gplcart\core\Module
48
     */
49
    protected $module;
50
51
    /**
52
     * @param CoreModule $module
53
     */
54
    public function __construct(CoreModule $module)
55
    {
56
        $this->module = $module;
57
    }
58
59
    /**
60
     * Implements hook "route.list"
61
     * @param array $routes
62
     */
63
    public function hookRouteList(array &$routes)
64
    {
65
        $routes['admin/module/settings/authorize'] = array(
66
            'access' => 'module_edit',
67
            'handlers' => array(
68
                'controller' => array('gplcart\\modules\\authorize\\controllers\\Settings', 'editSettings')
69
            )
70
        );
71
    }
72
73
    /**
74
     * Implements hook "module.enable.before"
75
     * @param mixed $result
76
     */
77
    public function hookModuleEnableBefore(&$result)
78
    {
79
        try {
80
            $this->getGateway();
81
        } catch (\InvalidArgumentException $ex) {
82
            $result = $ex->getMessage();
83
        }
84
    }
85
86
    /**
87
     * Implements hook "module.install.before"
88
     * @param mixed $result
89
     */
90
    public function hookModuleInstallBefore(&$result)
91
    {
92
        try {
93
            $this->getGateway();
94
        } catch (\InvalidArgumentException $ex) {
95
            $result = $ex->getMessage();
96
        }
97
    }
98
99
    /**
100
     * Implements hook "payment.methods"
101
     * @param array $methods
102
     */
103
    public function hookPaymentMethods(array &$methods)
104
    {
105
        $methods['authorize_sim'] = array(
106
            'module' => 'authorize',
107
            'image' => 'image/icon.png',
108
            'status' => $this->getStatus(),
109
            'title' => 'Authorize.Net',
110
            'template' => array('complete' => 'pay')
111
        );
112
    }
113
114
    /**
115
     * Implements hook "order.add.before"
116
     * @param array $order
117
     * @param \gplcart\core\models\Order $model
118
     */
119
    public function hookOrderAddBefore(array &$order, $model)
120
    {
121
        // Adjust order status before creation
122
        // We want to get payment in advance, so assign "awaiting payment" status
123
        if ($order['payment'] === 'authorize_sim') {
124
            $order['status'] = $model->getStatusAwaitingPayment();
125
        }
126
    }
127
128
    /**
129
     * Implements hook "order.checkout.complete"
130
     * @param string $message
131
     * @param array $order
132
     */
133
    public function hookOrderCompleteMessage(&$message, $order)
134
    {
135
        if ($order['payment'] === 'authorize_sim') {
136
            $message = ''; // Hide default message
137
        }
138
    }
139
140
    /**
141
     * Implements hook "order.complete.page"
142
     * @param array $order
143
     * @param \gplcart\core\models\Order $model
144
     * @param \gplcart\core\controllers\frontend\Controller $controller
145
     */
146
    public function hookOrderCompletePage(array $order, $model, $controller)
147
    {
148
        if ($order['payment'] === 'authorize_sim') {
149
150
            $this->order = $model;
151
            $this->data_order = $order;
152
            $this->controller = $controller;
153
154
            $this->processPurchase();
155
        }
156
    }
157
158
    /**
159
     * Get gateway instance
160
     * @return object
161
     * @throws \InvalidArgumentException
162
     */
163
    protected function getGateway()
164
    {
165
        /* @var $module \gplcart\modules\omnipay_library\Module */
166
        $module = Container::get('gplcart\\modules\\omnipay_library\\OmnipayLibrary');
167
        $gateway = $module->getGatewayInstance('AuthorizeNet_SIM');
168
169
        if (!$gateway 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...
170
            throw new \InvalidArgumentException('Object is not instance of Omnipay\AuthorizeNet\SIMGateway');
171
        }
172
173
        return $gateway;
174
    }
175
176
    /**
177
     * Process payment
178
     */
179
    protected function processPurchase()
180
    {
181
        if ($this->controller->isPosted('pay')) {
182
            $this->submitPurchase();
183
        } else if ($this->controller->isQuery('authorize_return')) {
184
            $this->response = $this->getGateway()->completePurchase($this->getPurchaseParams())->send();
185
            if ($this->controller->isQuery('cancel')) {
186
                $this->cancelPurchase();
187
            } else {
188
                $this->finishPurchase();
189
            }
190
        }
191
    }
192
193
    /**
194
     * Performs actions when a payment is canceled
195
     */
196
    protected function cancelPurchase()
197
    {
198
        $this->controller->setMessage($this->controller->text('Payment has been canceled'), 'warning');
199
        $gateway_message = $this->response->getMessage();
200
        if (!empty($gateway_message)) {
201
            $this->controller->setMessage($gateway_message, 'warning');
202
        }
203
    }
204
205
    /**
206
     * Handles submitted payment
207
     */
208
    protected function submitPurchase()
209
    {
210
        $gateway = $this->getGateway();
211
        $gateway->setApiLoginId($this->getSetting('apiLoginId'));
212
        $gateway->setHashSecret($this->getSetting('hashSecret'));
213
        $gateway->setTestMode((bool) $this->getSetting('testMode'));
214
        $gateway->setDeveloperMode((bool) $this->getSetting('testMode'));
215
        $gateway->setTransactionKey($this->getSetting('transactionKey'));
216
217
        $this->response = $gateway->purchase($this->getPurchaseParams())->send();
218
219
        if ($this->response->isRedirect()) {
220
            $this->response->redirect();
221
        } else if (!$this->response->isSuccessful()) {
222
            $this->redirectError();
223
        }
224
    }
225
226
    /**
227
     * Returns an array of purchase parameters
228
     * @return array
229
     */
230
    protected function getPurchaseParams()
231
    {
232
        return array(
233
            'currency' => $this->data_order['currency'],
234
            'amount' => $this->data_order['total_formatted_number'],
235
            'cancelUrl' => $this->controller->url("checkout/complete/{$this->data_order['order_id']}", array('authorize_return' => true, 'cancel' => true), true),
236
            'returnUrl' => $this->controller->url("checkout/complete/{$this->data_order['order_id']}", array('authorize_return' => true), true)
237
        );
238
    }
239
240
    /**
241
     * Performs final actions on success payment
242
     */
243
    protected function finishPurchase()
244
    {
245
        if ($this->response->isSuccessful()) {
246
            $this->updateOrderStatus();
247
            $this->addTransaction();
248
            $this->redirectSuccess();
249
        } else if ($this->response->isRedirect()) {
250
            $this->response->redirect();
251
        } else {
252
            $this->redirectError();
253
        }
254
    }
255
256
    /**
257
     * Redirect on error payment
258
     */
259
    protected function redirectError()
260
    {
261
        $this->controller->redirect('', $this->response->getMessage(), 'warning', true);
262
    }
263
264
    /**
265
     * Redirect on successful payment
266
     */
267
    protected function redirectSuccess()
268
    {
269
        $vars = array(
270
            '@num' => $this->data_order['order_id'],
271
            '@status' => $this->order->getStatusName($this->data_order['status'])
272
        );
273
274
        $message = $this->controller->text('Thank you! Payment has been made. Order #@num, status: @status', $vars);
275
        $this->controller->redirect('/', $message, 'success', true);
276
    }
277
278
    /**
279
     * Update order status after successful transaction
280
     */
281
    protected function updateOrderStatus()
282
    {
283
        $data = array('status' => $this->getSetting('order_status_success'));
284
        $this->order->update($this->data_order['order_id'], $data);
285
        $this->data_order = $this->order->get($this->data_order['order_id']);
286
    }
287
288
    /**
289
     * Adds a transaction
290
     */
291
    protected function addTransaction()
292
    {
293
        /* @var $model \gplcart\core\models\Transaction */
294
        $model = Container::get('gplcart\\core\\models\\Transaction');
295
296
        $transaction = array(
297
            'total' => $this->data_order['total'],
298
            'order_id' => $this->data_order['order_id'],
299
            'currency' => $this->data_order['currency'],
300
            'payment_method' => $this->data_order['payment'],
301
            'gateway_transaction_id' => $this->response->getTransactionReference()
302
        );
303
304
        return $model->add($transaction);
305
    }
306
307
    /**
308
     * Returns the current status for the payment method
309
     * @return bool
310
     */
311
    protected function getStatus()
312
    {
313
        return $this->getSetting('status') && $this->getSetting('apiLoginId')//
314
                && $this->getSetting('hashSecret') && $this->getSetting('transactionKey');
315
    }
316
317
    /**
318
     * Returns a module setting
319
     * @param string $name
320
     * @param mixed $default
321
     * @return mixed
322
     */
323
    protected function getSetting($name, $default = null)
324
    {
325
        return $this->module->getSettings('authorize', $name, $default);
326
    }
327
328
}
329