Completed
Push — master ( df2857...2b4027 )
by Nic
05:19
created

FoxyStripePurchaseForm   A

Complexity

Total Complexity 38

Size/Duplication

Total Lines 296
Duplicated Lines 0 %

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
wmc 38
eloc 130
dl 0
loc 296
ccs 0
cts 135
cp 0
rs 9.36
c 0
b 0
f 0

9 Methods

Rating   Name   Duplication   Size   Complexity  
A getSiteConfig() 0 7 2
A setSiteConfig() 0 9 3
A setProduct() 0 8 2
B __construct() 0 28 7
A getProduct() 0 3 1
C getProductFields() 0 102 13
A getProductActions() 0 14 3
A setAvailability() 0 5 2
A getProductOptionSet() 0 47 5
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
use SilverStripe\View\Requirements;
25
26
/**
27
 * Class FoxyStripePurchaseForm.
28
 *
29
 * @property FoxyStripeSetting $site_config
30
 * @property ProductPage $product
31
 */
32
class FoxyStripePurchaseForm extends Form
33
{
34
    /**
35
     * @var
36
     */
37
    protected $site_config;
38
39
    /**
40
     * @var
41
     */
42
    private $product;
43
44
    /**
45
     * @param $siteConfig
46
     *
47
     * @return $this
48
     */
49
    public function setSiteConfig($siteConfig)
50
    {
51
        $siteConfig = $siteConfig === null ? FoxyStripeSetting::current_foxystripe_setting() : $siteConfig;
52
        if ($siteConfig instanceof FoxyStripeSetting) {
53
            $this->site_config = $siteConfig;
54
55
            return $this;
56
        }
57
        throw new \InvalidArgumentException('$siteConfig needs to be an instance of FoxyStripeSetting.');
58
    }
59
60
    /**
61
     * @return FoxyStripeSetting
62
     */
63
    public function getSiteConfig()
64
    {
65
        if (!$this->site_config) {
66
            $this->setSiteConfig(FoxyStripeSetting::current_foxystripe_setting());
67
        }
68
69
        return $this->site_config;
70
    }
71
72
    /**
73
     * @param $product
74
     *
75
     * @return $this
76
     */
77
    public function setProduct($product)
78
    {
79
        if ($product instanceof ProductPage) {
80
            $this->product = $product;
81
82
            return $this;
83
        }
84
        throw new \InvalidArgumentException('$product needs to be an instance of ProductPage.');
85
    }
86
87
    /**
88
     * @return ProductPage
89
     */
90
    public function getProduct()
91
    {
92
        return $this->product;
93
    }
94
95
    /**
96
     * FoxyStripePurchaseForm constructor.
97
     *
98
     * @param ContentController $controller
99
     * @param string $name
100
     * @param FieldList|null $fields
101
     * @param FieldList|null $actions
102
     * @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...
103
     * @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...
104
     * @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...
105
     *
106
     */
107
    public function __construct(
108
        $controller,
109
        $name,
110
        FieldList $fields = null,
111
        FieldList $actions = null,
112
        $validator = null,
113
        $product = null,
114
        $siteConfig = null
115
    ) {
116
        $this->setProduct($product);
117
        $this->setSiteConfig($siteConfig);
118
119
        $fields = ($fields != null && $fields->exists()) ?
120
            $this->getProductFields($fields) :
121
            $this->getProductFields(FieldList::create());
122
123
        $actions = ($actions != null && $actions->exists()) ?
124
            $this->getProductActions($actions) :
125
            $this->getProductActions(FieldList::create());
126
        $validator = (!empty($validator) || $validator != null) ? $validator : RequiredFields::create();
127
128
        parent::__construct($controller, $name, $fields, $actions, $validator);
129
130
        //have to call after parent::__construct()
131
        $this->setAttribute('action', FoxyCart::FormActionURL());
132
        $this->disableSecurityToken();
133
134
        $this->setHTMLID($this->getTemplateHelper()->generateFormID($this) . "_{$product->ID}");
135
    }
136
137
    /**
138
     * @param FieldList $fields
139
     *
140
     * @return FieldList
141
     */
142
    protected function getProductFields(FieldList $fields)
143
    {
144
        //Requirements::javascript('dynamic/foxystripe: client/dist/javascript/scripts.min.js');
0 ignored issues
show
Unused Code Comprehensibility introduced by
72% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
145
        $hiddenTitle = ($this->product->ReceiptTitle) ?
146
            htmlspecialchars($this->product->ReceiptTitle) :
147
            htmlspecialchars($this->product->Title);
148
        $code = $this->product->Code;
149
150
        if ($this->product->Available) {
151
            $fields->push(
152
                HiddenField::create('name')
153
                    ->setValue(
154
                        ProductPage::getGeneratedValue($code, 'name', $hiddenTitle, 'value')
155
                    )
156
            );
157
            $fields->push(
158
                HiddenField::create('category')
159
                    ->setValue(
160
                        ProductPage::getGeneratedValue($code, 'category', $this->product->Category()->Code, 'value')
161
                    )
162
            );
163
            $fields->push(
164
                HiddenField::create('code')
165
                    ->setValue(
166
                        ProductPage::getGeneratedValue($code, 'code', $this->product->Code, 'value')
167
                    )
168
            );
169
            $fields->push(
170
                HiddenField::create(
171
                    'product_id'
172
                )->setValue(
173
                    ProductPage::getGeneratedValue($code, 'product_id', $this->product->ID, 'value')
174
                )
175
            );
176
            $fields->push(
177
                HiddenField::create('price')
178
                    ->setValue(
179
                        ProductPage::getGeneratedValue($code, 'price', $this->product->Price, 'value')
180
                    )
181
            );//can't override id
182
            if ($this->product->Weight > 0) {
183
                $fields->push(
184
                    HiddenField::create('weight')
185
                        ->setValue(
186
                            ProductPage::getGeneratedValue($code, 'weight', $this->product->Weight, 'value')
187
                        )
188
                );
189
            }
190
191
            $image = null;
192
            if ($this->product->Image() || ProductPage::has_extension(ProductPageLegacy::class)) {
193
                if ($this->product->Image()) {
194
                    $image = $this->product->Image()->Pad(80, 80)->absoluteURL;
195
                } elseif (ProductPage::has_extension(ProductPageLegacy::class) &&
196
                    $this->product->PreviewImage()->exists()) {
0 ignored issues
show
Bug introduced by
The method PreviewImage() does not exist on Dynamic\FoxyStripe\Page\ProductPage. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

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

196
                    $this->product->/** @scrutinizer ignore-call */ 
197
                                    PreviewImage()->exists()) {
Loading history...
197
                    $image = $this->product->PreviewImage()->Pad(80, 80)->absoluteURL;
198
                }
199
200
                if ($image) {
201
                    $fields->push(
202
                        HiddenField::create('image')
203
                            ->setValue(
204
                                ProductPage::getGeneratedValue($code, 'image', $image, 'value')
205
                            )
206
                    );
207
                }
208
            }
209
210
            $optionsSet = $this->getProductOptionSet();
211
            $fields->push($optionsSet);
212
213
            $quantityMax = ($this->site_config->MaxQuantity) ? $this->site_config->MaxQuantity : 10;
0 ignored issues
show
Unused Code introduced by
The assignment to $quantityMax is dead and can be removed.
Loading history...
214
215
            $fields->push(QuantityField::create('x:visibleQuantity')->setTitle('Quantity')->setValue(1));
216
            $fields->push(
217
                HiddenField::create('quantity')
218
                    ->setValue(
219
                        ProductPage::getGeneratedValue($code, 'quantity', 1, 'value')
220
                    )
221
            );
222
223
            $fields->push(
224
                HeaderField::create('submitPrice', '$' . $this->product->Price, 4)
225
                    ->addExtraClass('submit-price')
226
            );
227
            $fields->push(
228
                $unavailable = HeaderField::create('unavailableText', 'Selection unavailable', 4)
229
                    ->addExtraClass('unavailable-text')
230
            );
231
232
            if (!empty(trim($this->getSiteConfig()->StoreName)) && $this->getProduct()->getIsAvailable()) {
233
                $unavailable->addExtraClass('hidden');
234
            }
235
236
            $this->extend('updatePurchaseFormFields', $fields);
237
        } else {
238
            $fields->push(HeaderField::create('submitPrice', 'Currently Out of Stock', 4));
239
        }
240
241
        $this->extend('updateFoxyStripePurchaseFormFields', $fields);
242
243
        return $fields;
244
    }
245
246
    /**
247
     * @param FieldList $actions
248
     *
249
     * @return FieldList
250
     */
251
    protected function getProductActions(FieldList $actions)
252
    {
253
        if (!empty(trim($this->getSiteConfig()->StoreName)) && $this->getProduct()->getIsAvailable()) {
254
            $actions->push(
255
                $submit = FormAction::create(
256
                    'x:submit',
257
                    _t('ProductForm.AddToCart', 'Add to Cart')
258
                )->addExtraClass('fs-add-to-cart-button')
259
            );
260
        }
261
262
        $this->extend('updateFoxyStripePurchaseFormActions', $actions);
263
264
        return $actions;
265
    }
266
267
    /**
268
     * @return CompositeField
269
     */
270
    protected function getProductOptionSet()
271
    {
272
        $options = $this->product->ProductOptions();
273
        $groupedOptions = new GroupedList($options);
274
        $groupedBy = $groupedOptions->groupBy('ProductOptionGroupID');
275
276
        /** @var CompositeField $optionsSet */
277
        $optionsSet = CompositeField::create();
278
279
        /** @var DataList $set */
280
        foreach ($groupedBy as $id => $set) {
281
            $group = OptionGroup::get()->byID($id);
282
            $title = $group->Title;
283
            $name = preg_replace('/\s/', '_', $title);
284
            $disabled = [];
285
            $fullOptions = [];
286
287
            foreach ($set as $item) {
288
                $item = $this->setAvailability($item);
289
290
                $name = ProductPage::getGeneratedValue(
291
                    $this->product->Code,
292
                    $group->Title,
293
                    $item->getGeneratedValue(),
294
                    'value'
295
                );
296
297
                $fullOptions[$name] = $item->getGeneratedTitle();
298
                if (!$item->Availability) {
0 ignored issues
show
Bug Best Practice introduced by
The property Availability does not exist on Dynamic\FoxyStripe\Model\OptionItem. Since you implemented __get, consider adding a @property annotation.
Loading history...
299
                    array_push($disabled, $name);
300
                }
301
            }
302
303
            $optionsSet->push(
304
                $dropdown = DropdownField::create($name, $title, $fullOptions)->setTitle($title)
305
            );
306
307
            if (!empty($disabled)) {
308
                $dropdown->setDisabledItems($disabled);
309
            }
310
311
            $dropdown->addExtraClass("product-options");
312
        }
313
314
        $optionsSet->addExtraClass('foxycartOptionsContainer');
315
316
        return $optionsSet;
317
    }
318
319
    /**
320
     * @param OptionItem $option
321
     * @return OptionItem
322
     */
323
    protected function setAvailability(OptionItem $option)
324
    {
325
        $option->Available = ($option->getAvailability()) ? true : false;
0 ignored issues
show
Documentation Bug introduced by
It seems like $option->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...
326
327
        return $option;
328
    }
329
}
330