OrderModifier   F
last analyzed

Complexity

Total Complexity 81

Size/Duplication

Total Lines 835
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 19

Importance

Changes 0
Metric Value
dl 0
loc 835
rs 1.765
c 0
b 0
f 0
wmc 81
lcom 1
cbo 19

48 Methods

Rating   Name   Duplication   Size   Complexity  
A i18n_singular_name() 0 4 1
A i18n_plural_name() 0 4 1
A getCMSFields() 0 44 4
A scaffoldSearchFields() 0 7 1
A init_for_order() 0 6 1
A init() 0 9 1
A runUpdate() 0 13 4
A canBeUpdated() 0 4 1
A canCreate() 0 4 1
A canDelete() 0 4 1
A checkField() 0 12 3
A CalculationTotal() 0 8 2
A ShowForm() 0 4 1
A ShowFormInEditableOrderTable() 0 5 1
A ShowFormOutsideEditableOrderTable() 0 5 2
A getModifierForm() 0 10 2
A headingField() 0 9 2
A descriptionField() 0 9 2
A TableTitle() 0 4 1
A getTableTitle() 0 4 1
A getOrderModifier_Descriptor() 0 11 2
A Heading() 0 8 2
A Description() 0 8 2
A MoreInfoPage() 0 8 2
A ShowInTable() 0 10 3
A TableValueAsMoney() 0 4 1
A getTableValueAsMoney() 0 4 1
A HideInAjaxUpdate() 0 11 3
A CanBeRemoved() 0 4 1
A CanAdd() 0 4 2
A DoNotAddAutomatically() 0 4 1
A CalculatedTotal() 0 4 1
A AddLink() 0 12 5
A RemoveLink() 0 12 5
A PostSubmitAction() 0 4 1
A getRunningTotal() 0 4 1
A LiveName() 0 7 1
A LiveTableValue() 0 4 1
A LiveCalculatedTotal() 0 4 1
A IsChargeable() 0 4 1
A IsDeductable() 0 4 1
A IsNoChange() 0 4 1
A IsRemoved() 0 4 1
A onBeforeWrite() 0 4 1
A onBeforeRemove() 0 4 1
A onAfterRemove() 0 4 1
B updateForAjax() 0 61 4
A debug() 0 6 1

How to fix   Complexity   

Complex Class

Complex classes like OrderModifier often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use OrderModifier, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
/**
4
 * which returns an array of IDs
5
 * SEQUENCE - USE FOR ALL MODIFIERS!!!
6
 * *** 1. model defining static variables (e.g. $db, $has_one)
7
 * *** 2. cms variables + functions (e.g. getCMSFields, $searchableFields)
8
 * *** 3. other (non) static variables (e.g. private static $special_name_for_something, protected $order)
9
 * *** 4. CRUD functions (e.g. canEdit)
10
 * *** 5. init and update functions
11
 * *** 6. form functions (e. g. Showform and getform)
12
 * *** 7. template functions (e.g. ShowInTable, TableTitle, etc...) ... USES DB VALUES
13
 * *** 8. inner calculations.... USES CALCULATED VALUES
14
 * *** 9. calculate database fields: protected function Live[field name]  ... USES CALCULATED VALUES
15
 * *** 10. standard database related functions (e.g. onBeforeWrite, onAfterWrite, etc...)
16
 * *** 11. AJAX related functions
17
 * *** 12. debug functions.
18
 *
19
 * FAQs
20
 *
21
 * *** What is the difference between cart and table ***
22
 * The Cart is a smaller version of the Table. Table is used for Checkout Page + Confirmation page.
23
 * Cart is used for other pages (pre-checkout for example). At times, the values and names may differ
24
 *
25
 *
26
 * @authors: Nicolaas [at] Sunny Side Up .co.nz
27
 * @package: ecommerce
28
 * @sub-package: model
29
 * @inspiration: Silverstripe Ltd, Jeremy
30
 **/
