Passed
Pull Request — master (#356)
by Jason
03:00
created

FoxyStripePurchaseForm::getProductFields()   C

Complexity

Conditions 11
Paths 30

Size

Total Lines 90
Code Lines 72

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 132

Importance

Changes 0
Metric Value
eloc 72
dl 0
loc 90
ccs 0
cts 72
cp 0
rs 6.4642
c 0
b 0
f 0
cc 11
nc 30
nop 1
crap 132

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 Dynamic\FoxyStripe\Form;
4
5
use Dynamic\FoxyStripe\Model\FoxyCart;
6
use Dynamic\FoxyStripe\Model\FoxyStripeSetting;
7
use Dynamic\FoxyStripe\Model\OptionGroup;
8
use Dynamic\FoxyStripe\Model\OptionItem;
9
use Dynamic\FoxyStripe\ORM\ProductPageLegacy;
0 ignored issues
show
Bug introduced by
The type Dynamic\FoxyStripe\ORM\ProductPageLegacy was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
10
use Dynamic\FoxyStripe\Page\ProductPage;
11
use SilverStripe\CMS\Controllers\ContentController;
12
use SilverStripe\Dev\Debug;
13
use SilverStripe\Forms\CompositeField;
14
use SilverStripe\Forms\DropdownField;
15
use SilverStripe\Forms\FieldList;
16
use SilverStripe\Forms\Form;
17
use SilverStripe\Forms\FormAction;
18
use SilverStripe\Forms\HeaderField;
19
use SilverStripe\Forms\HiddenField;
20
use SilverStripe\Forms\RequiredFields;
21
use SilverStripe\ORM\DataList;
22
use SilverStripe\ORM\GroupedList;
23
use SilverStripe\SiteConfig\SiteConfig;
24
25
/**
26
 * Class FoxyStripePurchaseForm.
27
 *
28
 * @property FoxyStripeSetting $site_config
29
 * @property ProductPage $product
30
 */
31
class FoxyStripePurchaseForm extends Form
32
{
33
    /**
34
     * @var
35
     */
36
    protected $site_config;
37
38
    /**
39
     * @var
40
     */
41
    private $product;
42
43
    /**
44
     * @param $siteConfig
45
     *
46
     * @return $this
47
     */
48
    public function setSiteConfig($siteConfig)
49
    {
50
        $siteConfig = $siteConfig === null ? FoxyStripeSetting::current_foxystripe_setting() : $siteConfig;
51
        if ($siteConfig instanceof FoxyStripeSetting) {
52
            $this->site_config = $siteConfig;
53
54
            return $this;
55
        }
56
        throw new \InvalidArgumentException('$siteConfig needs to be an instance of FoxyStripeSetting.');
57
    }
58
59
    /**
60
     * @return FoxyStripeSetting
61
     */
62
    public function getSiteConfig()
63
    {
64
        if (!$this->site_config) {
65
            $this->setSiteConfig(FoxyStripeSetting::current_foxystripe_setting());
66
        }
67
68
        return $this->site_config;
69
    }
70
71
    /**
72
     * @param $product
73
     *
74
     * @return $this
75
     */
76
    public function setProduct($product)
77
    {
78
        if ($product instanceof ProductPage) {
79
            $this->product = $product;
80
81
            return $this;
82
        }
83
        throw new \InvalidArgumentException('$product needs to be an instance of ProductPage.');
84
    }
85
86
    /**
87
     * @return ProductPage
88
     */
89
    public function getProduct()
90
    {
91
        return $this->product;
92
    }
93
94
    /**
95
     * FoxyStripePurchaseForm constructor.
96
     *
97
     * @param ContentController $controller
98
     * @param string $name
99
     * @param FieldList|null $fields
100
     * @param FieldList|null $actions
101
     * @param null $validator
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $validator is correct as it would always require null to be passed?
Loading history...
102
     * @param null $product
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $product is correct as it would always require null to be passed?
Loading history...
103
     * @param null $siteConfig
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $siteConfig is correct as it would always require null to be passed?
Loading history...
104
     *
105
     */
106
    public function __construct(
107
        $controller,
108
        $name,
109
        FieldList $fields = null,
110
        FieldList $actions = null,
111
        $validator = null,
112
        $product = null,
113
        $siteConfig = null
114
    ) {
115
        $this->setProduct($product);
116
        $this->setSiteConfig($siteConfig);
117
118
        $fields = ($fields != null && $fields->exists()) ?
119
            $this->getProductFields($fields) :
120
            $this->getProductFields(FieldList::create());
121
122
        $actions = ($actions != null && $actions->exists()) ?
123
            $this->getProductActions($actions) :
124
            $this->getProductActions(FieldList::create());
125
        $validator = (!empty($validator) || $validator != null) ? $validator : RequiredFields::create();
126
127
        parent::__construct($controller, $name, $fields, $actions, $validator);
128
129
        //have to call after parent::__construct()
130
        $this->setAttribute('action', FoxyCart::FormActionURL());
131
        $this->disableSecurityToken();
132
    }
133
134
    /**
135
     * @param FieldList $fields
136
     *
137
     * @return FieldList
138
     */
139
    protected function getProductFields(FieldList $fields)
140
    {
141
        $hiddenTitle = ($this->product->ReceiptTitle) ?
142
            htmlspecialchars($this->product->ReceiptTitle) :
143
            htmlspecialchars($this->product->Title);
144
        $code = $this->product->Code;
145
146
        if ($this->product->Available) {
147
            $fields->push(HiddenField::create(ProductPage::getGeneratedValue(
148
                $code,
149
                'name',
150
                $hiddenTitle
151
            ))->setValue($hiddenTitle));
152
            $fields->push(HiddenField::create(ProductPage::getGeneratedValue(
153
                $code,
154
                'category',
155
                $this->product->Category()->Code
156
            ))->setValue($this->product->Category()->Code));
157
            $fields->push(HiddenField::create(ProductPage::getGeneratedValue(
158
                $code,
159
                'code',
160
                $this->product->Code
161
            ))->setValue($this->product->Code));
162
            $fields->push(HiddenField::create(ProductPage::getGeneratedValue(
163
                $code,
164
                'product_id',
165
                $this->product->ID
166
            ))->setValue($this->product->ID));
167
            $fields->push(HiddenField::create(ProductPage::getGeneratedValue(
168
                $code,
169
                'price',
170
                $this->product->Price
171
            ))->setValue($this->product->Price));//can't override id
172
            $fields->push(HiddenField::create(ProductPage::getGeneratedValue(
173
                $code,
174
                'weight',
175
                $this->product->Weight
176
            ))->setValue($this->product->Weight));
177
178
            $image = null;
179
            if ($this->product->Image() || ProductPage::has_extension(ProductPageLegacy::class)) {
180
                if ($this->product->Image()) {
181
                    $image = $this->product->Image()->Pad(80, 80)->absoluteURL;
182
                } elseif (ProductPage::has_extension(ProductPageLegacy::class) &&
183
                    $this->product->PreviewImage()->exists()) {
184
                    $image = $this->product->PreviewImage()->Pad(80, 80)->absoluteURL;
185
                }
186
                if ($image) {
187
                    $fields->push(
188
                        HiddenField::create(ProductPage::getGeneratedValue(
189
                            $code,
190
                            'image',
191
                            $image
192
                        ))->setValue($image)
193
                    );
194
                }
195
            }
196
197
            $optionsSet = $this->getProductOptionSet();
198
            $fields->push($optionsSet);
199
200
            $quantityMax = ($this->site_config->MaxQuantity) ? $this->site_config->MaxQuantity : 10;
201
            $count = 1;
202
            $quantity = array();
203
            while ($count <= $quantityMax) {
204
                $countVal = ProductPage::getGeneratedValue(
205
                    $this->product->Code,
206
                    'quantity',
207
                    $count,
208
                    'value'
209
                );
210
                $quantity[$countVal] = $count;
211
                ++$count;
212
            }
213
214
            $fields->push(DropdownField::create('quantity', 'Quantity', $quantity));
215
216
            $fields->push(HeaderField::create('submitPrice', '$'.$this->product->Price, 4)
217
                ->addExtraClass('submit-price'));
218
            $fields->push(HeaderField::create('unavailableText', 'Selection unavailable', 4)
219
                ->addExtraClass('hidden unavailable-text'));
220
221
            $this->extend('updatePurchaseFormFields', $fields);
222
        } else {
223
            $fields->push(HeaderField::create('submitPrice', 'Currently Out of Stock', 4));
224
        }
225
226
        $this->extend('updateFoxyStripePurchaseFormFields', $fields);
227
228
        return $fields;
229
    }
230
231
    /**
232
     * @param FieldList $actions
233
     *
234
     * @return FieldList
235
     */
236
    protected function getProductActions(FieldList $actions)
237
    {
238
        $actions->push($submit = FormAction::create(
239
            '',
240
            _t('ProductForm.AddToCart', 'Add to Cart')
241
        ));
242
        $submit->setAttribute(
243
            'name',
244
            ProductPage::getGeneratedValue(
245
                $this->product->Code,
246
                'Submit',
247
                _t('ProductForm.AddToCart', 'Add to Cart')
248
            )
249
        );
250
        if (!$this->site_config->StoreName ||
251
            $this->site_config->StoreName == '' ||
252
            !isset($this->site_config->StoreName) ||
253
            !$this->product->Available
254
        ) {
255
            $submit->setAttribute('Disabled', true);
256
        }
257
258
        $this->extend('updateFoxyStripePurchaseFormActions', $fields);
259
260
        return $actions;
261
    }
262
263
    /**
264
     * @return CompositeField
265
     */
266
    protected function getProductOptionSet()
267
    {
268
        $assignAvailable = function ($self) {
269
            /** @var OptionItem $self */
270
            $this->extend('updateFoxyStripePurchaseForm', $form);
271
            $self->Available = ($self->getAvailability()) ? true : false;
0 ignored issues
show
Documentation Bug introduced by
It seems like $self->getAvailability() ? true : false of type boolean is incompatible with the declared type SilverStripe\ORM\FieldType\DBBoolean of property $Available.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
272
        };
273
274
        $options = $this->product->ProductOptions();
275
        $groupedOptions = new GroupedList($options);
276
        $groupedBy = $groupedOptions->groupBy('ProductOptionGroupID');
277
278
        /** @var CompositeField $optionsSet */
279
        $optionsSet = CompositeField::create();
280
281
        /** @var DataList $set */
282
        foreach ($groupedBy as $id => $set) {
283
            $group = OptionGroup::get()->byID($id);
284
            $title = $group->Title;
285
            $name = preg_replace('/\s/', '_', $title);
286
            $set->each($assignAvailable);
287
            $disabled = array();
288
            $fullOptions = array();
289
            foreach ($set as $item) {
290
                $fullOptions[ProductPage::getGeneratedValue(
291
                    $this->product->Code,
292
                    $group->Title,
293
                    $item->getGeneratedValue(),
294
                    'value'
295
                )] = $item->getGeneratedTitle();
296
                if (!$item->Availability) {
297
                    array_push(
298
                        $disabled,
299
                        ProductPage::getGeneratedValue(
300
                            $this->product->Code,
301
                            $group->Title,
302
                            $item->getGeneratedValue(),
303
                            'value'
304
                        )
305
                    );
306
                }
307
            }
308
            $optionsSet->push(
309
                $dropdown = DropdownField::create($name, $title, $fullOptions)->setTitle($title)
310
            );
311
            $dropdown->setDisabledItems($disabled);
312
        }
313
314
        $optionsSet->addExtraClass('foxycartOptionsContainer');
315
316
        return $optionsSet;
317
    }
318
}
319