Completed
Push — master ( 8aec53...3b638e )
by Iurii
04:56
created

Stripe::getGatewayInstance()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 11
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

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