Passed
Push — master ( 751db6...a55259 )
by Jason
15:35 queued 11s
created

Purchasable::setHasVariations()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

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

155
                    ->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...
156
                    ->setSource(FoxyCategory::get()->map())
157
                    ->setDescription(_t(
158
                        __CLASS__ . '.FoxyCategoryDescription',
159
                        'Required. Must also exist in
160
                        <a href="https://admin.foxycart.com/admin.php?ThisAction=ManageProductCategories"
161
                            target="_blank">
162
                            Foxy Categories
163
                        </a>.
164
                        Used to set category specific options like shipping and taxes. Managed in Foxy > Categories'
165
                    ))
166
                    ->setEmptyString(''),
167
                TextField::create('ReceiptTitle')
168
                    ->setDescription(_t(
169
                        __CLASS__ . '.ReceiptTitleDescription',
170
                        'Optional. Alternate title to display on order receipt'
171
                    )),
172
            ],
173
            'Content'
174
        );
175
176
        if ($this->owner->exists()) {
0 ignored issues
show
Bug introduced by
The method exists() 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

176
        if ($this->owner->/** @scrutinizer ignore-call */ exists()) {

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...
177
            $variationsConfig = GridFieldConfig_RelationEditor::create()
178
                ->removeComponentsByType([
179
                    GridFieldAddExistingAutocompleter::class,
180
                    GridFieldPaginator::class,
181
                    GridFieldPageCount::class,
182
                    GridFieldSortableHeader::class,
183
                ])
184
                ->addComponents([
185
                    new GridFieldOrderableRows('SortOrder'),
186
                    new GridFieldTitleHeader(),
187
                    new GridFieldGroupable(
188
                        'VariationTypeID',    // The fieldname to set the Group
189
                        'Variation Type',   // A description of the function of the group
190
                        'none',         // A title/header for items without a group/unassigned
191
                        VariationType::get()->sort('SortOrder')->map()->toArray()
192
                    )
193
                ]);
194
195
            $fields->addFieldToTab(
196
                'Root.Variations',
197
                GridField::create(
198
                    'Variations',
199
                    'Variations',
200
                    $this->owner->Variations(),
201
                    $variationsConfig
202
                )
203
            );
204
        }
205
206
        $fields->addFieldsToTab(
207
            'Root.Inventory',
208
            [
209
                NumericField::create('QuantityMax')
210
                    ->setTitle('Maximum quantity allowed in the cart')
211
                    ->setDescription('For unlimited enter 0')
212
                    ->addExtraClass('stacked'),
213
                CheckboxField::create('Available')
214
                    ->setDescription(_t(
215
                        __CLASS__ . '.AvailableDescription',
216
                        'If unchecked, will remove "Add to Cart" form and instead display "Currently unavailable"'
217
                    )),
218
            ]
219
        );
220
    }
221
222
    /**
223
     * @return RequiredFields
224
     */
225
    public function getCMSValidator()
226
    {
227
        return new RequiredFields([
228
            "Price",
229
            "Code",
230
            "FoxyCategoryID",
231
        ]);
232
    }
233
234
    /**
235
     * @return mixed
236
     */
237
    public function isAvailable()
238
    {
239
        if (!$this->owner->Available) {
240
            return false;
241
        }
242
243
        if (!$this->owner->Variations()->count()) {
244
            return true;
245
        }
246
247
        foreach ($this->owner->Variations() as $variation) {
248
            if ($variation->Available) {
249
                return true;
250
            }
251
        }
252
253
        return false;
254
    }
255
256
    /**
257
     * @return bool
258
     */
259
    public function isProduct()
260
    {
261
        return true;
262
    }
263
264
    /**
265
     * @return array
266
     */
267
    public function providePermissions()
268
    {
269
        return [
270
            'MANAGE_FOXY_PRODUCTS' => [
271
                'name' => _t(
272
                    __CLASS__ . '.PERMISSION_MANAGE_PRODUCTS_DESCRIPTION',
273
                    'Manage products'
274
                ),
275
                'category' => _t(
276
                    __CLASS__ . '.PERMISSIONS_CATEGORY',
277
                    'Foxy'
278
                ),
279
                'help' => _t(
280
                    __CLASS__ . '.PERMISSION_MANAGE_PRODUCTS_HELP',
281
                    'Manage products and related settings'
282
                ),
283
                'sort' => 400,
284
            ],
285
        ];
286
    }
287
288
    /**
289
     * @param $member
290
     * @return bool|int|void
291
     */
292
    public function canCreate($member)
293
    {
294
        if (!$member) {
295
            $member = Security::getCurrentUser();
296
        }
297
298
        return Permission::checkMember($member, 'MANAGE_FOXY_PRODUCTS');
299
    }
300
301
    /**
302
     * @param $member
303
     * @return bool|int|void|null
304
     */
305
    public function canEdit($member)
306
    {
307
        if (!$member) {
308
            $member = Security::getCurrentUser();
309
        }
310
311
        return Permission::checkMember($member, 'MANAGE_FOXY_PRODUCTS');
312
    }
313
314
    /**
315
     * @param $member
316
     * @return bool|int|void
317
     */
318
    public function canDelete($member)
319
    {
320
        if (!$member) {
321
            $member = Security::getCurrentUser();
322
        }
323
324
        return Permission::checkMember($member, 'MANAGE_FOXY_PRODUCTS');
325
    }
326
327
    /**
328
     * @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...
329
     * @return bool|int
330
     */
331
    public function canUnpublish($member = null)
332
    {
333
        if (!$member) {
0 ignored issues
show
introduced by
$member is of type null, thus it always evaluated to false.
Loading history...
334
            $member = Security::getCurrentUser();
335
        }
336
337
        return Permission::checkMember($member, 'MANAGE_FOXY_PRODUCTS');
338
    }
339
340
    /**
341
     * @param $member
342
     * @return bool|int
343
     */
344
    public function canArchive($member = null)
345
    {
346
        if (!$member) {
347
            $member = Security::getCurrentUser();
348
        }
349
350
        return Permission::checkMember($member, 'MANAGE_FOXY_PRODUCTS');
351
    }
352
353
    /**
354
     *
355
     */
356
    public function onBeforeWrite()
357
    {
358
        // trim spaces and replace duplicate spaces
359
        $trimmed = trim($this->owner->Code);
360
        $this->owner->Code = preg_replace('/\s+/', ' ', $trimmed);
361
    }
362
}
363