Completed
Push — master ( afc79c...1e4ee2 )
by Iurii
01:19
created

Twocheckout::getGateway()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 12
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 12
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 6
nc 2
nop 0
1
<?php
2
3
/**
4
 * @package 2 Checkout
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\twocheckout;
11
12
use gplcart\core\Module,
13
    gplcart\core\Container;
14
15
/**
16
 * Main class for 2 Checkout module
17
 */
18
class Twocheckout 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
     * Module class instance
47
     * @var \gplcart\core\Module $module
48
     */
49
    protected $module;
50
51
    /**
52
     * @param Module $module
53
     */
54
    public function __construct(Module $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/twocheckout'] = array(
66
            'access' => 'module_edit',
67
            'handlers' => array(
68
                'controller' => array('gplcart\\modules\\twocheckout\\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
        $this->checkGateway($result);
80
    }
81
82
    /**
83
     * Implements hook "module.install.before"
84
     * @param mixed $result
85
     */
86
    public function hookModuleInstallBefore(&$result)
87
    {
88
        $this->checkGateway($result);
89
    }
90
91
    /**
92
     * Check 2checkout gateway class is loaded
93
     * @param mixed $result
94
     */
95
    protected function checkGateway(&$result)
96
    {
97
        try {
98
            $this->getGateway();
99
        } catch (\InvalidArgumentException $ex) {
100
            $result = $ex->getMessage();
101
        }
102
    }
103
104
    /**
105
     * Implements hook "payment.methods"
106
     * @param array $methods
107
     */
108
    public function hookPaymentMethods(array &$methods)
109
    {
110
        $methods['twocheckout'] = array(
111
            'module' => 'twocheckout',
112
            'image' => 'image/icon.png',
113
            'title' => '2 Checkout',
114
            'status' => $this->getStatus(),
115
            'template' => array('complete' => 'pay')
116
        );
117
    }
118
119
    /**
120
     * Implements hook "order.add.before"
121
     * @param array $order
122
     * @param \gplcart\core\models\Order $object
123
     */
124
    public function hookOrderAddBefore(array &$order, $object)
125
    {
126
        // Adjust order status before creation
127
        // We want to get payment in advance, so assign "awaiting payment" status
128
        if ($order['payment'] === 'twocheckout') {
129
            $order['status'] = $object->getStatusAwaitingPayment();
130
        }
131
    }
132
133
    /**
134
     * Implements hook "order.checkout.complete"
135
     * @param string $message
136
     * @param array $order
137
     */
138
    public function hookOrderCompleteMessage(&$message, $order)
139
    {
140
        if ($order['payment'] === 'twocheckout') {
141
            $message = ''; // Hide default message
142
        }
143
    }
144
145
    /**
146
     * Implements hook "order.complete.page"
147
     * @param array $order
148
     * @param \gplcart\core\models\Order $model
149
     * @param \gplcart\core\controllers\frontend\Controller $controller
150
     */
151
    public function hookOrderCompletePage(array $order, $model, $controller)
152
    {
153
        $this->setOrderCompletePage($order, $model, $controller);
154
    }
155
156
    /**
157
     * Set order complete page
158
     * @param array $order
159
     * @param \gplcart\core\models\Order $model
160
     * @param \gplcart\core\controllers\frontend\Controller $controller
161
     */
162
    protected function setOrderCompletePage(array $order, $model, $controller)
163
    {
164
        $this->order = $model;
165
        $this->data_order = $order;
166
        $this->controller = $controller;
167
168
        if ($order['payment'] === 'twocheckout') {
169
            $this->submitPayment();
170
            $this->completePayment();
171
        }
172
    }
173
174
    /**
175
     * Get gateway instance
176
     * @return \Omnipay\TwoCheckoutPlus\Gateway
177
     * @throws \InvalidArgumentException
178
     */
179
    public function getGateway()
180
    {
181
        /* @var $module \gplcart\modules\omnipay_library\OmnipayLibrary */
182
        $module = $this->module->getInstance('omnipay_library');
183
        $gateway = $module->getGatewayInstance('TwoCheckoutPlus');
184
185
        if (!$gateway instanceof \Omnipay\TwoCheckoutPlus\Gateway) {
0 ignored issues
show
Bug introduced by
The class Omnipay\TwoCheckoutPlus\Gateway 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...
186
            throw new \InvalidArgumentException('Object is not instance of Omnipay\TwoCheckoutPlus\Gateway');
187
        }
188
189
        return $gateway;
190
    }
191
192
    /**
193
     * Returns a module setting
194
     * @param string $name
195
     * @param mixed $default
196
     * @return mixed
197
     */
198
    protected function getModuleSetting($name, $default = null)
199
    {
200
        return $this->module->getSettings('twocheckout', $name, $default);
201
    }
202
203
    /**
204
     * Returns the current status of the payment method
205
     */
206
    protected function getStatus()
207
    {
208
        return $this->getModuleSetting('status') && $this->getModuleSetting('accountNumber') && $this->getModuleSetting('secretWord');
209
    }
210
211
    /**
212
     * Performs actions when purchase is completed
213
     */
214
    protected function completePayment()
215
    {
216
        if ($this->controller->isQuery('paid')) {
217
            $gateway = $this->getGateway();
218
            $this->response = $gateway->completePurchase($this->getPurchaseParams())->send();
219
            $this->processResponse();
220
        }
221
    }
222
223
    /**
224
     * Handles submitted payment
225
     */
226
    protected function submitPayment()
227
    {
228
        if ($this->controller->isPosted('pay')) {
229
230
            $gateway = $this->getGateway();
231
            $gateway->setDemoMode((bool) $this->getModuleSetting('test'));
232
            $gateway->setCurrency($this->data_order['currency']);
233
            $gateway->setSecretWord($this->getModuleSetting('secretWord'));
234
            $gateway->setAccountNumber($this->getModuleSetting('accountNumber'));
235
236
            $cart = array(array(
237
                    'quantity' => 1,
238
                    'type' => 'product',
239
                    'price' => $this->data_order['total_formatted_number'],
240
                    'name' => $this->controller->text('Order #@num', array('@num' => $this->data_order['order_id']))
241
            ));
242
243
            $gateway->setCart($cart);
244
245
            $this->response = $gateway->purchase($this->getPurchaseParams())->send();
246
247
            if ($this->response->isRedirect()) {
248
                $this->response->redirect();
249
            } else if (!$this->response->isSuccessful()) {
250
                $this->redirectError();
251
            }
252
        }
253
    }
254
255
    /**
256
     * Returns an array of purchase parameters
257
     * @return array
258
     */
259
    protected function getPurchaseParams()
260
    {
261
        return array(
262
            'currency' => $this->data_order['currency'],
263
            'total' => $this->data_order['total_formatted_number'],
264
            'cancelUrl' => $this->controller->url("checkout/complete/{$this->data_order['order_id']}", array('cancel' => true), true),
265
            'returnUrl' => $this->controller->url("checkout/complete/{$this->data_order['order_id']}", array('paid' => true), true)
266
        );
267
    }
268
269
    /**
270
     * Processes gateway response
271
     */
272
    protected function processResponse()
273
    {
274
        if ($this->response->isSuccessful()) {
275
            $this->updateOrderStatus();
276
            $this->addTransaction();
277
            $this->redirectSuccess();
278
        } else if ($this->response->isRedirect()) {
279
            $this->response->redirect();
280
        } else {
281
            $this->redirectError();
282
        }
283
    }
284
285
    /**
286
     * Redirect on error transaction
287
     */
288
    protected function redirectError()
289
    {
290
        $this->controller->redirect('', $this->response->getMessage(), 'warning', true);
291
    }
292
293
    /**
294
     * Redirect on successful transaction
295
     */
296
    protected function redirectSuccess()
297
    {
298
        $vars = array(
299
            '@num' => $this->data_order['order_id'],
300
            '@status' => $this->order->getStatusName($this->data_order['status'])
301
        );
302
303
        $message = $this->controller->text('Thank you! Payment has been made. Order #@num, status: @status', $vars);
304
        $this->controller->redirect('/', $message, 'success', true);
305
    }
306
307
    /**
308
     * Update order status after successful transaction
309
     */
310
    protected function updateOrderStatus()
311
    {
312
        $data = array(
313
            'status' => $this->getModuleSetting('order_status_success'));
314
315
        $this->order->update($this->data_order['order_id'], $data);
316
        $this->data_order = $this->order->get($this->data_order['order_id']);
317
    }
318
319
    /**
320
     * Adds a transaction
321
     * @return integer
322
     */
323
    protected function addTransaction()
324
    {
325
        /* @var $model \gplcart\core\models\Transaction */
326
        $model = Container::get('gplcart\\core\\models\\Transaction');
327
328
        $transaction = array(
329
            'total' => $this->data_order['total'],
330
            'order_id' => $this->data_order['order_id'],
331
            'currency' => $this->data_order['currency'],
332
            'payment_method' => $this->data_order['payment'],
333
            'gateway_transaction_id' => $this->response->getTransactionReference()
334
        );
335
336
        return $model->add($transaction);
337
    }
338
339
}
340