Passed
Push — master ( 228662...b9feb3 )
by Nic
02:48
created

Purchasable::updateCMSFields()   B

Complexity

Conditions 2
Paths 2

Size

Total Lines 77
Code Lines 55

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 2
eloc 55
c 2
b 0
f 0
nc 2
nop 1
dl 0
loc 77
rs 8.9818

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\Extension;
4
5
use Dynamic\Foxy\Model\FoxyCategory;
6
use Dynamic\Foxy\Model\ProductOption;
7
use SilverStripe\Forms\CheckboxField;
8
use SilverStripe\Forms\CurrencyField;
9
use SilverStripe\Forms\DropdownField;
10
use SilverStripe\Forms\FieldList;
11
use SilverStripe\Forms\GridField\GridField;
12
use SilverStripe\Forms\GridField\GridFieldAddExistingAutocompleter;
13
use SilverStripe\Forms\GridField\GridFieldConfig_RelationEditor;
14
use SilverStripe\Forms\NumericField;
15
use SilverStripe\Forms\TextField;
16
use SilverStripe\ORM\DataExtension;
17
use SilverStripe\ORM\ValidationResult;
18
use SilverStripe\Security\Permission;
19
use SilverStripe\Security\PermissionProvider;
20
use SilverStripe\Security\Security;
21
use Symbiote\GridFieldExtensions\GridFieldAddExistingSearchButton;
22
use Symbiote\GridFieldExtensions\GridFieldOrderableRows;
23
24
/**
25
 * Class Purchasable
26
 * @package Dynamic\Foxy\Extension
27
 *
28
 * @property double Price
29
 * @property string Code
30
 * @property string ReceiptTitle
31
 * @property bool Available
32
 * @property int $QuantityMax
33
 *
34
 * @property int FoxyCategoryID
35
 * @method FoxyCategory FoxyCategory()
36
 *
37
 * @method \SilverStripe\ORM\ManyManyList Options()
38
 *
39
 * @property-read \SilverStripe\ORM\DataObject|Purchasable $owner
40
 */
