Completed
Push — master ( e312ae...228662 )
by Nic
10:54
created

ProductOption::getCode()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 12
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 8
c 0
b 0
f 0
nc 4
nop 1
dl 0
loc 12
rs 10
1
<?php
2
3
namespace Dynamic\Foxy\Model;
4
5
use Dynamic\Foxy\Extension\Purchasable;
6
use SilverStripe\CMS\Model\SiteTree;
7
use SilverStripe\Forms\CheckboxField;
8
use SilverStripe\Forms\CurrencyField;
9
use SilverStripe\Forms\DropdownField;
10
use SilverStripe\Forms\FieldList;
11
use SilverStripe\Forms\HeaderField;
12
use SilverStripe\Forms\NumericField;
13
use SilverStripe\Forms\ReadonlyField;
14
use SilverStripe\Forms\TextField;
15
use SilverStripe\ORM\DataObject;
16
use SilverStripe\ORM\FieldType\DBBoolean;
17
use SilverStripe\Security\Permission;
18
use SilverStripe\Security\Security;
19
20
/**
21
 * Class ProductOption
22
 * @package Dynamic\Foxy\Model
23
 *
24
 * @property string Title
25
 *
26
 * The following are from many_many_extraFields
27
 * @property-read double WeightModifier
28
 * @property-read string CodeModifier
29
 * @property-read double PriceModifier
30
 * @property-read string WeightModifierAction
31
 * @property-read string CodeModifierAction
32
 * @property-read string PriceModifierAction
33
 * @property-read bool Available
34
 * @property-read int Type
35
 * @property-read string OptionModifierKey
36
 * @property-read int SortOrder
37
 */
