Completed
Push — master ( e005b3...afc79c )
by Iurii
01:12
created

Twocheckout::submitPayment()   B

Complexity

Conditions 4
Paths 4

Size

Total Lines 26
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 26
rs 8.5806
c 0
b 0
f 0
cc 4
eloc 17
nc 4
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\Config;
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
     * @param Config $config
47
     */
48
    public function __construct(Config $config)
49
    {
50
        parent::__construct($config);
51
    }
52
53
    /* ------------------------- Hooks ------------------------- */
54
55
    /**
56
     * Implements hook "route.list"
57
     * @param array $routes
58
     */
59
    public function hookRouteList(array &$routes)
60
    {
61
        $routes['admin/module/settings/twocheckout'] = array(
62
            'access' => 'module_edit',
63
            'handlers' => array(
64
                'controller' => array('gplcart\\modules\\twocheckout\\controllers\\Settings', 'editSettings')
65
            )
66
        );
67
    }
68
69
    /**
70
     * Implements hook "module.enable.before"
71
     * @param mixed $result
72
     */
73
    public function hookModuleEnableBefore(&$result)
74
    {
75
        try {
76
            $this->getGatewayInstance();
77
        } catch (\InvalidArgumentException $ex) {
78
            $result = $ex->getMessage();
79
        }
80
    }
81
82
    /**
83
     * Implements hook "module.install.before"
84
     * @param mixed $result
85
     */
86
    public function hookModuleInstallBefore(&$result)
87
    {
88
        try {
89
            $this->getGatewayInstance();
90
        } catch (\InvalidArgumentException $ex) {
91
            $result = $ex->getMessage();
92
        }
93
    }
94
95
    /**
96
     * Implements hook "payment.methods"
97
     * @param array $methods
98
     */
99
    public function hookPaymentMethods(array &$methods)
100
    {
101
        $methods['twocheckout'] = array(
102
            'module' => 'twocheckout',
103
            'image' => 'image/icon.png',
104
            'status' => $this->getStatus(),
105
            'title' => $this->getLanguage()->text('2 Checkout'),
106
            'template' => array('complete' => 'pay')
107
        );
108
    }
109
110
    /**
111
     * Implements hook "order.add.before"
112
     * @param array $order
113
     * @param \gplcart\core\models\Order $object
114
     */
115
    public function hookOrderAddBefore(array &$order, $object)
116
    {
117
        // Adjust order status before creation
118
        // We want to get payment in advance, so assign "awaiting payment" status
119
        if ($order['payment'] === 'twocheckout') {
120
            $order['status'] = $object->getStatusAwaitingPayment();
121
        }
122
    }
123
124
    /**
125
     * Implements hook "order.checkout.complete"
126
     * @param string $message
127
     * @param array $order
128
     */
129
    public function hookOrderCompleteMessage(&$message, $order)
130
    {
131
        if ($order['payment'] === 'twocheckout') {
132
            $message = ''; // Hide default message
133
        }
134
    }
135
136
    /**
137
     * Implements hook "order.complete.page"
138
     * @param array $order
139
     * @param \gplcart\core\models\Order $model
140
     * @param \gplcart\core\controllers\frontend\Controller $controller
141
     */
142
    public function hookOrderCompletePage(array $order, $model, $controller)
143
    {
144
        $this->order = $model;
145
        $this->data_order = $order;
146
        $this->controller = $controller;
147
148
        if ($order['payment'] === 'twocheckout') {
149
            $this->submitPayment();
150
            $this->completePayment();
151
        }
152
    }
153
154
    /* ------------------------- API ------------------------- */
155
156
    /**
157
     * Get gateway instance
158
     * @return object
159
     * @throws \InvalidArgumentException
160
     */
161
    public function getGatewayInstance()
162
    {
163
        /* @var $model \gplcart\modules\omnipay_library\OmnipayLibrary */
164
        $model = $this->getInstance('omnipay_library');
165
166
        $instance = $model->getGatewayInstance('TwoCheckoutPlus');
167
168
        if (!$instance 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...
169
            throw new \InvalidArgumentException('Object is not instance of Omnipay\TwoCheckoutPlus\Gateway');
170
        }
171
172
        return $instance;
173
    }
174
175
    /* ------------------------- Helpers ------------------------- */
176
177
    /**
178
     * Returns a module setting
179
     * @param string $name
180
     * @param mixed $default
181
     * @return mixed
182
     */
183
    protected function getModuleSetting($name, $default = null)
184
    {
185
        return $this->config->getFromModule('twocheckout', $name, $default);
186
    }
187
188
    /**
189
     * Returns the current status of the payment method
190
     */
191
    protected function getStatus()
192
    {
193
        return $this->getModuleSetting('status') && $this->getModuleSetting('accountNumber') && $this->getModuleSetting('secretWord');
194
    }
195
196
    /**
197
     * Performs actions when purchase is completed
198
     */
199
    protected function completePayment()
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 submitPayment()
212
    {
213
        if ($this->controller->isPosted('pay')) {
214
215
            $gateway = $this->getGatewayInstance();
216
            $gateway->setDemoMode((bool) $this->getModuleSetting('test'));
217
            $gateway->setCurrency($this->data_order['currency']);
218
            $gateway->setSecretWord($this->getModuleSetting('secretWord'));
219
            $gateway->setAccountNumber($this->getModuleSetting('accountNumber'));
220
221
            $gateway->setCart(array(array(
222
                    'quantity' => 1,
223
                    'type' => 'product',
224
                    'price' => $this->data_order['total_formatted_number'],
225
                    'name' => $this->controller->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->getModuleSetting('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->getModel('Transaction');
316
        return $object->add($transaction);
317
    }
318
319
}
320