Passed
Push — master ( 91af14...32a131 )
by Jason
03:27
created

AddToCartForm::getProductFields()   B

Complexity

Conditions 9
Paths 62

Size

Total Lines 92
Code Lines 56

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 9
eloc 56
nc 62
nop 1
dl 0
loc 92
rs 7.4044
c 0
b 0
f 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
namespace Dynamic\Foxy\Form;
4
5
use Dynamic\Foxy\Extension\Purchasable;
6
use Dynamic\Foxy\Extension\Shippable;
7
use Dynamic\Foxy\Model\Foxy;
8
use Dynamic\Foxy\Model\FoxyHelper;
9
use Dynamic\Foxy\Model\ProductOption;
10
use SilverStripe\Forms\CompositeField;
11
use SilverStripe\Forms\DropdownField;
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\RequiredFields;
18
19
class AddToCartForm extends Form
20
{
21
    /**
22
     * @var
23
     */
24
    protected $helper;
25
26
    /**
27
     * @var
28
     */
29
    private $product;
30
31
    /**
32
     * @param $helper
33
     *
34
     * @return $this
35
     */
36
    public function setFoxyHelper($helper)
37
    {
38
        $helper = $helper === null ? FoxyHelper::create() : $helper;
39
        if ($helper instanceof FoxyHelper) {
40
            $this->helper = $helper;
41
            return $this;
42
        }
43
        throw new \InvalidArgumentException('$helper needs to be an instance of FoxyHelper.');
44
    }
45
46
    /**
47
     * @return FoxyHelper
48
     */
49
    public function getFoxyHelper()
50
    {
51
        if (!$this->helper) {
52
            $this->setFoxyHelper(FoxyHelper::create());
53
        }
54
        return $this->helper;
55
    }
56
57
    /**
58
     * @param $product
59
     *
60
     * @return $this
61
     */
62
    public function setProduct($product)
63
    {
64
        if ($product->isProduct()) {
65
            $this->product = $product;
66
            return $this;
67
        }
68
        throw new \InvalidArgumentException('$product needs to implement a Foxy DataExtension.');
69
    }
70
71
    /**
72
     * @return ProductPage
0 ignored issues
show
Bug introduced by
The type Dynamic\Foxy\Form\ProductPage 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...
73
     */
74
    public function getProduct()
75
    {
76
        return $this->product;
77
    }
78
79
    /**
80
     * AddToCartForm constructor.
81
     *
82
     * @param ContentController $controller
0 ignored issues
show
Bug introduced by
The type Dynamic\Foxy\Form\ContentController 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...
83
     * @param string $name
84
     * @param FieldList|null $fields
85
     * @param FieldList|null $actions
86
     * @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...
87
     * @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...
88
     * @param null $helper
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $helper is correct as it would always require null to be passed?
Loading history...
89
     *
90
     */
91
    public function __construct(
92
        $controller,
93
        $name,
94
        FieldList $fields = null,
95
        FieldList $actions = null,
96
        $validator = null,
97
        $product = null,
98
        $helper = null
99
    ) {
100
        $this->setProduct($product);
101
        $this->setFoxyHelper($helper);
102
103
        $fields = ($fields != null && $fields->exists()) ?
104
            $this->getProductFields($fields) :
105
            $this->getProductFields(FieldList::create());
106
107
        $actions = ($actions != null && $actions->exists()) ?
108
            $this->getProductActions($actions) :
109
            $this->getProductActions(FieldList::create());
110
111
        $validator = (!empty($validator) || $validator != null) ? $validator : RequiredFields::create();
112
113
        parent::__construct($controller, $name, $fields, $actions, $validator);
114
115
        //have to call after parent::__construct()
116
        $this->setAttribute('action', FoxyHelper::FormActionURL());
117
        $this->disableSecurityToken();
118
        $this->setHTMLID($this->getTemplateHelper()->generateFormID($this) . "_{$product->ID}");
119
    }
120
121
    /**
122
     * @param FieldList $fields
123
     *
124
     * @return FieldList
125
     */
126
    protected function getProductFields(FieldList $fields)
127
    {
128
        $hiddenTitle = ($this->product->ReceiptTitle) ?
129
            htmlspecialchars($this->product->ReceiptTitle) :
130
            htmlspecialchars($this->product->Title);
131
        $code = $this->product->Code;
132
133
        if ($this->product->isAvailable()) {
134
            $fields->push(
135
                HiddenField::create('name')
136
                    ->setValue(
137
                        self::getGeneratedValue($code, 'name', $hiddenTitle, 'value')
138
                    )
139
            );
140
141
            $fields->push(
142
                HiddenField::create('category')
143
                    ->setValue(
144
                        self::getGeneratedValue($code, 'category', $this->product->FoxyCategory()->Code, 'value')
145
                    )
146
            );
147
148
            $fields->push(
149
                HiddenField::create('code')
150
                    ->setValue(
151
                        self::getGeneratedValue($code, 'code', $this->product->Code, 'value')
152
                    )
153
            );
154
155
            $fields->push(
156
                HiddenField::create('product_id')
157
                    ->setValue(
158
                        self::getGeneratedValue($code, 'product_id', $this->product->ID, 'value')
159
                    )
160
                    ->setName('h:product_id')
161
            );
162
163
            $fields->push(
164
                HiddenField::create('price')
165
                    ->setValue(
166
                        self::getGeneratedValue($code, 'price', $this->product->Price, 'value')
167
                    )
168
            );
169
170
            if ($this->product->hasExtension(Shippable::class)) {
171
                if ($this->product->Weight > 0) {
172
                    $fields->push(
173
                        HiddenField::create('weight')
174
                            ->setValue(
175
                                self::getGeneratedValue($code, 'weight', $this->product->Weight, 'value')
176
                            )
177
                    );
178
                }
179
            }
180
181
            $image = null;
182
            if ($this->product->hasMethod('getImage')) {
183
                if ($this->product->getImage()) {
184
                    $image = $this->product->getImage()->CMSThumbnail()->absoluteURL;
185
                }
186
                if ($image) {
187
                    $fields->push(
188
                        HiddenField::create('image')
189
                            ->setValue(
190
                                self::getGeneratedValue($code, 'image', $image, 'value')
191
                            )
192
                    );
193
                }
194
            }
195
196
            $optionsSet = $this->getProductOptionSet();
197
            $fields->push($optionsSet);
198
            $quantityMax = (FoxyHelper::config()->get('max_quantity' != null)) ?
0 ignored issues
show
Unused Code introduced by
The assignment to $quantityMax is dead and can be removed.
Loading history...
199
                FoxyHelper::config()->get('MaxQuantity') :
200
                10;
201
            $fields->push(QuantityField::create('x:visibleQuantity')->setTitle('Quantity')->setValue(1));
202
            $fields->push(
203
                HiddenField::create('quantity')
204
                    ->setValue(
205
                        self::getGeneratedValue($code, 'quantity', 1, 'value')
206
                    )
207
            );
208
209
            $fields->push(
210
                HeaderField::create('submitPrice', '$' . $this->product->Price, 4)
211
                    ->addExtraClass('submit-price')
212
            );
213
        }
214
215
        $this->extend('updateProductFields', $fields);
216
217
        return $fields;
218
    }
219
220
    /**
221
     * @param FieldList $actions
222
     *
223
     * @return FieldList
224
     */
225
    protected function getProductActions(FieldList $actions)
226
    {
227
        if (!empty(trim($this->helper->getStoreCartURL())) && $this->product->isAvailable()) {
228
            $actions->push(
229
                FormAction::create(
230
                    'x:submit',
231
                    _t(__CLASS__ . '.AddToCart', 'Add to Cart')
232
                )
233
                    ->addExtraClass('fs-add-to-cart-button')
234
                    ->setName('x:submit')
235
            );
236
        }
237
238
        $this->extend('updateProductActions', $actions);
239
240
        return $actions;
241
    }
242
243
    /**
244
     * @param null $productCode
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $productCode is correct as it would always require null to be passed?
Loading history...
245
     * @param null $optionName
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $optionName is correct as it would always require null to be passed?
Loading history...
246
     * @param null $optionValue
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $optionValue is correct as it would always require null to be passed?
Loading history...
247
     * @param string $method
248
     * @param bool $output
249
     * @param bool $urlEncode
250
     *
251
     * @return null|string
252
     */
253
    // todo - Purchasable Extension or AddToCartForm? protected in Form
254
    public static function getGeneratedValue(
255
        $productCode = null,
256
        $optionName = null,
257
        $optionValue = null,
258
        $method = 'name',
259
        $output = false,
260
        $urlEncode = false
261
    ) {
262
        $optionName = ($optionName !== null) ? preg_replace('/\s/', '_', $optionName) : $optionName;
0 ignored issues
show
introduced by
The condition $optionName !== null is always false.
Loading history...
263
        $helper = FoxyHelper::create();
264
265
        return $helper::fc_hash_value($productCode, $optionName, $optionValue, $method, $output, $urlEncode);
266
    }
267
268
    /**
269
     * @return CompositeField
270
     */
271
    protected function getProductOptionSet()
272
    {
273
        /** @var CompositeField $optionsSet */
274
        $optionsSet = CompositeField::create();
275
276
        $types = $this->product->OptionTypes();
277
278
        foreach ($types as $type) {
279
            $title = $type->Title;
280
            $fieldName = preg_replace('/\s/', '_', $title);
281
            $disabled = [];
282
            $fullOptions = [];
283
284
            foreach ($type->Options() as $option) {
285
                $option = $this->setAvailability($option);
286
                $name = self::getGeneratedValue(
287
                    $this->product->Code,
288
                    $type->Title,
289
                    $option->getGeneratedValue(),
290
                    'value'
291
                );
292
293
                $fullOptions[$name] = $option->getGeneratedTitle();
294
                if (!$option->Availability) {
295
                    array_push($disabled, $name);
296
                }
297
            }
298
299
            $optionsSet->push(
300
                $dropdown = DropdownField::create($fieldName, $title, $fullOptions)->setTitle($title)
301
            );
302
303
            if (!empty($disabled)) {
304
                $dropdown->setDisabledItems($disabled);
305
            }
306
307
            $dropdown->addExtraClass("product-options");
308
        }
309
310
        $optionsSet->addExtraClass('foxycartOptionsContainer');
311
312
        return $optionsSet;
313
    }
314
315
    /**
316
     * @param OptionItem $option
0 ignored issues
show
Bug introduced by
The type Dynamic\Foxy\Form\OptionItem 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...
317
     * @return OptionItem
318
     */
319
    protected function setAvailability(ProductOption $option)
320
    {
321
        $option->Available = ($option->getAvailability()) ? true : false;
0 ignored issues
show
Bug Best Practice introduced by
The property Available does not exist on Dynamic\Foxy\Model\ProductOption. Since you implemented __set, consider adding a @property annotation.
Loading history...
322
        return $option;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $option returns the type Dynamic\Foxy\Model\ProductOption which is incompatible with the documented return type Dynamic\Foxy\Form\OptionItem.
Loading history...
323
    }
324
}
325