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