Completed
Push — master ( 1e4ee2...e3e525 )
by Iurii
02:20
created

Module::hookOrderCompleteMessage()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 6
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 3
nc 2
nop 2
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\Container,
13
    gplcart\core\Module as CoreModule;
14
15
/**
16
 * Main class for 2 Checkout 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 $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/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
     * Implements hook "payment.methods"
93
     * @param array $methods
94
     */
95
    public function hookPaymentMethods(array &$methods)
96
    {
97
        $methods['twocheckout'] = array(
98
            'module' => 'twocheckout',
99
            'image' => 'image/icon.png',
100
            'title' => '2 Checkout',
101
            'status' => $this->getStatus(),
102
            'template' => array('complete' => 'pay')
103
        );
104
    }
105
106
    /**
107
     * Implements hook "order.add.before"
108
     * @param array $order
109
     * @param \gplcart\core\models\Order $object
110
     */
111
    public function hookOrderAddBefore(array &$order, $object)
112
    {
113
        // Adjust order status before creation
114
        // We want to get payment in advance, so assign "awaiting payment" status
115
        if ($order['payment'] === 'twocheckout') {
116
            $order['status'] = $object->getStatusAwaitingPayment();
117
        }
118
    }
119
120
    /**
121
     * Implements hook "order.checkout.complete"
122
     * @param string $message
123
     * @param array $order
124
     */
125
    public function hookOrderCompleteMessage(&$message, $order)
126
    {
127
        if ($order['payment'] === 'twocheckout') {
128
            $message = ''; // Hide default message
129
        }
130
    }
131
132
    /**
133
     * Implements hook "order.complete.page"
134
     * @param array $order
135
     * @param \gplcart\core\models\Order $model
136
     * @param \gplcart\core\controllers\frontend\Controller $controller
137
     */
138
    public function hookOrderCompletePage(array $order, $model, $controller)
139
    {
140
        $this->setOrderCompletePage($order, $model, $controller);
141
    }
142
143
    /**
144
     * Check 2checkout gateway class is loaded
145
     * @param mixed $result
146
     */
147
    protected function checkGateway(&$result)
148
    {
149
        try {
150
            $this->getGateway();
151
        } catch (\InvalidArgumentException $ex) {
152
            $result = $ex->getMessage();
153
        }
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\Module */
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