38
class ProductOption extends DataObject
39
{
40
    /**
41
     * @var array
42
     */
43
    private static $db = [
44
        'Title' => 'Varchar(255)',
45
    ];
46
47
    /**
48
     * @var string
49
     */
50
    private static $table_name = 'ProductOption';
51
52
    /**
53
     * @var string
54
     */
55
    private static $singular_name = 'Option';
56
57
    /**
58
     * @var string
59
     */
60
    private static $plural_name = 'Options';
61
62
    /**
63
     * @var array
64
     */
65
    private static $defaults = [
66
        'ManyMany[Available]' => true,
67
    ];
68
69
    /**
70
     * @var array
71
     */
72
    private static $summary_fields = [
73
        'Title' => 'Title',
74
        'IsAvailable' => 'Available',
75
        'OptionType' => 'Type',
76
    ];
77
78
    /**
79
     * @return FieldList
80
     */
81
    public function getCMSFields()
82
    {
83
        $this->beforeUpdateCMSFields(function (FieldList $fields) {
84
            if ($this->exists()) {
85
                $fields->addFieldToTab(
86
                    'Root.Main',
87
                    ReadonlyField::create('ManyMany[OptionModifierKey]')
88
                        ->setTitle(_t('OptionItem.ModifierKey', 'Modifier Key'))
89
                );
90
            }
91
92
            $fields->addFieldsToTab('Root.Main', [
93
                CheckboxField::create('ManyMany[Available]', 'Available for purchase'),
94
95
                DropdownField::create('ManyMany[Type]', 'Option Type', OptionType::get()->map())
96
                    ->setEmptyString(''),
97
98
                // Weight Modifier Fields
99
                HeaderField::create('WeightHD', _t('OptionItem.WeightHD', 'Modify Weight'), 4),
100
                NumericField::create("ManyMany[WeightModifier]")
101
                    ->setTitle(_t('OptionItem.WeightModifier', 'Weight'))
102
                    ->setScale(3)
103
                    ->setDescription(_t(
104
                        'OptionItem.WeightDescription',
105
                        'Only supports up to 3 decimal places'
106
                    )),
107
                DropdownField::create(
108
                    'ManyMany[WeightModifierAction]',
109
                    _t('OptionItem.WeightModifierAction', 'Weight Modification'),
110
                    [
111
                        'Add' => _t(
112
                            'OptionItem.WeightAdd',
113
                            'Add to Base Weight',
114
                            'Add to weight'
115
                        ),
116
                        'Subtract' => _t(
117
                            'OptionItem.WeightSubtract',
118
                            'Subtract from Base Weight',
119
                            'Subtract from weight'
120
                        ),
121
                        'Set' => _t('OptionItem.WeightSet', 'Set as a new Weight'),
122
                    ]
123
                )
124
                    ->setEmptyString('')
125
                    ->setDescription(_t(
126
                        'OptionItem.WeightDescription',
127
                        'Does weight modify or replace base weight?'
128
                    )),
129
130
                // Price Modifier Fields
131
                HeaderField::create('PriceHD', _t('OptionItem.PriceHD', 'Modify Price'), 4),
132
                CurrencyField::create('ManyMany[PriceModifier]')
133
                    ->setTitle(_t('OptionItem.PriceModifier', 'Price')),
134
                DropdownField::create(
135
                    'ManyMany[PriceModifierAction]',
136
                    _t('OptionItem.PriceModifierAction', 'Price Modification'),
137
                    [
138
                        'Add' => _t(
139
                            'OptionItem.PriceAdd',
140
                            'Add to Base Price',
141
                            'Add to price'
142
                        ),
143
                        'Subtract' => _t(
144
                            'OptionItem.PriceSubtract',
145
                            'Subtract from Base Price',
146
                            'Subtract from price'
147
                        ),
148
                        'Set' => _t('OptionItem.PriceSet', 'Set as a new Price'),
149
                    ]
150
                )
151
                    ->setEmptyString('')
152
                    ->setDescription(_t('OptionItem.PriceDescription', 'Does price modify or replace base price?')),
153
154
                // Code Modifier Fields
155
                HeaderField::create('CodeHD', _t('OptionItem.CodeHD', 'Modify Code'), 4),
156
                TextField::create('ManyMany[CodeModifier]')
157
                    ->setTitle(_t('OptionItem.CodeModifier', 'Code')),
158
                DropdownField::create(
159
                    'ManyMany[CodeModifierAction]',
160
                    _t('OptionItem.CodeModifierAction', 'Code Modification'),
161
                    [
162
                        'Add' => _t(
163
                            'OptionItem.CodeAdd',
164
                            'Add to Base Code',
165
                            'Add to code'
166
                        ),
167
                        'Subtract' => _t(
168
                            'OptionItem.CodeSubtract',
169
                            'Subtract from Base Code',
170
                            'Subtract from code'
171
                        ),
172
                        'Set' => _t('OptionItem.CodeSet', 'Set as a new Code'),
173
                    ]
174
                )
175
                    ->setEmptyString('')
176
                    ->setDescription(_t('OptionItem.CodeDescription', 'Does code modify or replace base code?')),
177
            ]);
178
        });
179
180
        return parent::getCMSFields();
181
    }
182
183
    /**
184
     *
185
     */
186
    public function onBeforeWrite()
187
    {
188
        parent::onBeforeWrite();
189
190
        $modifierKeyField = 'ManyMany[OptionModifierKey]';
191
        $this->{$modifierKeyField} = $this->getGeneratedValue();
192
193
        $codeModifierField = 'ManyMany[CodeModifier]';
194
        switch ($this->CodeModifierAction) {
195
            case 'Subtract':
196
            case 'Add':
197
                if ($this->config()->get('trimAllWhitespace') == false) {
198
                    // trim the right of the code - some companies use spaces to denote options
199
                    $trimmed = rtrim($this->{$codeModifierField});
200
                    // replace duplicate spaces
201
                    $this->{$codeModifierField} = preg_replace('/\s+/', ' ', $trimmed);
202
                    break;
203
                }
204
                /* falls through */
205
            case 'Set':
206
                $trimmed = trim($this->{$codeModifierField});
207
                $this->{$codeModifierField} = preg_replace('/\s+/', ' ', $trimmed);
208
                break;
209
        }
210
    }
211
212
    /**
213
     * @param $oma
214
     * @param bool $returnWithOnlyPlusMinus
215
     *
216
     * @return string
217
     */
218
    public static function getOptionModifierActionSymbol($oma, $returnWithOnlyPlusMinus = false)
219
    {
220
        switch ($oma) {
221
            case 'Subtract':
222
                $symbol = '-';
223
                break;
224
            case 'Set':
225
                $symbol = ($returnWithOnlyPlusMinus) ? '' : ':';
226
                break;
227
            default:
228
                $symbol = '+';
229
        }
230
231
        return $symbol;
232
    }
233
234
    /**
235
     * @return string
236
     */
237
    public function getWeightModifierWithSymbol()
238
    {
239
        return self::getOptionModifierActionSymbol($this->WeightModifierAction) . $this->WeightModifier;
240
    }
241
242
    /**
243
     * @return string
244
     */
245
    public function getPriceModifierWithSymbol()
246
    {
247
        return self::getOptionModifierActionSymbol($this->PriceModifierAction) . $this->PriceModifier;
248
    }
249
250
    /**
251
     * @return string
252
     */
253
    public function getCodeModifierWithSymbol()
254
    {
255
        return self::getOptionModifierActionSymbol($this->CodeModifierAction) . $this->CodeModifier;
256
    }
257
258
    /**
259
     * @return string
260
     */
261
    public function getGeneratedValue()
262
    {
263
        $modPrice = ($this->PriceModifier) ? (string)$this->PriceModifier : '0';
264
        $modPriceWithSymbol = self::getOptionModifierActionSymbol($this->PriceModifierAction) . $modPrice;
265
        $modWeight = ($this->WeightModifier) ? (string)$this->WeightModifier : '0';
266
        $modWeight = self::getOptionModifierActionSymbol($this->WeightModifierAction) . $modWeight;
267
        $modCode = self::getOptionModifierActionSymbol($this->CodeModifierAction) . $this->CodeModifier;
268
269
        return $this->Title . '{p' . $modPriceWithSymbol . '|w' . $modWeight . '|c' . $modCode . '}';
270
    }
271
272
    /**
273
     * @return mixed|string
274
     */
275
    public function getGeneratedTitle()
276
    {
277
        $modPrice = ($this->PriceModifier) ? (string)$this->PriceModifier : '0';
278
        $title = $this->Title;
279
        $title .= ($this->PriceModifier != 0) ?
280
            ': (' . self::getOptionModifierActionSymbol(
281
                $this->PriceModifierAction,
282
                $returnWithOnlyPlusMinus = true
283
            ) . '$' . $modPrice . ')' :
284
            '';
285
286
        return $title;
287
    }
288
289
    /**
290
     * @return bool
291
     */
292
    public function getAvailability()
293
    {
294
        $available = ($this->Available == 1) ? true : false;
295
        $this->extend('updateOptionAvailability', $available);
296
297
        return $available;
298
    }
299
300
    /**
301
     * @return string
302
     */
303
    public function getIsAvailable()
304
    {
305
        $available = DBBoolean::create();
306
        $available->setValue($this->getAvailability());
307
308
        return $available->Nice();
309
    }
310
311
    /**
312
     * @return string
313
     */
314
    public function getOptionType()
315
    {
316
        if ($this->Type) {
317
            $type = OptionType::get()->byID($this->Type);
318
            if ($type) {
0 ignored issues
show
introduced by
$type is of type SilverStripe\ORM\DataObject, thus it always evaluated to true.
Loading history...
319
                return $type->Title;
320
            }
321
        }
322
    }
323
324
    /**
325
     * @param $member
326
     * @return bool|int|void
327
     */
328
    public function canCreate($member = null, $context = [])
329
    {
330
        if (!$member) {
331
            $member = Security::getCurrentUser();
332
        }
333
334
        return Permission::checkMember($member, 'MANAGE_FOXY_PRODUCTS');
335
    }
336
337
    /**
338
     * @param $member
339
     * @return bool|int|void|null
340
     */
341
    public function canEdit($member = null, $context = [])
0 ignored issues
show
Unused Code introduced by
The parameter $context is not used and could be removed. ( Ignorable by Annotation )

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

341
    public function canEdit($member = null, /** @scrutinizer ignore-unused */ $context = [])

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
342
    {
343
        if (!$member) {
344
            $member = Security::getCurrentUser();
345
        }
346
347
        return Permission::checkMember($member, 'MANAGE_FOXY_PRODUCTS');
348
    }
349
350
    /**
351
     * @param $member
352
     * @return bool|int|void
353
     */
354
    public function canDelete($member = null, $context = [])
0 ignored issues
show
Unused Code introduced by
The parameter $context is not used and could be removed. ( Ignorable by Annotation )

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

354
    public function canDelete($member = null, /** @scrutinizer ignore-unused */ $context = [])

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
355
    {
356
        if (!$member) {
357
            $member = Security::getCurrentUser();
358
        }
359
360
        return Permission::checkMember($member, 'MANAGE_FOXY_PRODUCTS');
361
    }
362
363
    /**
364
     * @param Purchasable $product
365
     * @return mixed
366
     */
367
    public function getPrice($product)
368
    {
369
        switch ($this->PriceModifierAction) {
370
            case 'Subtract':
371
                return $product->Price - $this->PriceModifier;
372
            case 'Set':
373
                return $this->PriceModifier;
374
            case 'Add':
375
                return $product->Price + $this->PriceModifier;
376
        }
377
378
        return $product->Price;
379
    }
380
381
    /**
382
     * @param Purchasable $product
383
     * @return string
384
     */
385
    public function getCode($product)
386
    {
387
        switch ($this->CodeModifierAction) {
388
            case 'Subtract':
389
                return rtrim($product->Code, $this->CodeModifier);
390
            case 'Set':
391
                return $this->CodeModifier;
392
            case 'Add':
393
                return $product->Code . $this->CodeModifier;
394
        }
395
396
        return $product->Code;
397
    }
398
}
399