OrderActionsForm   A
last analyzed

Complexity

Total Complexity 31

Size/Duplication

Total Lines 238
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 122
c 1
b 0
f 0
dl 0
loc 238
rs 9.92
wmc 31

4 Methods

Rating   Name   Duplication   Size   Complexity  
B __construct() 0 82 10
B dopayment() 0 34 8
A docancel() 0 20 6
B getCCFields() 0 40 7
1
<?php
2
3
namespace SilverShop\Forms;
4
5
use SilverShop\Checkout\OrderEmailNotifier;
6
use SilverShop\Checkout\OrderProcessor;
7
use SilverShop\Extension\ShopConfigExtension;
8
use SilverShop\Model\Order;
9
use SilverStripe\Core\Config\Config;
10
use SilverStripe\Control\HTTPResponse;
11
use SilverStripe\Forms\CompositeField;
12
use SilverStripe\Forms\FieldList;
13
use SilverStripe\Forms\Form;
14
use SilverStripe\Forms\FormAction;
15
use SilverStripe\Forms\HeaderField;
16
use SilverStripe\Forms\HiddenField;
17
use SilverStripe\Forms\LiteralField;
18
use SilverStripe\Forms\OptionsetField;
19
use SilverStripe\Omnipay\GatewayFieldsFactory;
20
use SilverStripe\Omnipay\GatewayInfo;
21
use SilverStripe\ORM\FieldType\DBCurrency;
22
use SilverStripe\Security\Security;
23
use SilverStripe\View\Requirements;
24
25
/**
26
 * Perform actions on placed orders
27
 */