31
class OrderModifier extends OrderAttribute
32
{
33
    /**
34
     * what variables are accessible through  http://mysite.com/api/ecommerce/v1/OrderModifier/.
35
     *
36
     * @var array
37
     */
38
    private static $api_access = array(
0 ignored issues
show
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
39
        'view' => array(
40
            'CalculatedTotal',
41
            'Sort',
42
            'GroupSort',
43
            'TableTitle',
44
            'TableSubTitle',
45
            'CartTitle',
46
            'CartSubTitle',
47
            'Name',
48
            'TableValue',
49
            'HasBeenRemoved',
50
            'Order',
51
        ),
52
    );
53
54
    // ########################################  *** 1. model defining static variables (e.g. $db, $has_one)
55
56
    /**
57
     * @var array
58
     *            stardard SS definition
59
     */
60
    private static $db = array(
0 ignored issues
show
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
61
        'Name' => 'HTMLText', // we use this to create the TableTitle, CartTitle and TableSubTitle
62
        'TableValue' => 'Currency', //the $$ shown in the checkout table
63
        'HasBeenRemoved' => 'Boolean', // we add this so that we can see what modifiers have been removed
64
    );
65
66
    /**
67
     * make sure to choose the right Type and Name for this.
68
     * stardard SS variable.
69
     *
70
     * @var array
71
     */
72
    private static $defaults = array(
0 ignored issues
show
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
73
        'Name' => 'Modifier', //making sure that you choose a different name for any class extensions.
74
    );
75
76
    // ########################################  *** 2. cms variables  + functions (e.g. getCMSFields, $searchableFields)
77
78
    /**
79
     * stardard SS variable.
80
     *
81
     * @var array
82
     */
83
    private static $searchable_fields = array(
0 ignored issues
show
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
84
        'OrderID' => array(
85
            'field' => 'NumericField',
86
            'title' => 'Order Number',
87
        ),
88
        //"TableTitle" => "PartialMatchFilter",
89
        'TableValue',
90
        'HasBeenRemoved',
91
    );
92
93
    /**
94
     * stardard SS definition.
95
     *
96
     * @var array
97
     */
98
    private static $summary_fields = array(
0 ignored issues
show
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
99
        'OrderID' => 'Order ID',
100
        'TableTitle' => 'Table Title',
101
        'TableSubTitle' => 'More ...',
102
        'TableValue' => 'Value Shown',
103
        'CalculatedTotal' => 'Calculation Total',
104
    );
105
106
    /**
107
     * stardard SS definition.
108
     *
109
     * @var array
110
     */
111
    private static $casting = array(
0 ignored issues
show
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
112
        'TableValueAsMoney' => 'Money',
113
    );
114
115
    /**
116
     * stardard SS variable.
117
     *
118
     * @var string
119
     */
120
    private static $singular_name = 'Order Modifier';
0 ignored issues
show
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
121
    public function i18n_singular_name()
122
    {
123
        return _t('OrderModifier.SINGULARNAME', 'Order Modifier');
124
    }
125
126
    /**
127
     * stardard SS variable.
128
     *
129
     * @var string
130
     */
131
    private static $plural_name = 'Order Modifiers';
0 ignored issues
show
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
132
    public function i18n_plural_name()
133
    {
134
        return _t('OrderModifier.PLURALNAME', 'Order Modifiers');
135
    }
136
137
    /**
138
     * Standard SS variable.
139
     *
140
     * @var string
141
     */
142
    private static $description = 'An addition to the order that sits between the sub-total and the total (e.g. tax, delivery, etc...).';
0 ignored issues
show
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
143
144
    /**
145
     * stardard SS metbod.
146
     *
147
     * @return FieldList
148
     */
149
    public function getCMSFields()
150
    {
151
        $fields = parent::getCMSFields();
152
        $fields->removeByName('Sort');
153
        $fields->removeByName('GroupSort');
154
        $fields->replaceField('Name', $nameField = new ReadonlyField('Name'));
155
        $nameField->dontEscape = true;
156
        $fields->removeByName('TableValue');
157
        $fields->removeByName('CalculatedTotal');
158
        $fields->removeByName('HasBeenRemoved');
159
        $fields->addFieldToTab(
160
            'Root',
161
            Tab::create(
162
                'Debug',
163
                _t('OrderModifier.DEBUG', 'Debug'),
164
                new ReadonlyField('CreatedShown', 'Created', $this->Created),
165
                new ReadonlyField('LastEditedShown', 'Last Edited', $this->LastEdited),
166
                new ReadonlyField('TableValueShown', 'Table Value', $this->TableValue),
0 ignored issues
show
Documentation introduced by
The property TableValue does not exist on object<OrderModifier>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
167
                new ReadonlyField('CalculatedTotal', 'Raw Value', $this->CalculatedTotal)
0 ignored issues
show
Documentation introduced by
The property CalculatedTotal does not exist on object<OrderModifier>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
168
            )
169
        );
170
171
        $fields->addFieldToTab('Root.Main', new CheckboxField('HasBeenRemoved', 'Has been removed'));
172
        $fields->removeByName('OrderAttribute_GroupID');
173
174
        //OrderID Field
175
        if ($this->OrderID && $this->exists()) {
0 ignored issues
show
Documentation introduced by
The property OrderID does not exist on object<OrderModifier>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
176
            $fields->replaceField('OrderID', $fields->dataFieldByName('OrderID')->performReadonlyTransformation());
177
        } else {
178
            $fields->replaceField('OrderID', new NumericField('OrderID'));
179
        }
180
181
        //ClassName Field
182
        $availableModifiers = EcommerceConfig::get('Order', 'modifiers');
183
184
        if ($this->exists()) {
185
            $fields->addFieldToTab('Root.Main', new LiteralField('MyClassName', '<h2>'.$this->singular_name().'</h2>'), 'Name');
186
        } else {
187
            $ecommerceClassNameOrTypeDropdownField = EcommerceClassNameOrTypeDropdownField::create('ClassName', 'Type', 'OrderModifier', $availableModifiers);
188
            $fields->addFieldToTab('Root.Main', $ecommerceClassNameOrTypeDropdownField, 'Name');
189
        }
190
191
        return $fields;
192
    }
193
194
    /**
195
     * Determine which properties on the DataObject are
196
     * searchable, and map them to their default {@link FormField}
197
     * representations. Used for scaffolding a searchform for {@link ModelAdmin}.
198
     *
199
     * Some additional logic is included for switching field labels, based on
200
     * how generic or specific the field type is.
201
     *
202
     * Used by {@link SearchContext}.
203
     *
204
     * @param array $_params
0 ignored issues
show
Documentation introduced by
Should the type for parameter $_params not be array|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
205
     *                       'fieldClasses': Associative array of field names as keys and FormField classes as values
206
     *                       'restrictFields': Numeric array of a field name whitelist
207
     *
208
     * @return FieldList
209
     */
210
    public function scaffoldSearchFields($_params = null)
211
    {
212
        $fields = parent::scaffoldSearchFields($_params);
213
        $fields->replaceField('OrderID', new NumericField('OrderID', 'Order Number'));
214
215
        return $fields;
216
    }
217
218
    // ########################################  *** 3. other static variables (e.g. special_name_for_something)
219
220
    /**
221
     * $doNotAddAutomatically Identifies whether a modifier is NOT automatically added
222
     * Most modifiers, such as delivery and GST would be added automatically.
223
     * However, there are also ones that are not added automatically.
224
     *
225
     * @var bool
226
     **/
227
    protected $doNotAddAutomatically = false;
228
229
    /**
230
     * $can_be_removed Identifies whether a modifier can be removed by the user.
231
     *
232
     * @var bool
233
     **/
234
    protected $canBeRemoved = false;
235
236
    /**
237
     * This is a flag for running an update.
238
     * Running an update means that all fields are (re)set, using the Live{FieldName} methods.
239
     *
240
     * @var bool
241
     **/
242
    protected $mustUpdate = false;
243
244
    /**
245
     * When recalculating all the modifiers, this private variable is added to as a running total
246
     * other modifiers can then tap into this to work out their own values.
247
     * For example, a tax modifier needs to know the value of the other modifiers before calculating
248
     * its own value (i.e. tax is also paid over handling and shipping).
249
     * Always consider the "order" (which one first) of the order modifiers when using this variable.
250
     *
251
     * @var float
252
     **/
253
    private $runningTotal = 0;
254
255
    // ######################################## *** 4. CRUD functions (e.g. canEdit)
256
257
    // ########################################  *** 5. init and update functions
258
259
    /**
260
     *
261
     */
262
    public static function init_for_order($className)
0 ignored issues
show
Unused Code introduced by
The parameter $className is not used and could be removed.

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

Loading history...
263
    {
264
        user_error('the init_for_order method has been depreciated, instead, use $myModifier->init()', E_USER_ERROR);
265
266
        return false;
267
    }
268
269
    /**
270
     * This method runs when the OrderModifier is first added to the order.
271
     **/
272
    public function init()
273
    {
274
        parent::init();
275
        $this->write();
276
        $this->mustUpdate = true;
277
        $this->runUpdate($force = false);
278
279
        return true;
280
    }
281
282
    /*
283
     * all classes extending OrderModifier must have this method if it has more fields
284
     * @param boolean $recalculate - run it, even if it has run already
285
     **/
286
    public function runUpdate($recalculate = false)
287
    {
288
        if (!$this->IsRemoved()) {
289
            $this->checkField('Name');
290
            $this->checkField('CalculatedTotal');
291
            $this->checkField('TableValue');
292
            if ($this->mustUpdate && $this->canBeUpdated()) {
293
                $this->write();
294
            }
295
            $this->runningTotal += $this->CalculatedTotal;
0 ignored issues
show
Documentation introduced by
The property CalculatedTotal does not exist on object<OrderModifier>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
296
        }
297
        parent::runUpdate($recalculate);
298
    }
299
300
    /**
301
     * You can overload this method as canEdit might not be the right indicator.
302
     *
303
     * @return bool
304
     **/
305
    protected function canBeUpdated()
306
    {
307
        return $this->canEdit();
308
    }
309
310
    /**
311
     * standard SS Method.
312
     *
313
     * @return bool
314
     **/
315
    public function canCreate($member = null)
316
    {
317
        return false;
318
    }
319
320
    /**
321
     * standard SS Method.
322
     *
323
     * @return bool
324
     **/
325
    public function canDelete($member = null)
326
    {
327
        return false;
328
    }
329
330
    /**
331
     * This method simply checks if a fields has changed and if it has changed it updates the field.
332
     *
333
     * @param string $fieldName
334
     **/
335
    protected function checkField($fieldName)
336
    {
337
        if ($this->canBeUpdated()) {
338
            $functionName = 'Live'.$fieldName;
339
            $oldValue = $this->$fieldName;
340
            $newValue = $this->$functionName();
341
            if ($oldValue != $newValue) {
342
                $this->$fieldName = $newValue;
343
                $this->mustUpdate = true;
344
            }
345
        }
346
    }
347
348
    /**
349
     * Provides a modifier total that is positive or negative, depending on whether the modifier is chargable or not.
350
     * This number is used to work out the order Grand Total.....
351
     * It is important to note that this can be positive or negative, while the amount is always positive.
352
     *
353
     * @return float / double
354
     */
355
    public function CalculationTotal()
356
    {
357
        if ($this->HasBeenRemoved) {
0 ignored issues
show
Documentation introduced by
The property HasBeenRemoved does not exist on object<OrderModifier>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
358
            return 0;
359
        }
360
361
        return $this->CalculatedTotal;
0 ignored issues
show
Documentation introduced by
The property CalculatedTotal does not exist on object<OrderModifier>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
362
    }
363
364
    // ########################################  *** 6. form functions (Showform and getform)
365
366
    /**
367
     * This determines whether the OrderModifierForm is shown or not. {@link OrderModifier::get_form()}.
368
     * OrderModifierForms are forms that are added to check out to facilitate the use of the modifier.
369
     * An example would be a form allowing the user to select the delivery option.
370
     *
371
     * @return bool
372
     */
373
    public function ShowForm()
374
    {
375
        return false;
376
    }
377
378
    /**
379
     * Should the form be included in the EDITABLE form
380
     * on the checkout page?
381
     *
382
     * @return bool
383
     */
384
    public function ShowFormInEditableOrderTable()
385
    {
386
        //extend in OrderModifier Extensions
387
        return false;
388
    }
389
390
    /**
391
     * Should the form be shown outside of editable table
392
     * on the checkout page (opposite of ShowFormInEditableOrderTable)?
393
     *
394
     * @return bool
395
     */
396
    public function ShowFormOutsideEditableOrderTable()
397
    {
398
        //extend in OrderModifier Extensions
399
        return $this->ShowFormInEditableOrderTable() ? false : true;
400
    }
401
402
    /**
403
     * This function returns a form that allows a user
404
     * to change the modifier to the order.
405
     *
406
     * We have mainly added this function as an example!
407
     *
408
     * @param Controller $optionalController - optional custom controller class
0 ignored issues
show
Documentation introduced by
Should the type for parameter $optionalController not be null|Controller?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
409
     * @param Validator  $optionalValidator  - optional custom validator class
0 ignored issues
show
Documentation introduced by
Should the type for parameter $optionalValidator not be null|Validator?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
410
     *
411
     * @return OrderModifierForm or subclass
0 ignored issues
show
Documentation introduced by
Should the return type not be OrderModifierForm|null?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
412
     */
413
    public function getModifierForm(Controller $optionalController = null, Validator $optionalValidator = null)
414
    {
415
        if ($this->ShowForm()) {
416
            $fields = new FieldList();
417
            $fields->push($this->headingField());
418
            $fields->push($this->descriptionField());
419
420
            return OrderModifierForm::create($optionalController, 'ModifierForm', $fields, $actions = new FieldList(), $optionalValidator);
421
        }
422
    }
423
424
    /**
425
     * @return object (HeadingField)
426
     */
427
    protected function headingField()
428
    {
429
        $name = $this->ClassName.'Heading';
430
        if ($this->Heading()) {
431
            return new HeaderField($name, $this->Heading(), 4);
432
        }
433
434
        return new LiteralField($name, '<!-- EmptyHeading -->', '<!-- EmptyHeading -->');
0 ignored issues
show
Unused Code introduced by
The call to LiteralField::__construct() has too many arguments starting with '<!-- EmptyHeading -->'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
435
    }
436
437
    /**
438
     * @return object (LiteralField)
439
     */
440
    protected function descriptionField()
441
    {
442
        $name = $this->ClassName.'Description';
443
        if ($this->Description()) {
444
            return new LiteralField($name, '<div id="'.Convert::raw2att($name).'DescriptionHolder" class="descriptionHolder">'.Convert::raw2xml($this->Description()).'</div>');
445
        }
446
447
        return new LiteralField($name, '<!-- EmptyDescription -->', '<!-- EmptyDescription -->');
0 ignored issues
show
Unused Code introduced by
The call to LiteralField::__construct() has too many arguments starting with '<!-- EmptyDescription -->'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
448
    }
449
450
    // ######################################## *** 7. template functions (e.g. ShowInTable, TableTitle, etc...)
451
452
    /**
453
     * Casted variable, returns the table title.
454
     *
455
     * @return string
456
     */
457
    public function TableTitle()
458
    {
459
        return $this->getTableTitle();
460
    }
461
    public function getTableTitle()
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
462
    {
463
        return $this->Name;
0 ignored issues
show
Documentation introduced by
The property Name does not exist on object<OrderModifier>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
464
    }
465
466
    /**
467
     * caching of relevant OrderModifier_Descriptor.
468
     *
469
     * @var OrderModifier_Descriptor
470
     */
471
    private $orderModifier_Descriptor = null;
472
473
    /**
474
     * returns the relevant orderModifier_Descriptor.
475
     *
476
     * @return OrderModifier_Descriptor | Null
477
     */
478
    protected function getOrderModifier_Descriptor()
479
    {
480
        if ($this->orderModifier_Descriptor === null) {
481
            $this->orderModifier_Descriptor = DataObject::get_one(
482
                'OrderModifier_Descriptor',
483
                array('ModifierClassName' => $this->ClassName)
484
            );
485
        }
486
487
        return $this->orderModifier_Descriptor;
488
    }
489
490
    /**
491
     * returns a heading if there is one.
492
     *
493
     * @return string
494
     **/
495
    public function Heading()
496
    {
497
        if ($obj = $this->getOrderModifier_Descriptor()) {
498
            return $obj->Heading;
0 ignored issues
show
Documentation introduced by
The property Heading does not exist on object<OrderModifier_Descriptor>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
499
        }
500
501
        return '';
502
    }
503
504
    /**
505
     * returns a description if there is one.
506
     *
507
     * @return string (html)
508
     **/
509
    public function Description()
510
    {
511
        if ($obj = $this->getOrderModifier_Descriptor()) {
512
            return $obj->Description;
0 ignored issues
show
Documentation introduced by
The property Description does not exist on object<OrderModifier_Descriptor>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
513
        }
514
515
        return '';
516
    }
517
518
    /**
519
     * returns a page for a more info link... (if there is one).
520
     *
521
     * @return object (SiteTree)
522
     **/
523
    public function MoreInfoPage()
524
    {
525
        if ($obj = $this->getOrderModifier_Descriptor()) {
526
            return $obj->Link();
0 ignored issues
show
Documentation Bug introduced by
The method Link does not exist on object<OrderModifier_Descriptor>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
527
        }
528
529
        return;
530
    }
531
532
    /**
533
     * tells you whether the modifier shows up on the checkout  / cart form.
534
     * this is also the place where we check if the modifier has been updated.
535
     *
536
     * @return bool
537
     */
538
    public function ShowInTable()
539
    {
540
        if (!$this->baseRunUpdateCalled) {
0 ignored issues
show
Documentation introduced by
The property baseRunUpdateCalled does not exist on object<OrderModifier>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
541
            if ($this->canBeUpdated()) {
542
                user_error('While the order can be edited, you must call the runUpdate method everytime you get the details for this modifier', E_USER_ERROR);
543
            }
544
        }
545
546
        return false;
547
    }
548
549
    /**
550
     * Returns the Money object of the Table Value.
551
     *
552
     * @return Money
553
     **/
554
    public function TableValueAsMoney()
555
    {
556
        return $this->getTableValueAsMoney();
557
    }
558
    public function getTableValueAsMoney()
559
    {
560
        return EcommerceCurrency::get_money_object_from_order_currency($this->TableValue, $this->Order());
0 ignored issues
show
Documentation introduced by
The property TableValue does not exist on object<OrderModifier>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
561
    }
562
563
    /**
564
     * some modifiers can be hidden after an ajax update (e.g. if someone enters a discount coupon and it does not exist).
565
     * There might be instances where ShowInTable (the starting point) is TRUE and HideInAjaxUpdate return false.
566
     *
567
     *@return bool
568
     **/
569
    public function HideInAjaxUpdate()
570
    {
571
        if ($this->IsRemoved()) {
572
            return true;
573
        }
574
        if ($this->ShowInTable()) {
0 ignored issues
show
Unused Code introduced by
This if statement, and the following return statement can be replaced with return !$this->ShowInTable();.
Loading history...
575
            return false;
576
        }
577
578
        return true;
579
    }
580
581
    /**
582
     * Checks if the modifier can be removed.
583
     *
584
     * @return bool
585
     **/
586
    public function CanBeRemoved()
587
    {
588
        return $this->canBeRemoved;
589
    }
590
591
    /**
592
     * Checks if the modifier can be added manually.
593
     *
594
     * @return bool
595
     **/
596
    public function CanAdd()
597
    {
598
        return $this->HasBeenRemoved || $this->DoNotAddOnInit();
0 ignored issues
show
Documentation introduced by
The property HasBeenRemoved does not exist on object<OrderModifier>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
Documentation Bug introduced by
The method DoNotAddOnInit does not exist on object<OrderModifier>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
599
    }
600
601
    /**
602
     *Identifier whether a modifier will be added automatically for all new orders.
603
     *
604
     * @return bool
605
     */
606
    public function DoNotAddAutomatically()
607
    {
608
        return $this->doNotAddAutomatically;
609
    }
610
611
    /**
612
     * Actual calculation used.
613
     *
614
     * @return float / Double
615
     **/
616
    public function CalculatedTotal()
617
    {
618
        return $this->CalculatedTotal;
0 ignored issues
show
Documentation introduced by
The property CalculatedTotal does not exist on object<OrderModifier>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
619
    }
620
621
    /**
622
     * This link is for modifiers that have been removed and are being put "back".
623
     *
624
     * @return string
625
     **/
626
    public function AddLink()
627
    {
628
        $params = array();
629
        $updatedLinkParameters = $this->extend('ModifierAddLinkUpdate', $params);
630
        if ($updatedLinkParameters !== null && is_array($updatedLinkParameters) && count($updatedLinkParameters)) {
631
            foreach ($updatedLinkParameters as $updatedLinkParametersUpdate) {
632
                $params = array_merge($params, $updatedLinkParametersUpdate);
633
            }
634
        }
635
636
        return ShoppingCart_Controller::add_modifier_link($this->ID, $params, $this->ClassName);
0 ignored issues
show
Unused Code introduced by
The call to ShoppingCart_Controller::add_modifier_link() has too many arguments starting with $this->ClassName.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
637
    }
638
639
    /**
640
     * Link that can be used to remove the modifier.
641
     *
642
     * @return string
643
     **/
644
    public function RemoveLink()
645
    {
646
        $param = array();
647
        $updatedLinkParameters = $this->extend('ModifierRemoveLinkUpdate', $param);
648
        if ($updatedLinkParameters !== null && is_array($updatedLinkParameters) && count($updatedLinkParameters)) {
649
            foreach ($updatedLinkParameters as $updatedLinkParametersUpdate) {
650
                $param = array_merge($param, $updatedLinkParametersUpdate);
651
            }
652
        }
653
654
        return ShoppingCart_Controller::remove_modifier_link($this->ID, $param, $this->ClassName);
0 ignored issues
show
Unused Code introduced by
The call to ShoppingCart_Controller::remove_modifier_link() has too many arguments starting with $this->ClassName.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
655
    }
656
657
    /**
658
     * retursn and array like this: array(Title => "bla", Link => "/doit/now/");.
659
     *
660
     * @return array
661
     */
662
    public function PostSubmitAction()
663
    {
664
        return array();
665
    }
666
667
    // ######################################## ***  8. inner calculations....
668
669
    /**
670
     * returns the running total variable.
671
     *
672
     * @see variable definition for more information
673
     *
674
     * @return float
675
     */
676
    public function getRunningTotal()
677
    {
678
        return $this->runningTotal;
679
    }
680
681
    // ######################################## ***  9. calculate database fields ( = protected function Live[field name]() { ....}
682
683
    protected function LiveName()
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
684
    {
685
        user_error('The "LiveName" method has be defined in ...'.$this->ClassName, E_USER_NOTICE);
686
        $defaults = $this->config()->get('defaults');
687
688
        return $defaults['Name'];
689
    }
690
691
    protected function LiveTableValue()
692
    {
693
        return $this->LiveCalculatedTotal();
694
    }
695
696
    /**
697
     * This function is always called to determine the
698
     * amount this modifier needs to charge or deduct - if any.
699
     *
700
     *
701
     * @return Currency
702
     */
703
    protected function LiveCalculatedTotal()
704
    {
705
        return $this->CalculatedTotal;
0 ignored issues
show
Documentation introduced by
The property CalculatedTotal does not exist on object<OrderModifier>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
706
    }
707
708
    // ######################################## ***  10. Type Functions (IsChargeable, IsDeductable, IsNoChange, IsRemoved)
709
710
    /**
711
     * should be extended if it is true in child class.
712
     *
713
     * @return bool
714
     */
715
    public function IsChargeable()
716
    {
717
        return $this->CalculatedTotal > 0;
0 ignored issues
show
Documentation introduced by
The property CalculatedTotal does not exist on object<OrderModifier>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
718
    }
719
    /**
720
     * should be extended if it is true in child class.
721
     *
722
     * @return bool
723
     */
724
    public function IsDeductable()
725
    {
726
        return $this->CalculatedTotal < 0;
0 ignored issues
show
Documentation introduced by
The property CalculatedTotal does not exist on object<OrderModifier>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
727
    }
728
729
    /**
730
     * should be extended if it is true in child class.
731
     *
732
     * @return bool
733
     */
734
    public function IsNoChange()
735
    {
736
        return $this->CalculatedTotal == 0;
0 ignored issues
show
Documentation introduced by
The property CalculatedTotal does not exist on object<OrderModifier>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
737
    }
738
739
    /**
740
     * should be extended if it is true in child class
741
     * Needs to be a public class.
742
     *
743
     * @return bool
744
     */
745
    public function IsRemoved()
746
    {
747
        return $this->HasBeenRemoved;
0 ignored issues
show
Documentation introduced by
The property HasBeenRemoved does not exist on object<OrderModifier>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
748
    }
749
750
    // ######################################## ***  11. standard database related functions (e.g. onBeforeWrite, onAfterWrite, etc...)
751
752
    /**
753
     * standard SS method.
754
     */
755
    public function onBeforeWrite()
756
    {
757
        parent::onBeforeWrite();
758
    }
759
760
    /**
761
     * removing the Order Modifier does not delete it
762
     * rather, it ignores it (e.g. remove discount coupon)
763
     * We cant delete it, because we need to have a positive record
764
     * of it being removed.
765
     * Extend on Child Classes.
766
     */
767
    public function onBeforeRemove()
768
    {
769
        //you can add more stuff here in sub classes
770
    }
771
772
    /**
773
     * removing the Order Modifier does not delete it
774
     * rather, it ignores it (e.g. remove discount coupon)
775
     * We cant delete it, because we need to have a positive record
776
     * of it being removed.
777
     * Extend on Child Classes.
778
     */
779
    public function onAfterRemove()
780
    {
781
        //you can add more stuff here in sub classes
782
    }
783
784
    // ######################################## ***  11. AJAX related functions
785
786
    /**
787
     * @param array $js javascript array
788
     *
789
     * @return array for AJAX JSON
790
     **/
791
    public function updateForAjax(array $js)
792
    {
793
        $function = EcommerceConfig::get('OrderModifier', 'ajax_total_format');
794
        if (is_array($function)) {
795
            list($function, $format) = $function;
796
        }
797
        $total = $this->$function();
798
        if (isset($format)) {
799
            $total = $total->$format();
800
        }
801
        $ajaxObject = $this->AJAXDefinitions();
802
        //TableValue is a database value
803
        $tableValue = DBField::create_field('Currency', $this->TableValue)->Nice();
0 ignored issues
show
Documentation introduced by
The property TableValue does not exist on object<OrderModifier>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
Unused Code introduced by
$tableValue is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
804
        if ($this->HideInAjaxUpdate()) {
805
            $js[] = array(
806
                't' => 'id',
807
                's' => $ajaxObject->TableID(),
808
                'p' => 'hide',
809
                'v' => 1,
810
            );
811
        } else {
812
            $js[] = array(
813
                't' => 'id',
814
                's' => $ajaxObject->TableID(),
815
                'p' => 'hide',
816
                'v' => 0,
817
            );
818
            $js[] = array(
819
                't' => 'id',
820
                's' => $ajaxObject->TableTitleID(),
821
                'p' => 'innerHTML',
822
                'v' => $this->TableTitle(),
823
            );
824
            $js[] = array(
825
                't' => 'id',
826
                's' => $ajaxObject->CartTitleID(),
827
                'p' => 'innerHTML',
828
                'v' => $this->CartTitle(),
829
            );
830
            $js[] = array(
831
                't' => 'id',
832
                's' => $ajaxObject->TableSubTitleID(),
833
                'p' => 'innerHTML',
834
                'v' => $this->TableSubTitle(),
835
            );
836
            $js[] = array(
837
                't' => 'id',
838
                's' => $ajaxObject->CartSubTitleID(),
839
                'p' => 'innerHTML',
840
                'v' => $this->CartSubTitle(),
841
            );
842
            $js[] = array(
843
                't' => 'id',
844
                's' => $ajaxObject->TableTotalID(),
845
                'p' => 'innerHTML',
846
                'v' => $total,
847
            );
848
        }
849
850
        return $js;
851
    }
852
853
    // ######################################## ***  12. debug functions
854
855
    /**
856
     * Debug helper method.
857
     * Access through : /shoppingcart/debug/.
858
     */
859
    public function debug()
860
    {
861
        $html = EcommerceTaskDebugCart::debug_object($this);
862
863
        return $html;
864
    }
865
}
866