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