41
class Purchasable extends DataExtension implements PermissionProvider
42
{
43
    /**
44
     * @var array
45
     */
46
    private static $db = [
0 ignored issues
show
introduced by
The private property $db is not used, and could be removed.
Loading history...
47
        'Price' => 'Currency',
48
        'Code' => 'Varchar(100)',
49
        'ReceiptTitle' => 'HTMLVarchar(255)',
50
        'Available' => 'Boolean',
51
        'QuantityMax' => 'Int',
52
    ];
53
54
    /**
55
     * @var array
56
     */
57
    private static $has_one = [
0 ignored issues
show
introduced by
The private property $has_one is not used, and could be removed.
Loading history...
58
        'FoxyCategory' => FoxyCategory::class,
59
    ];
60
61
    /**
62
     * @var array
63
     */
64
    private static $many_many = [
0 ignored issues
show
introduced by
The private property $many_many is not used, and could be removed.
Loading history...
65
        'Options' => ProductOption::class,
66
    ];
67
68
    /**
69
     * @var array
70
     */
71
    private static $many_many_extraFields = [
0 ignored issues
show
introduced by
The private property $many_many_extraFields is not used, and could be removed.
Loading history...
72
        'Options' => [
73
            'WeightModifier' => 'Decimal(9,3)',
74
            'CodeModifier' => 'Text',
75
            'PriceModifier' => 'Currency',
76
            'WeightModifierAction' => "Enum('Add,Subtract,Set', null)",
77
            'CodeModifierAction' => "Enum('Add,Subtract,Set', null)",
78
            'PriceModifierAction' => "Enum('Add,Subtract,Set', null)",
79
            'Available' => 'Boolean',
80
            'Type' => 'Int',
81
            'OptionModifierKey' => 'Varchar(255)',
82
            'SortOrder' => 'Int',
83
        ],
84
        'OptionTypes' => [
85
            'SortOrder' => 'Int',
86
        ],
87
    ];
88
89
    /**
90
     * @var array
91
     */
92
    private static $indexes = [
0 ignored issues
show
introduced by
The private property $indexes is not used, and could be removed.
Loading history...
93
        'Code' => [
94
            'type' => 'unique',
95
            'columns' => ['Code'],
96
        ],
97
    ];
98
99
    /**
100
     * @var array
101
     */
102
    private static $defaults = [
0 ignored issues
show
introduced by
The private property $defaults is not used, and could be removed.
Loading history...
103
        'ShowInMenus' => false,
104
        'Available' => true,
105
    ];
106
107
    /**
108
     * @var array
109
     */
110
    private static $summary_fields = [
0 ignored issues
show
introduced by
The private property $summary_fields is not used, and could be removed.
Loading history...
111
        'Image.CMSThumbnail',
112
        'Title',
113
        'Code',
114
        'Price.Nice',
115
    ];
116
117
    /**
118
     * @var array
119
     */
120
    private static $searchable_fields = [
0 ignored issues
show
introduced by
The private property $searchable_fields is not used, and could be removed.
Loading history...
121
        'Title',
122
        'Code',
123
        'Available',
124
    ];
125
126
    /**
127
     * @param bool $includerelations
128
     *
129
     * @return array
130
     */
131
    public function updateFieldLabels(&$labels)
132
    {
133
        $labels['Title'] = _t(__CLASS__ . '.TitleLabel', 'Product Name');
134
        $labels['Code'] = _t(__CLASS__ . '.CodeLabel', 'Code');
135
        $labels['Price'] = _t(__CLASS__ . '.PriceLabel', 'Price');
136
        $labels['Price.Nice'] = _t(__CLASS__ . '.PriceLabel', 'Price');
137
        $labels['Available'] = _t(__CLASS__ . '.AvailableLabel', 'Available for purchase');
138
        $labels['Available.Nice'] = _t(__CLASS__ . '.AvailableLabelNice', 'Available');
139
        $labels['Image.CMSThumbnail'] = _t(__CLASS__ . '.ImageLabel', 'Image');
140
        $labels['ReceiptTitle'] = _t(__CLASS__ . '.ReceiptTitleLabel', 'Product title for receipt');
141
        $labels['FoxyCategoryID'] = _t(__CLASS__ . '.FoxyCategoryLabel', 'Foxy Category');
142
    }
143
144
    /**
145
     * @param FieldList $fields
146
     */
147
    public function updateCMSFields(FieldList $fields)
148
    {
149
        $fields->removeByName([
150
            'SKU',
151
        ]);
152
153
        $fields->addFieldsToTab(
154
            'Root.Ecommerce',
155
            [
156
                CurrencyField::create('Price')
157
                    ->setDescription(_t(
158
                        __CLASS__ . '.PriceDescription',
159
                        'Base price for this product. Can be modified using Product Options'
160
                    )),
161
                TextField::create('Code')
162
                    ->setDescription(_t(
163
                        __CLASS__ . '.CodeDescription',
164
                        'Required, must be unique. Product identifier used by FoxyCart in transactions. All leading and trailing spaces are removed on save.'
165
                    )),
166
                DropdownField::create('FoxyCategoryID')
167
                    ->setTitle($this->owner->fieldLabel('FoxyCategoryID'))
0 ignored issues
show
Bug introduced by
The method fieldLabel() does not exist on Dynamic\Foxy\Extension\Purchasable. ( Ignorable by Annotation )

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

167
                    ->setTitle($this->owner->/** @scrutinizer ignore-call */ fieldLabel('FoxyCategoryID'))

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
168
                    ->setSource(FoxyCategory::get()->map())
169
                    ->setDescription(_t(
170
                        __CLASS__ . '.FoxyCategoryDescription',
171
                        'Required. Must also exist in
172
                        <a href="https://admin.foxycart.com/admin.php?ThisAction=ManageProductCategories"
173
                            target="_blank">
174
                            Foxy Categories
175
                        </a>.
176
                        Used to set category specific options like shipping and taxes. Managed in Foxy > Categories'
177
                    ))
178
                    ->setEmptyString(''),
179
                TextField::create('ReceiptTitle')
180
                    ->setDescription(_t(
181
                        __CLASS__ . '.ReceiptTitleDescription',
182
                        'Optional. Alternate title to display on order receipt'
183
                    )),
184
            ],
185
            'Content'
186
        );
187
188
        if ($this->owner->ID) {
0 ignored issues
show
Bug Best Practice introduced by
The property ID does not exist on Dynamic\Foxy\Extension\Purchasable. Did you maybe forget to declare it?
Loading history...
189
            $config = GridFieldConfig_RelationEditor::create();
190
            $config
191
                ->addComponents([
192
                    new GridFieldOrderableRows('SortOrder'),
193
                    new GridFieldAddExistingSearchButton(),
194
                ])
195
                ->removeComponentsByType([
196
                    GridFieldAddExistingAutocompleter::class,
197
                ]);
198
            $options = GridField::create(
199
                'Options',
200
                'Options',
201
                $this->owner->Options()->sort('SortOrder'),
202
                $config
203
            );
204
205
            $fields->addFieldsToTab(
206
                'Root.Options',
207
                [
208
                    $options,
209
                ]
210
            );
211
        }
212
213
        $fields->addFieldsToTab(
214
            'Root.Inventory',
215
            [
216
                NumericField::create('QuantityMax')
217
                    ->setTitle('Maximum quantity allowed in the cart')
218
                    ->setDescription('For unlimited enter 0')
219
                    ->addExtraClass('stacked'),
220
                CheckboxField::create('Available')
221
                    ->setDescription(_t(
222
                        __CLASS__ . '.AvailableDescription',
223
                        'If unchecked, will remove "Add to Cart" form and instead display "Currently unavailable"'
224
                    )),
225
            ]
226
        );
227
    }
228
229
    /**
230
     * @return \SilverStripe\ORM\ValidationResult
231
     */
232
    public function validate(ValidationResult $validationResult)
233
    {
234
        /*
235
        if (!$this->owner->Price) {
236
            $validationResult->addError(
237
                _t(__CLASS__ . '.PriceRequired', 'You must set a product price in the Foxy tab')
238
            );
239
        }
240
241
        if (!$this->owner->Code) {
242
            $validationResult->addError(
243
                _t(__CLASS__ . '.CodeRequired', 'You must set a product code in the Foxy tab')
244
            );
245
        }
246
247
        if (!$this->owner->FoxyCategoryID) {
248
            $validationResult->addError(
249
                _t(__CLASS__ . '.FoxyCategoryRequired', 'You must set a foxy category in the Foxy tab.')
250
            );
251
        }
252
        */
253
    }
254
255
    /**
256
     * @return bool
257
     */
258
    public function isAvailable()
259
    {
260
        if (!$this->owner->Available) {
261
            return false;
262
        }
263
264
        if (!$this->owner->Options()->exists()) {
265
            return true;
266
        }
267
268
        foreach ($this->owner->Options() as $option) {
269
            if ($option->Available) {
270
                return true;
271
            }
272
        }
273
274
        return false;
275
    }
276
277
    /**
278
     * @return bool
279
     */
280
    public function isProduct()
281
    {
282
        return true;
283
    }
284
285
    /**
286
     * @return array
287
     */
288
    public function providePermissions()
289
    {
290
        return [
291
            'MANAGE_FOXY_PRODUCTS' => [
292
                'name' => _t(
293
                    __CLASS__ . '.PERMISSION_MANAGE_PRODUCTS_DESCRIPTION',
294
                    'Manage products'
295
                ),
296
                'category' => _t(
297
                    __CLASS__ . '.PERMISSIONS_CATEGORY',
298
                    'Foxy'
299
                ),
300
                'help' => _t(
301
                    __CLASS__ . '.PERMISSION_MANAGE_PRODUCTS_HELP',
302
                    'Manage products and related settings'
303
                ),
304
                'sort' => 400,
305
            ],
306
        ];
307
    }
308
309
    /**
310
     * @param $member
311
     * @return bool|int|void
312
     */
313
    public function canCreate($member)
314
    {
315
        if (!$member) {
316
            $member = Security::getCurrentUser();
317
        }
318
319
        return Permission::checkMember($member, 'MANAGE_FOXY_PRODUCTS');
320
    }
321
322
    /**
323
     * @param $member
324
     * @return bool|int|void|null
325
     */
326
    public function canEdit($member)
327
    {
328
        if (!$member) {
329
            $member = Security::getCurrentUser();
330
        }
331
332
        return Permission::checkMember($member, 'MANAGE_FOXY_PRODUCTS');
333
    }
334
335
    /**
336
     * @param $member
337
     * @return bool|int|void
338
     */
339
    public function canDelete($member)
340
    {
341
        if (!$member) {
342
            $member = Security::getCurrentUser();
343
        }
344
345
        return Permission::checkMember($member, 'MANAGE_FOXY_PRODUCTS');
346
    }
347
348
    /**
349
     * @param null $member
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $member is correct as it would always require null to be passed?
Loading history...
350
     * @return bool|int
351
     */
352
    public function canUnpublish($member = null)
353
    {
354
        if (!$member) {
0 ignored issues
show
introduced by
$member is of type null, thus it always evaluated to false.
Loading history...
355
            $member = Security::getCurrentUser();
356
        }
357
358
        return Permission::checkMember($member, 'MANAGE_FOXY_PRODUCTS');
359
    }
360
361
    /**
362
     * @param $member
363
     * @return bool|int
364
     */
365
    public function canArchive($member = null)
366
    {
367
        if (!$member) {
368
            $member = Security::getCurrentUser();
369
        }
370
371
        return Permission::checkMember($member, 'MANAGE_FOXY_PRODUCTS');
372
    }
373
374
    /**
375
     *
376
     */
377
    public function onBeforeWrite()
378
    {
379
        // trim spaces and replace duplicate spaces
380
        $trimmed = trim($this->owner->Code);
381
        $this->owner->Code = preg_replace('/\s+/', ' ', $trimmed);
382
    }
383
}
384