PaymentForm::submitpayment()   C
last analyzed

Complexity

Conditions 14
Paths 60

Size

Total Lines 67
Code Lines 37

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 14
eloc 37
c 1
b 0
f 0
nc 60
nop 2
dl 0
loc 67
rs 6.2666

How to fix   Long Method    Complexity   

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
namespace SilverShop\Forms;
4
5
use SilverShop\Checkout\Checkout;
6
use SilverShop\Checkout\CheckoutComponentConfig;
7
use SilverShop\Checkout\Component\CheckoutComponentNamespaced;
8
use SilverShop\Checkout\Component\OnsitePayment;
9
use SilverShop\Checkout\OrderProcessor;
10
use SilverShop\Model\Order;
11
use SilverStripe\Omnipay\GatewayFieldsFactory;
12
use SilverStripe\Omnipay\GatewayInfo;
13
14
class PaymentForm extends CheckoutForm
15
{
16
    /**
17
     * @var string URL to redirect the user to on payment success.
18
     * Not the same as the "confirm" action in {@link PaymentGatewayController}.
19
     */
20
    protected $successlink;
21
22
    /**
23
     * @var string URL to redirect the user to on payment failure.
24
     * Not the same as the "cancel" action in {@link PaymentGatewayController}.
25
     */
26
    protected $failurelink;
27
28
    /**
29
     * @var OrderProcessor
30
     */
31
    protected $orderProcessor;
32
33
    public function __construct($controller, $name, CheckoutComponentConfig $config)
34
    {
35
        parent::__construct($controller, $name, $config);
36
37
        $this->orderProcessor = OrderProcessor::create($config->getOrder());
38
    }
39
40
    public function setSuccessLink($link)
41
    {
42
        $this->successlink = $link;
43
    }
44
45
    public function getSuccessLink()
46
    {
47
        return $this->successlink;
48
    }
49
50
    public function setFailureLink($link)
51
    {
52
        $this->failurelink = $link;
53
    }
54
55
    public function getFailureLink()
56
    {
57
        return $this->failurelink;
58
    }
59
60
    public function checkoutSubmit($data, $form)
61
    {
62
        // form validation has passed by this point, so we can save data
63
        $this->config->setData($form->getData());
64
        $order = $this->config->getOrder();
65
        $gateway = Checkout::get($order)->getSelectedPaymentMethod(false);
66
        if (GatewayInfo::isOffsite($gateway)
67
            || GatewayInfo::isManual($gateway)
68
            || $this->config->hasComponentWithPaymentData()
69
        ) {
70
            return $this->submitpayment($data, $form);
71
        }
72
73
        return $this->controller->redirect(
74
            $this->controller->Link('payment') //assumes CheckoutPage
75
        );
76
    }
77
78
    /**
79
     * Behaviour can be overwritten by creating a processPaymentResponse method
80
     * on the controller owning this form. It takes a Symfony\Component\HttpFoundation\Response argument,
81
     * and expects an SS_HTTPResponse in return.
82
     */
83
    public function submitpayment($data, $form)
0 ignored issues
show
Unused Code introduced by
The parameter $data is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

83
    public function submitpayment(/** @scrutinizer ignore-unused */ $data, $form)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
84
    {
85
        $data = $form->getData();
86
87
        $cancelUrl = $this->getFailureLink() ? $this->getFailureLink() : $this->controller->Link();
88
89
        $order = $this->config->getOrder();
90
91
        // final recalculation, before making payment
92
        $order->calculate();
93
        
94
        if ($order->isChanged()) {
95
            $order->write();
96
        }
97
        
98
        // handle cases where order total is 0. Note that the order will appear
99
        // as "paid", but without a Payment record attached.
100
        if ($order->GrandTotal() == 0 && Order::config()->allow_zero_order_total) {
101
            if (!$this->orderProcessor->placeOrder()) {
102
                $form->sessionMessage($this->orderProcessor->getError());
103
                return $this->controller->redirectBack();
104
            }
105
            return $this->controller->redirect($this->getSuccessLink());
106
        }
107
108
        // try to place order before payment, if configured
109
        if (Order::config()->place_before_payment) {
110
            if (!$this->orderProcessor->placeOrder()) {
111
                $form->sessionMessage($this->orderProcessor->getError());
112
                return $this->controller->redirectBack();
113
            }
114
            $cancelUrl = $this->orderProcessor->getReturnUrl();
115
        }
116
117
        // if we got here from checkoutSubmit and there's a namespaced Component that provides payment data,
118
        // we need to strip the inputs down to only the checkout component.
119
        $components = $this->config->getComponents();
120
        if ($components->first() instanceof CheckoutComponentNamespaced) {
121
            foreach ($components as $component) {
122
                if ($component->Proxy()->providesPaymentData()) {
123
                    $data = array_merge($data, $component->unnamespaceData($data));
124
                }
125
            }
126
        }
127
128
        $gateway = Checkout::get($order)->getSelectedPaymentMethod(false);
129
        $fieldFactory = new GatewayFieldsFactory($gateway);
130
131
        // This is where the payment is actually attempted
132
        $paymentResponse = $this->orderProcessor->makePayment(
133
            $gateway,
134
            $fieldFactory->normalizeFormData($data),
135
            $this->getSuccessLink(),
136
            $cancelUrl
137
        );
138
139
        $response = null;
140
        if ($this->controller->hasMethod('processPaymentResponse')) {
141
            $response = $this->controller->processPaymentResponse($paymentResponse, $form);
142
        } elseif ($paymentResponse && !$paymentResponse->isError()) {
143
            $response = $paymentResponse->redirectOrRespond();
144
        } else {
145
            $form->sessionMessage($this->orderProcessor->getError(), 'bad');
146
            $response = $this->controller->redirectBack();
147
        }
148
149
        return $response;
150
    }
151
152
    /**
153
     * @param OrderProcessor $processor
154
     */
155
    public function setOrderProcessor(OrderProcessor $processor)
156
    {
157
        $this->orderProcessor = $processor;
158
    }
159
160
    /**
161
     * @return OrderProcessor
162
     */
163
    public function getOrderProcessor()
164
    {
165
        return $this->orderProcessor;
166
    }
167
}
168