GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.

placeOrderAction()   C
last analyzed

Complexity

Conditions 7
Paths 126

Size

Total Lines 70
Code Lines 45

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 70
rs 5.683
cc 7
eloc 45
nc 126
nop 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * Copyright (c) 2013-2014 eBay Enterprise, Inc.
4
 *
5
 * NOTICE OF LICENSE
6
 *
7
 * This source file is subject to the Open Software License (OSL 3.0)
8
 * that is bundled with this package in the file LICENSE.md.
9
 * It is also available through the world-wide-web at this URL:
10
 * http://opensource.org/licenses/osl-3.0.php
11
 *
12
 * @copyright   Copyright (c) 2013-2014 eBay Enterprise, Inc. (http://www.ebayenterprise.com/)
13
 * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
14
 */
15
16
/**
17
 * Checkout Controller for Ebay Enterprise PayPal
18
 */
19
class EbayEnterprise_PayPal_CheckoutController extends Mage_Core_Controller_Front_Action
20
{
21
    /** @var EbayEnterprise_Paypal_Model_Express_Checkout */
22
    protected $_checkout = null;
23
24
    /** @var EbayEnterprise_PayPal_Helper_Data */
25
    protected $_helper = null;
26
    /** @var EbayEnterprise_PayPal_Model_Config */
27
    protected $_config = null;
28
    /** @var Mage_Sales_Model_Quote */
29
    protected $_quote = false;
30
    /** @var Mage_Checkout_Helper_Data */
31
    protected $_checkoutHelper;
32
    /** @var EbayEnterprise_MageLog_Helper_Data */
33
    protected $_logger;
34
    /** @var EbayEnterprise_MageLog_Helper_Context */
35
    protected $_context;
36
37
    /**
38
     * prepare instances of the config model and the helper.
39
     */
40
    protected function _construct()
41
    {
42
        parent::_construct();
43
        $this->_helper = Mage::helper('ebayenterprise_paypal');
44
        $this->_config = $this->_helper->getConfigModel();
45
        $this->_logger = Mage::helper('ebayenterprise_magelog');
46
        $this->_context = Mage::helper('ebayenterprise_magelog/context');
47
        $this->_checkoutHelper = Mage::helper('checkout');
48
    }
49
50
    /**
51
     * prevent dispatching controller actions when not enabled.
52
     *
53
     * @return self
54
     */
55 View Code Duplication
    public function preDispatch()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
56
    {
57
        parent::preDispatch();
58
        if (!$this->_config->isEnabledFlag) {
0 ignored issues
show
Bug introduced by
The property isEnabledFlag does not seem to exist in EbayEnterprise_PayPal_Model_Config.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
59
            // when the payment method is disabled, prevent dispatching actions from
60
            // this controller.
61
            $this->setFlag('', static::FLAG_NO_DISPATCH, true)->_forward(
62
                '/noroute'
63
            );
64
        }
65
        return $this;
66
    }
67
68
    /**
69
     * return true if a guest is allowed to checkout without registering
70
     * @return boolean
71
     */
72
    protected function _isGuestAllowedWithoutRegistering($quoteCheckoutMethod, Mage_Sales_Model_Quote $quote)
73
    {
74
        return (!$quoteCheckoutMethod || $quoteCheckoutMethod != Mage_Checkout_Model_Type_Onepage::METHOD_REGISTER) &&
75
            !$this->_checkoutHelper->isAllowedGuestCheckout($quote, $quote->getStoreId());
76
    }
77
78
    /**
79
     * Start Express Checkout by requesting initial token and dispatching customer to PayPal
80
     */
81
    public function startAction()
82
    {
83
        try {
84
            $this->_initCheckout();
85
            $customer = Mage::getSingleton('customer/session')->getCustomer();
86
            $quoteCheckoutMethod = $this->_getQuote()->getCheckoutMethod();
87
            if ($customer && $customer->getId()) {
88
                $this->_checkout->setCustomerWithAddressChange(
89
                    $customer,
90
                    $this->_getQuote()->getBillingAddress(),
91
                    $this->_getQuote()->getShippingAddress()
92
                );
93
            } elseif ($this->_isGuestAllowedWithoutRegistering($quoteCheckoutMethod, $this->_getQuote())) {
94
                Mage::getSingleton('core/session')->addNotice(
95
                    $this->_helper->__(
96
                        'To proceed to Checkout, please log in using your email address.'
97
                    )
98
                );
99
                $this->redirectLogin();
100
                Mage::getSingleton('customer/session')
101
                    ->setBeforeAuthUrl(
102
                        Mage::getUrl('*/*/*', array('_current' => true))
103
                    );
104
                return;
105
            }
106
107
            try {
108
                $buttonKey = EbayEnterprise_Paypal_Model_Express_Checkout::PAYMENT_INFO_BUTTON;
109
                $startReply = $this->_checkout->start(
110
                    Mage::getUrl('*/*/return'),
111
                    Mage::getUrl('*/*/cancel'),
112
                    $this->getRequest()->getParam($buttonKey)
113
                );
114
                $this->_initToken($startReply['token']);
115
                $this->_redirectToPayPalSite($startReply);
116
                return;
117
            } catch (EbayEnterprise_PayPal_Exception $e) {
118
                $this->_getCheckoutSession()->addError($e->getMessage());
119
                $this->_redirect('checkout/cart');
120
            }
121
        } catch (Mage_Core_Exception $e) {
122
            $this->_getCheckoutSession()->addError($e->getMessage());
123
        } catch (Exception $e) {
124
            $this->_getCheckoutSession()->addError(
125
                $this->__('Unable to start Express Checkout.')
126
            );
127
            $this->_logger->logException($e, $this->_context->getMetaData(__CLASS__, [], $e));
128
        }
129
130
        $this->_redirect('checkout/cart');
131
    }
132
133
    /**
134
     * Return shipping options items for shipping address from request
135
     */
136
    public function shippingOptionsCallbackAction()
137
    {
138
        try {
139
            $quoteId = $this->getRequest()->getParam('quote_id');
140
            $this->_quote = Mage::getModel('sales/quote')->load($quoteId);
141
            $this->_initCheckout();
142
            $response = $this->_checkout->getShippingOptionsCallbackResponse(
0 ignored issues
show
Bug introduced by
The method getShippingOptionsCallbackResponse() does not seem to exist on object<EbayEnterprise_Pa...Model_Express_Checkout>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
143
                $this->getRequest()->getParams()
144
            );
145
            $this->getResponse()->setBody($response);
146
        } catch (Exception $e) {
147
            $this->_logger->logException($e, $this->_context->getMetaData(__CLASS__, [], $e));
148
        }
149
    }
150
151
    /**
152
     * Cancel Express Checkout
153
     */
154
    public function cancelAction()
155
    {
156
        try {
157
            $this->_initToken(false);
158
            // TODO verify if this logic of order cancelation is deprecated
0 ignored issues
show
Coding Style Best Practice introduced by
Comments for TODO tasks are often forgotten in the code; it might be better to use a dedicated issue tracker.
Loading history...
159
            // if there is an order - cancel it
160
            $orderId = $this->_getCheckoutSession()->getLastOrderId();
161
            $order = ($orderId) ? Mage::getModel('sales/order')->load($orderId)
162
                : false;
163
            if ($order && $order->getId()
164
                && $order->getQuoteId() == $this->_getCheckoutSession()
165
                    ->getQuoteId()
166
            ) {
167
                $order->cancel()->save();
168
                $this->_getCheckoutSession()
169
                    ->unsLastQuoteId()
170
                    ->unsLastSuccessQuoteId()
171
                    ->unsLastOrderId()
172
                    ->unsLastRealOrderId()
173
                    ->addSuccess(
174
                        $this->__(
175
                            'Express Checkout and Order have been canceled.'
176
                        )
177
                    );
178
            } else {
179
                $this->_getCheckoutSession()->addSuccess(
180
                    $this->__('Express Checkout has been canceled.')
181
                );
182
            }
183
        } catch (Mage_Core_Exception $e) {
184
            $this->_getCheckoutSession()->addError($e->getMessage());
185
        } catch (Exception $e) {
186
            $this->_getCheckoutSession()->addError(
187
                $this->__('Unable to cancel Express Checkout.')
188
            );
189
            $this->_logger->logException($e, $this->_context->getMetaData(__CLASS__, [], $e));
190
        }
191
192
        $this->_redirect('checkout/cart');
193
    }
194
195
    /**
196
     * Return from PayPal and dispatch customer to order review page
197
     */
198
    public function returnAction()
199
    {
200
        if ($this->getRequest()->getParam('retry_authorization') == 'true'
201
            && is_array(
202
                $this->_getCheckoutSession()->getPaypalTransactionData()
203
            )
204
        ) {
205
            $this->_forward('placeOrder');
206
            return;
207
        }
208
        try {
209
            $this->_getCheckoutSession()->unsPaypalTransactionData();
210
            $this->_checkout = $this->_initCheckout();
211
            $this->_checkout->returnFromPaypal($this->_initToken());
212
            $this->_redirect('*/*/review');
213
            return;
214
        } catch (Mage_Core_Exception $e) {
215
            Mage::getSingleton('checkout/session')->addError($e->getMessage());
216
        } catch (Exception $e) {
217
            Mage::getSingleton('checkout/session')->addError(
218
                $this->__('Unable to process Express Checkout approval.')
219
            );
220
            $this->_logger->logException($e, $this->_context->getMetaData(__CLASS__, [], $e));
221
        }
222
        $this->_redirect('checkout/cart');
223
    }
224
225
    /**
226
     * Review order after returning from PayPal
227
     */
228
    public function reviewAction()
229
    {
230
        /** @var Mage_Checkout_Model_Session */
231
        $checkoutSession = $this->_getCheckoutSession();
232
        if ($checkoutSession->getIsUseMultiShippingCheckout()) {
233
            /** @var array */
234
            $paymentData = (array) $checkoutSession->getMultiShippingPaymentData();
235
            $paymentData['is_return_from_paypal'] = true;
236
            $checkoutSession->setMultiShippingPaymentData($paymentData);
237
            $this->_redirect('checkout/multishipping/overview');
238
        }
239
        try {
240
            $this->_initCheckout();
241
            $this->_checkout->prepareOrderReview($this->_initToken());
0 ignored issues
show
Unused Code introduced by
The call to EbayEnterprise_PayPal_Mo...t::prepareOrderReview() has too many arguments starting with $this->_initToken().

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
242
            $this->loadLayout();
243
            $this->_initLayoutMessages('ebayenterprise_paypal/session');
244
            $this->renderLayout();
245
            return;
246
        } catch (Mage_Core_Exception $e) {
247
            $checkoutSession->addError($e->getMessage());
248
        } catch (Exception $e) {
249
            $checkoutSession->addError(
250
                $this->__('Unable to initialize Express Checkout review.')
251
            );
252
            $this->_logger->logException($e, $this->_context->getMetaData(__CLASS__, [], $e));
253
        }
254
        $this->_redirect('checkout/cart');
255
    }
256
257
    /**
258
     * Redirect back to PayPal to all editing payment information
259
     */
260
    public function editAction()
261
    {
262
        try {
263
            $this->_redirectToPayPalSite(
264
                array(
265
                    'useraction' => 'continue',
266
                    'token'      => $this->_initToken(),
267
                )
268
            );
269
        } catch (Mage_Core_Exception $e) {
270
            $this->_getSession()->addError($e->getMessage());
271
            $this->_redirect('*/*/review');
272
        }
273
    }
274
275
    /**
276
     * Update shipping method (combined action for ajax and regular request)
277
     */
278
    public function saveShippingMethodAction()
279
    {
280
        try {
281
            $isAjax = $this->getRequest()->getParam('isAjax');
282
            $this->_initCheckout();
283
            $this->_checkout->updateShippingMethod(
284
                $this->getRequest()->getParam('shipping_method')
285
            );
286
            if ($isAjax) {
287
                $this->loadLayout('paypal_express_review_details');
288
                $this->getResponse()->setBody(
289
                    $this->getLayout()->getBlock('root')
290
                        ->setQuote($this->_getQuote())
291
                        ->toHtml()
292
                );
293
                return;
294
            }
295
        } catch (Mage_Core_Exception $e) {
296
            $this->_getSession()->addError($e->getMessage());
297
        } catch (Exception $e) {
298
            $this->_getSession()->addError(
299
                $this->__('Unable to update shipping method.')
300
            );
301
            $this->_logger->logException($e, $this->_context->getMetaData(__CLASS__, [], $e));
302
        }
303
        if ($isAjax) {
304
            $this->getResponse()->setBody(
305
                '<script type="text/javascript">window.location.href = '
306
                . Mage::getUrl('*/*/review') . ';</script>'
307
            );
308
        } else {
309
            $this->_redirect('*/*/review');
310
        }
311
    }
312
313
    /**
314
     * Submit the order
315
     */
316
    public function placeOrderAction()
317
    {
318
        try {
319
            $requiredAgreements = $this->_checkoutHelper
320
                ->getRequiredAgreementIds();
321
            if ($requiredAgreements) {
322
                $postedAgreements = array_keys(
323
                    $this->getRequest()->getPost('agreement', array())
324
                );
325
                if (array_diff($requiredAgreements, $postedAgreements)) {
326
                    Mage::throwException(
327
                        $this->_helper->__(
328
                            'Please agree to all the terms and conditions before placing the order.'
329
                        )
330
                    );
331
                }
332
            }
333
334
            $this->_initCheckout();
335
            $this->_checkout->place($this->_initToken());
0 ignored issues
show
Documentation introduced by
$this->_initToken() is of type object<EbayEnterprise_PayPal_CheckoutController>, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
336
337
            // prepare session to success or cancellation page
338
            $session = $this->_getCheckoutSession();
339
            $session->clearHelperData();
340
341
            // last successful quote
342
            $quoteId = $this->_getQuote()->getId();
343
            $session->setLastQuoteId($quoteId)->setLastSuccessQuoteId($quoteId);
344
345
            // an order may be created
346
            $order = $this->_checkout->getOrder();
347
            if ($order) {
348
                $session->setLastOrderId($order->getId())
349
                    ->setLastRealOrderId($order->getIncrementId());
350
            }
351
            $this->_initToken(false); // no need in token anymore
352
            $this->_redirect('checkout/onepage/success');
353
            return;
354
        } catch (EbayEnterprise_PayPal_Exception $e) {
355
            $this->_checkoutHelper->sendPaymentFailedEmail(
356
                $this->_getQuote(),
357
                $e->getMessage()
358
            );
359
            $this->_logger->logException($e, $this->_context->getMetaData(__CLASS__, [], $e));
360
            // If a PayPal exception is thrown while trying to place the order,
361
            // the PayPal transaction failed or was voided and customer needs to
362
            // begin PayPal flow again. Place error message in checkout session
363
            // so it will be displayed in the cart and redirect back to the cart
364
            // for the checkout flow to begin again.
365
            $this->_getCheckoutSession()->addError($e->getMessage());
366
            $this->_redirect('checkout/cart');
367
        } catch (Mage_Core_Exception $e) {
368
            $this->_checkoutHelper->sendPaymentFailedEmail(
369
                $this->_getQuote(),
370
                $e->getMessage()
371
            );
372
            $this->_getSession()->addError($e->getMessage());
373
            $this->_redirect('*/*/review');
374
        } catch (Exception $e) {
375
            $this->_checkoutHelper->sendPaymentFailedEmail(
376
                $this->_getQuote(),
377
                $this->__('Unable to place the order.')
378
            );
379
            $this->_getSession()->addError(
380
                $this->__('Unable to place the order.')
381
            );
382
            $this->_logger->logException($e, $this->_context->getMetaData(__CLASS__, [], $e));
383
            $this->_redirect('*/*/review');
384
        }
385
    }
386
387
    /**
388
     * Redirect customer back to PayPal with the same token
389
     */
390
    protected function _redirectSameToken()
391
    {
392
        $token = $this->_initToken();
393
        $this->getResponse()->setRedirect(
394
            $this->_config->getExpressCheckoutStartUrl($token)
0 ignored issues
show
Bug introduced by
The method getExpressCheckoutStartUrl() does not seem to exist on object<EbayEnterprise_PayPal_Model_Config>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
395
        );
396
    }
397
398
    /**
399
     * Redirect customer to shopping cart and show error message
400
     *
401
     * @param string $errorMessage
402
     */
403
    protected function _redirectToCartAndShowError($errorMessage)
404
    {
405
        $cart = Mage::getSingleton('checkout/cart');
406
        $cart->getCheckoutSession()->addError($errorMessage);
407
        $this->_redirect('checkout/cart');
408
    }
409
410
    /**
411
     * Instantiate quote and checkout
412
     *
413
     * @return EbayEnterprise_PayPal_CheckoutController
414
     * @throws Mage_Core_Exception
415
     */
416
    protected function _initCheckout()
417
    {
418
        $quote = $this->_getQuote();
419
        if (!$quote->hasItems() || $quote->getHasError()) {
420
            $this->getResponse()->setHeader('HTTP/1.1', '403 Forbidden');
421
            Mage::throwException(
422
                $this->_helper->__('Unable to initialize Express Checkout.')
423
            );
424
        }
425
        $this->_checkout = Mage::getSingleton(
426
            'ebayenterprise_paypal/express_checkout',
427
            array(
428
                'helper' => $this->_helper,
429
                'logger' => null,
430
                'config' => $this->_config,
431
                'quote'  => $quote
432
            )
433
        );
434
        $this->_checkout->setCustomerSession(
435
            Mage::getSingleton('customer/session')
436
        );
437
        return $this->_checkout;
438
    }
439
440
    /**
441
     * Search for proper checkout token in request or session or (un)set specified one
442
     *
443
     * @param string $setToken
0 ignored issues
show
Documentation introduced by
Should the type for parameter $setToken not be string|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
444
     *
445
     * @return EbayEnterprise_PayPal_CheckoutController |string
446
     */
447
    protected function _initToken($setToken = null)
448
    {
449
        if (null !== $setToken) {
450
            if (false === $setToken) {
451
                // security measure for avoid unsetting token twice
452
                if (!$this->_getSession()->getExpressCheckoutToken()) {
453
                    Mage::throwException(
454
                        $this->_helper->__(
455
                            'PayPal Express Checkout Token does not exist.'
456
                        )
457
                    );
458
                }
459
                $this->_getSession()->unsExpressCheckoutToken();
460
            } else {
461
                $this->_getSession()->setExpressCheckoutToken($setToken);
462
            }
463
            return $this;
464
        }
465
        if ($setToken = $this->getRequest()->getParam('token')) {
466
            if ($setToken !== $this->_getSession()->getExpressCheckoutToken()) {
467
                Mage::throwException(
468
                    $this->_helper->__(
469
                        'Wrong PayPal Express Checkout Token specified.'
470
                    )
471
                );
472
            }
473
        } else {
474
            $setToken = $this->_getSession()->getExpressCheckoutToken();
475
        }
476
        return $setToken;
477
    }
478
479
    /**
480
     * PayPal session instance getter
481
     *
482
     * @return EbayEnterprise_PayPal_Model_Session
483
     */
484
    private function _getSession()
485
    {
486
        return Mage::getSingleton('ebayenterprise_paypal/session');
487
    }
488
489
    /**
490
     * Return checkout session object
491
     *
492
     * @return Mage_Checkout_Model_Session
493
     */
494
    protected function _getCheckoutSession()
495
    {
496
        return Mage::getSingleton('checkout/session');
497
    }
498
499
    /**
500
     * Return checkout quote object
501
     *
502
     * @return Mage_Sales_Model_Quote
503
     */
504
    private function _getQuote()
505
    {
506
        if (!$this->_quote) {
507
            return Mage::helper('ebayenterprise_paypal')->getQuote();
508
        }
509
        return $this->_quote;
510
    }
511
512
    /**
513
     * Redirect to login page
514
     *
515
     */
516
    public function redirectLogin()
517
    {
518
        $this->setFlag('', 'no-dispatch', true);
519
        $this->getResponse()->setRedirect(
520
            Mage::helper('core/url')->addRequestParam(
521
                Mage::helper('customer')->getLoginUrl(),
522
                array('context' => 'checkout')
523
            )
524
        );
525
    }
526
527
    /**
528
     * redirect to the paypal site so the user can login.
529
     *
530
     * @param  array $data
531
     * - requires 'token' => token string from the set express reply
532
     *
533
     * @return self
534
     */
535
    protected function _redirectToPayPalSite(array $data)
536
    {
537
        $data['cmd'] = '_express-checkout';
538
        $mode = $this->_config->isSandboxedFlag ? 'sandbox.' : '';
0 ignored issues
show
Bug introduced by
The property isSandboxedFlag does not seem to exist in EbayEnterprise_PayPal_Model_Config.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
539
        $queryString = http_build_query($data);
540
        $this->getResponse()->setRedirect(str_replace(
541
            array('{mode}', '{query_string}'),
542
            array($mode, $queryString),
543
            'https://www.{mode}paypal.com/cgi-bin/webscr?{query_string}'
544
        ));
545
        return $this;
546
    }
547
}
548