Completed
Push — master ( 926943...3dc2ab )
by Iurii
01:12
created

Stripe.php (1 issue)

Labels
Severity

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

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 gplcart\core\Module;
13
use gplcart\core\models\Language as LanguageModel;
14
15
/**
16
 * Main class for Stripe module
17
 */
18
class Stripe extends Module
19
{
20
21
    /**
22
     * The current order
23
     * @var array
24
     */
25
    protected $data_order;
26
27
    /**
28
     * Stripe token
29
     * @var string
30
     */
31
    protected $data_token;
32
33
    /**
34
     * Omnipay response instance
35
     * @var object
36
     */
37
    protected $response;
38
39
    /**
40
     * Frontend controller instance
41
     * @var \gplcart\core\controllers\frontend\Controller $controller
42
     */
43
    protected $controller;
44
45
    /**
46
     * Language model instance
47
     * @var \gplcart\core\models\Language $language
48
     */
49
    protected $language;
50
51
    /**
52
     * Order model instance
53
     * @var \gplcart\core\models\Order $order
54
     */
55
    protected $order;
56
57
    /**
58
     * @param LanguageModel $language
59
     */
60
    public function __construct(LanguageModel $language)
61
    {
62
        parent::__construct();
63
64
        $this->language = $language;
65
    }
66
67
    /**
68
     * Returns Stripe gateway object
69
     * @return object
70
     * @throws \InvalidArgumentException
71
     */
72
    protected function getGatewayInstance()
73
    {
74
        /* @var $model \gplcart\modules\omnipay_library\OmnipayLibrary */
75
        $model = $this->getInstance('gplcart\\modules\\omnipay_library\\OmnipayLibrary');
76
        
77
        $instance = $model->getGatewayInstance('Stripe');
78
79
        if (!$instance instanceof \Omnipay\Stripe\Gateway) {
0 ignored issues
show
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...
80
            throw new \InvalidArgumentException('Object is not instance of Omnipay\Stripe\Gateway');
81
        }
82
83
        return $instance;
84
    }
85
86
    /**
87
     * Implements hook "module.enable.before"
88
     * @param mixed $result
89
     */
90
    public function hookModuleEnableBefore(&$result)
91
    {
92
        try {
93
            $this->getGatewayInstance();
94
        } catch (\InvalidArgumentException $ex) {
95
            $result = $ex->getMessage();
96
        }
97
    }
98
99
    /**
100
     * Implements hook "module.install.before"
101
     * @param mixed $result
102
     */
103
    public function hookModuleInstallBefore(&$result)
104
    {
105
        try {
106
            $this->getGatewayInstance();
107
        } catch (\InvalidArgumentException $ex) {
108
            $result = $ex->getMessage();
109
        }
110
    }
111
112
    /**
113
     * Implements hook "route.list"
114
     * @param array $routes 
115
     */
116
    public function hookRouteList(array &$routes)
117
    {
118
        $routes['admin/module/settings/stripe'] = array(
119
            'access' => 'module_edit',
120
            'handlers' => array(
121
                'controller' => array('gplcart\\modules\\stripe\\controllers\\Settings', 'editSettings')
122
            )
123
        );
124
    }
125
126
    /**
127
     * Implements hook "payment.methods"
128
     * @param array $methods 
129
     */
130
    public function hookPaymentMethods(array &$methods)
131
    {
132
        $methods['stripe'] = array(
133
            'module' => 'stripe',
134
            'image' => 'image/icon.png',
135
            'status' => $this->getStatus(),
136
            'title' => $this->language->text('Stripe'),
137
            'template' => array('complete' => 'pay')
138
        );
139
    }
140
141
    /**
142
     * Returns a module setting
143
     * @param string $name
144
     * @param mixed $default
145
     * @return mixed
146
     */
147
    protected function setting($name, $default = null)
148
    {
149
        return $this->config->module('stripe', $name, $default);
150
    }
151
152
    /**
153
     * Returns the current status of the payment method
154
     */
155
    protected function getStatus()
156
    {
157
        if (!$this->setting('status')) {
158
            return false;
159
        }
160
        if ($this->setting('test')) {
161
            return $this->setting('test_key') && $this->setting('test_public_key');
162
        }
163
        return $this->setting('live_key') && $this->setting('live_public_key');
164
    }
165
166
    /**
167
     * Returns a public API key
168
     * @return string
169
     */
170
    protected function getPublicKey()
171
    {
172
        $key = $this->setting('test') ? 'test_public_key' : 'live_public_key';
173
        return $this->setting($key);
174
    }
175
176
    /**
177
     * Returns a secret API key
178
     * @return string
179
     */
180
    protected function getSecretKey()
181
    {
182
        $key = $this->setting('test') ? 'test_key' : 'live_key';
183
        return $this->setting($key);
184
    }
185
186
    /**
187
     * Implements hook "order.add.before"
188
     * @param array $order
189
     * @param \gplcart\core\models\Order $model
190
     */
191
    public function hookOrderAddBefore(array &$order, $model)
192
    {
193
        // Adjust order status before creation
194
        // We want to get payment in advance, so assign "awaiting payment" status
195
        if ($order['payment'] === 'stripe') {
196
            $order['status'] = $model->getStatusAwaitingPayment();
197
        }
198
    }
199
200
    /**
201
     * Implements hook "order.checkout.complete"
202
     * @param string $message
203
     * @param array $order
204
     */
205
    public function hookOrderCompleteMessage(&$message, $order)
206
    {
207
        if ($order['payment'] === 'stripe') {
208
            $message = ''; // Hide default message
209
        }
210
    }
211
212
    /**
213
     * Implements hook "order.complete.page"
214
     * @param array $order
215
     * @param \gplcart\core\models\Order $model
216
     * @param \gplcart\core\controllers\frontend\Controller $controller
217
     */
218
    public function hookOrderCompletePage(array $order, $model, $controller)
219
    {
220
        if ($order['payment'] !== 'stripe') {
221
            return null;
222
        }
223
224
        $this->order = $model;
225
        $this->data_order = $order;
226
        $this->controller = $controller;
227
228
        $this->submit();
229
230
        $controller->setJs('https://js.stripe.com/v2');
231
        $controller->setJs('system/modules/stripe/js/common.js');
232
        $controller->setJsSettings('stripe', array('key' => $this->getPublicKey()));
233
    }
234
235
    /**
236
     * Handles submitted payment
237
     * @return null
238
     */
239
    protected function submit()
240
    {
241
        $this->data_token = $this->controller->getPosted('stripeToken', '', true, 'string');
242
243
        if (empty($this->data_token)) {
244
            return null;
245
        }
246
247
        $params = array(
248
            'token' => $this->data_token,
249
            'currency' => $this->data_order['currency'],
250
            'amount' => $this->data_order['total_formatted_number']
251
        );
252
253
        $gateway = $this->getGatewayInstance();
254
        $gateway->setApiKey($this->getSecretKey());
255
        $this->response = $gateway->purchase($params)->send();
256
        return $this->processResponse();
257
    }
258
259
    /**
260
     * Processes gateway response
261
     * @return boolean
262
     */
263
    protected function processResponse()
264
    {
265
        if ($this->response->isSuccessful()) {
266
            $this->updateOrderStatus();
267
            $this->addTransaction();
268
            $this->redirectSuccess();
269
            return true;
270
        }
271
272
        if ($this->response->isRedirect()) {
273
            $this->response->redirect();
274
            return true;
275
        }
276
277
        $this->redirectError();
278
        return false;
279
    }
280
281
    /**
282
     * Redirect on error transaction
283
     */
284
    protected function redirectError()
285
    {
286
        $this->controller->redirect('', $this->response->getMessage(), 'warning', true);
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->setting('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
        $transaction = array(
320
            'total' => $this->data_order['total'],
321
            'order_id' => $this->data_order['order_id'],
322
            'currency' => $this->data_order['currency'],
323
            'payment_method' => $this->data_order['payment'],
324
            'gateway_transaction_id' => $this->response->getTransactionReference()
325
        );
326
327
        /* @var $object \gplcart\core\models\Transaction */
328
        $object = $this->getInstance('gplcart\\core\\models\\Transaction');
329
        return $object->add($transaction);
330
    }
331
332
}
333