28
class OrderActionsForm extends Form
29
{
30
    private static $allowed_actions = [
0 ignored issues
show
introduced by
The private property $allowed_actions is not used, and could be removed.
Loading history...
31
        'docancel',
32
        'dopayment',
33
        'httpsubmission',
34
    ];
35
36
    private static $email_notification = false;
37
38
    private static $allow_paying = true;
39
40
    private static $allow_cancelling = true;
41
42
    private static $include_jquery = true;
43
44
    /**
45
     * @var Order the order
46
     */
47
    protected $order;
48
49
    /**
50
     * OrderActionsForm constructor.
51
     *
52
     * @param  $controller
53
     * @param  $name
54
     * @param  Order      $order
55
     * @throws \SilverStripe\Omnipay\Exception\InvalidConfigurationException
56
     */
57
    public function __construct($controller, $name, Order $order)
58
    {
59
        $this->order = $order;
60
        $fields = FieldList::create(
61
            HiddenField::create('OrderID', '', $order->ID)
62
        );
63
        $actions = FieldList::create();
64
        //payment
65
        if (self::config()->allow_paying && $order->canPay()) {
66
            $gateways = GatewayInfo::getSupportedGateways();
67
            //remove manual gateways
68
            foreach ($gateways as $gateway => $gatewayname) {
69
                if (GatewayInfo::isManual($gateway)) {
70
                    unset($gateways[$gateway]);
71
                }
72
            }
73
            if (!empty($gateways)) {
74
                $fields->push(
75
                    HeaderField::create(
76
                        'MakePaymentHeader',
77
                        _t(__CLASS__ . '.MakePayment', 'Make Payment')
78
                    )
79
                );
80
                $outstandingfield = DBCurrency::create_field(DBCurrency::class, $order->TotalOutstanding(true));
81
                $fields->push(
82
                    LiteralField::create(
83
                        'Outstanding',
84
                        _t(
85
                            'SilverShop\Model\Order.OutstandingWithAmount',
86
                            'Outstanding: {Amount}',
87
                            '',
88
                            ['Amount' => $outstandingfield->Nice()]
89
                        )
90
                    )
91
                );
92
                $fields->push(
93
                    OptionsetField::create(
94
                        'PaymentMethod',
95
                        _t(__CLASS__ . '.PaymentMethod', 'Payment Method'),
96
                        $gateways,
97
                        key($gateways)
98
                    )
99
                );
100
101
                if ($ccFields = $this->getCCFields($gateways)) {
102
                    if ($this->config()->include_jquery) {
103
                        Requirements::javascript('https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js');
104
                    }
105
                    Requirements::javascript('silvershop/core: client/dist/javascript/OrderActionsForm.js');
106
                    $fields->push($ccFields);
107
                }
108
109
                $actions->push(
110
                    FormAction::create(
111
                        'dopayment',
112
                        _t(__CLASS__ . '.PayOrder', 'Pay outstanding balance')
113
                    )->setUseButtonTag(Config::inst()->get(ShopConfigExtension::class, 'forms_use_button_tag'))
114
                );
115
            }
116
        }
117
        //cancelling
118
        if (self::config()->allow_cancelling && $order->canCancel()) {
119
            $actions->push(
120
                FormAction::create(
121
                    'docancel',
122
                    _t(__CLASS__ . '.CancelOrder', 'Cancel this order')
123
                )->setValidationExempt(true)
124
            );
125
        }
126
127
        parent::__construct(
128
            $controller,
129
            $name,
130
            $fields,
131
            $actions,
132
            OrderActionsFormValidator::create(
133
                [
134
                    'PaymentMethod'
135
                ]
136
            )
137
        );
138
        $this->extend('updateForm', $order);
139
    }
140
141
    /**
142
     * Make payment for a place order, where payment had previously failed.
143
     *
144
     * @param array $data
145
     * @param Form  $form
146
     *
147
     * @return HTTPResponse
148
     */
149
    public function dopayment($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

149
    public function dopayment(/** @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...
150
    {
151
        if (self::config()->allow_paying
152
            && $this->order
153
            && $this->order->canPay()
154
        ) {
155
            // Save payment data from form and process payment
156
            $data = $form->getData();
157
            $gateway = (!empty($data['PaymentMethod'])) ? $data['PaymentMethod'] : null;
158
159
            if (!GatewayInfo::isManual($gateway)) {
160
                $processor = OrderProcessor::create($this->order);
161
                $fieldFactory = new GatewayFieldsFactory(null);
162
                $response = $processor->makePayment(
163
                    $gateway,
164
                    $fieldFactory->normalizeFormData($data),
165
                    $processor->getReturnUrl()
166
                );
167
                if ($response && !$response->isError()) {
168
                    return $response->redirectOrRespond();
169
                } else {
170
                    $form->sessionMessage($processor->getError(), 'bad');
171
                }
172
            } else {
173
                $form->sessionMessage(_t(__CLASS__ . '.ManualNotAllowed', 'Manual payment not allowed'), 'bad');
174
            }
175
176
            return $this->controller->redirectBack();
177
        }
178
        $form->sessionMessage(
179
            _t(__CLASS__ . '.CouldNotProcessPayment', 'Payment could not be processed.'),
180
            'bad'
181
        );
182
        return $this->controller->redirectBack();
183
    }
184
185
    /**
186
     * Form action handler for CancelOrderForm.
187
     *
188
     * Take the order that this was to be change on,
189
     * and set the status that was requested from
190
     * the form request data.
191
     *
192
     * @param  array $data The form request data submitted
193
     * @param  Form  $form The {@link Form} this was submitted on
194
     * @throws \SilverStripe\ORM\ValidationException
195
     */
196
    public function docancel($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

196
    public function docancel(/** @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...
Unused Code introduced by
The parameter $form 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

196
    public function docancel($data, /** @scrutinizer ignore-unused */ $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...
197
    {
198
        if (self::config()->allow_cancelling
199
            && $this->order->canCancel()
200
        ) {
201
            $this->order->setField('Status', 'MemberCancelled');
202
            $this->order->write();
203
204
            if (self::config()->email_notification) {
205
                OrderEmailNotifier::create($this->order)->sendCancelNotification();
206
            }
207
208
            $this->controller->sessionMessage(
209
                _t(__CLASS__ . '.OrderCancelled', 'Order sucessfully cancelled'),
210
                'warning'
211
            );
212
            if (Security::getCurrentUser() && $link = $this->order->Link()) {
213
                $this->controller->redirect($link);
214
            } else {
215
                $this->controller->redirectBack();
216
            }
217
        }
218
    }
219
220
    /**
221
     * Get credit card fields for the given gateways
222
     *
223
     * @param  array $gateways
224
     * @return CompositeField|null
225
     */
226
    protected function getCCFields(array $gateways)
227
    {
228
        $fieldFactory = new GatewayFieldsFactory(null, ['Card']);
229
        $onsiteGateways = [];
230
        $allRequired = [];
231
        foreach ($gateways as $gateway => $title) {
232
            if (!GatewayInfo::isOffsite($gateway)) {
233
                $required = GatewayInfo::requiredFields($gateway);
234
                $onsiteGateways[$gateway] = $fieldFactory->getFieldName($required);
235
                $allRequired += $required;
236
            }
237
        }
238
239
        $allRequired = array_unique($allRequired);
240
        $allRequired = $fieldFactory->getFieldName(array_combine($allRequired, $allRequired));
241
242
        if (empty($onsiteGateways)) {
243
            return null;
244
        }
245
246
        $ccFields = $fieldFactory->getCardFields();
247
248
        // Remove all the credit card fields that aren't required by any gateway
249
        foreach ($ccFields->dataFields() as $name => $field) {
250
            if ($name && !in_array($name, $allRequired)) {
251
                $ccFields->removeByName($name, true);
252
            }
253
        }
254
255
        $lookupField = LiteralField::create(
256
            '_CCLookupField',
257
            sprintf(
258
                '<span class="gateway-lookup" data-gateways=\'%s\'></span>',
259
                json_encode($onsiteGateways, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP)
260
            )
261
        );
262
263
        $ccFields->push($lookupField);
264
265
        return CompositeField::create($ccFields)->setTag('fieldset')->addExtraClass('credit-card');
266
    }
267
}
268