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