Completed
Push — master ( d67803...156b7e )
by Iurii
04:44
created

Twocheckout::processResponse()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 12
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

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