Completed
Push — master ( abf3b5...131895 )
by Iurii
01:44
created

Main::submitPayment()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 18
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 18
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 11
nc 2
nop 0
1
<?php
2
3
/**
4
 * @package Stripe
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\stripe;
11
12
use Exception;
13
use gplcart\core\Module,
14
    gplcart\core\Container;
15
use gplcart\core\exceptions\Dependency as DependencyException;
16
17
/**
18
 * Main class for Stripe module
19
 */
20
class Main
21
{
22
23
    /**
24
     * The current order
25
     * @var array
26
     */
27
    protected $data_order;
28
29
    /**
30
     * Stripe token
31
     * @var string
32
     */
33
    protected $data_token;
34
35
    /**
36
     * Omnipay response instance
37
     * @var object
38
     */
39
    protected $response;
40
41
    /**
42
     * Frontend controller instance
43
     * @var \gplcart\core\controllers\frontend\Controller $controller
44
     */
45
    protected $controller;
46
47
    /**
48
     * Order model instance
49
     * @var \gplcart\core\models\Order $order
50
     */
51
    protected $order;
52
53
    /**
54
     * Module class instance
55
     * @var \gplcart\core\Module $module
56
     */
57
    protected $module;
58
59
    /**
60
     * @param Module $module
61
     */
62
    public function __construct(Module $module)
63
    {
64
        $this->module = $module;
65
    }
66
67
    /**
68
     * Implements hook "module.enable.before"
69
     * @param mixed $result
70
     */
71
    public function hookModuleEnableBefore(&$result)
72
    {
73
        $this->checkGateway($result);
74
    }
75
76
    /**
77
     * Implements hook "module.install.before"
78
     * @param mixed $result
79
     */
80
    public function hookModuleInstallBefore(&$result)
81
    {
82
        $this->checkGateway($result);
83
    }
84
85
    /**
86
     * Implements hook "route.list"
87
     * @param array $routes
88
     */
89
    public function hookRouteList(array &$routes)
90
    {
91
        $routes['admin/module/settings/stripe'] = array(
92
            'access' => 'module_edit',
93
            'handlers' => array(
94
                'controller' => array('gplcart\\modules\\stripe\\controllers\\Settings', 'editSettings')
95
            )
96
        );
97
    }
98
99
    /**
100
     * Implements hook "payment.methods"
101
     * @param array $methods
102
     */
103
    public function hookPaymentMethods(array &$methods)
104
    {
105
        $methods['stripe'] = array(
106
            'module' => 'stripe',
107
            'image' => 'image/icon.png',
108
            'status' => $this->getStatus(),
109
            'title' => 'Stripe',
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'] === 'stripe') {
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'] === 'stripe') {
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
        $this->setCompletePage($order, $model, $controller);
149
    }
150
151
    /**
152
     * Check that Stripe gateway object is loaded
153
     * @param mixed $result
154
     */
155
    protected function checkGateway(&$result)
156
    {
157
        try {
158
            $this->getGateway();
159
        } catch (Exception $ex) {
160
            $result = $ex->getMessage();
161
        }
162
    }
163
164
    /**
165
     * Set up order complete page
166
     * @param array $order
167
     * @param \gplcart\core\models\Order $model
168
     * @param \gplcart\core\controllers\frontend\Controller $controller
169
     */
170
    protected function setCompletePage(array $order, $model, $controller)
171
    {
172
        if ($order['payment'] === 'stripe') {
173
174
            $this->order = $model;
175
            $this->data_order = $order;
176
            $this->controller = $controller;
177
178
            $this->submitPayment();
179
180
            $controller->setJs('https://js.stripe.com/v2');
181
            $controller->setJs('system/modules/stripe/js/common.js');
182
            $controller->setJsSettings('stripe', array('key' => $this->getPublicKey()));
183
        }
184
    }
185
186
    /**
187
     * Returns Stripe gateway object
188
     * @return \Omnipay\Stripe\Gateway
189
     * @throws DependencyException
190
     */
191
    public function getGateway()
192
    {
193
        /* @var $module \gplcart\modules\omnipay_library\Main */
194
        $module = $this->module->getInstance('omnipay_library');
195
        $gateway = $module->getGatewayInstance('Stripe');
196
197
        if (!$gateway instanceof \Omnipay\Stripe\Gateway) {
0 ignored issues
show
Bug introduced by
The class Omnipay\Stripe\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...
198
            throw new DependencyException('Gateway must be instance of Omnipay\Stripe\Gateway');
199
        }
200
201
        return $gateway;
202
    }
203
204
    /**
205
     * Returns a public API key
206
     * @return string
207
     */
208
    public function getPublicKey()
209
    {
210
        $key = $this->getModuleSetting('test') ? 'test_public_key' : 'live_public_key';
211
        return $this->getModuleSetting($key);
212
    }
213
214
    /**
215
     * Returns a secret API key
216
     * @return string
217
     */
218
    public function getSecretKey()
219
    {
220
        $key = $this->getModuleSetting('test') ? 'test_key' : 'live_key';
221
        return $this->getModuleSetting($key);
222
    }
223
224
    /**
225
     * Returns a module setting
226
     * @param string $name
227
     * @param mixed $default
228
     * @return mixed
229
     */
230
    protected function getModuleSetting($name, $default = null)
231
    {
232
        return $this->module->getSettings('stripe', $name, $default);
233
    }
234
235
    /**
236
     * Returns the current status of the payment method
237
     */
238
    protected function getStatus()
239
    {
240
        if (!$this->getModuleSetting('status')) {
241
            return false;
242
        }
243
244
        if ($this->getModuleSetting('test')) {
245
            return $this->getModuleSetting('test_key') && $this->getModuleSetting('test_public_key');
246
        }
247
248
        return $this->getModuleSetting('live_key') && $this->getModuleSetting('live_public_key');
249
    }
250
251
    /**
252
     * Handles submitted payment
253
     */
254
    protected function submitPayment()
255
    {
256
        $this->data_token = $this->controller->getPosted('stripeToken', '', true, 'string');
257
258
        if (!empty($this->data_token)) {
259
260
            $params = array(
261
                'token' => $this->data_token,
262
                'currency' => $this->data_order['currency'],
263
                'amount' => $this->data_order['total_formatted_number']
264
            );
265
266
            $gateway = $this->getGateway();
267
            $gateway->setApiKey($this->getSecretKey());
268
            $this->response = $gateway->purchase($params)->send();
269
            $this->processResponse();
270
        }
271
    }
272
273
    /**
274
     * Processes gateway response
275
     */
276
    protected function processResponse()
277
    {
278
        if ($this->response->isSuccessful()) {
279
            $this->updateOrderStatus();
280
            $this->addTransaction();
281
            $this->redirectSuccess();
282
        } else if ($this->response->isRedirect()) {
283
            $this->response->redirect();
284
        } else {
285
            $this->controller->redirect('', $this->response->getMessage(), 'warning', true);
286
        }
287
    }
288
289
    /**
290
     * Redirect on successful transaction
291
     */
292
    protected function redirectSuccess()
293
    {
294
        $vars = array(
295
            '@num' => $this->data_order['order_id'],
296
            '@status' => $this->order->getStatusName($this->data_order['status'])
297
        );
298
299
        $message = $this->controller->text('Thank you! Payment has been made. Order #@num, status: @status', $vars);
300
        $this->controller->redirect('/', $message, 'success', true);
301
    }
302
303
    /**
304
     * Update order status after successful transaction
305
     */
306
    protected function updateOrderStatus()
307
    {
308
        $data = array('status' => $this->getModuleSetting('order_status_success'));
309
        $this->order->update($this->data_order['order_id'], $data);
310
        $this->data_order = $this->order->get($this->data_order['order_id']);
311
    }
312
313
    /**
314
     * Adds a transaction
315
     * @return integer
316
     */
317
    protected function addTransaction()
318
    {
319
        /* @var $model \gplcart\core\models\Transaction */
320
        $model = Container::get('gplcart\\core\\models\\Transaction');
321
322
        $transaction = array(
323
            'total' => $this->data_order['total'],
324
            'order_id' => $this->data_order['order_id'],
325
            'currency' => $this->data_order['currency'],
326
            'payment_method' => $this->data_order['payment'],
327
            'gateway_transaction_id' => $this->response->getTransactionReference()
328
        );
329
330
        return $model->add($transaction);
331
    }
332
333
}
334