OrderStep::CalculatedDeferTimeInSeconds()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
dl 0
loc 4
rs 10
c 0
b 0
f 0
nc 1
nop 1
1
<?php
2
3
/**
4
 * @description: see OrderStep.md
5
 *
6
 *
7
 * @authors: Nicolaas [at] Sunny Side Up .co.nz
8
 * @package: ecommerce
9
 * @sub-package: model
10
 * @inspiration: Silverstripe Ltd, Jeremy
11
 **/
12
class OrderStep extends DataObject implements EditableEcommerceObject
13
{
14
15
16
    /**
17
     * standard SS variable.
18
     *
19
     * @return array
20
     */
21
    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...
22
        'Name' => 'Varchar(50)',
23
        'Code' => 'Varchar(50)',
24
        'Description' => 'Text',
25
        'EmailSubject' => 'Varchar(200)',
26
        'CustomerMessage' => 'HTMLText',
27
        //customer privileges
28
        'CustomerCanEdit' => 'Boolean',
29
        'CustomerCanCancel' => 'Boolean',
30
        'CustomerCanPay' => 'Boolean',
31
        //What to show the customer...
32
        'ShowAsUncompletedOrder' => 'Boolean',
33
        'ShowAsInProcessOrder' => 'Boolean',
34
        'ShowAsCompletedOrder' => 'Boolean',
35
        'HideStepFromCustomer' => 'Boolean',
36
        //sorting index
37
        'Sort' => 'Int',
38
        'DeferTimeInSeconds' => 'Int',
39
        'DeferFromSubmitTime' => 'Boolean'
40
    );
41
42
43
44
    /**
45
     * standard SS variable.
46
     *
47
     * @return array
48
     */
49
    private static $indexes = 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...
50
        'Code' => true,
51
        'Sort' => true,
52
    );
53
54
    /**
55
     * standard SS variable.
56
     *
57
     * @return array
58
     */
59
    private static $has_many = 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...
60
        'Orders' => 'Order',
61
        'OrderEmailRecords' => 'OrderEmailRecord',
62
        'OrderProcessQueueEntries' => 'OrderProcessQueue'
63
    );
64
65
    /**
66
     * standard SS variable.
67
     *
68
     * @return array
69
     */
70
    private static $field_labels = 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...
71
        'Sort' => 'Sorting Index',
72
        'CustomerCanEdit' => 'Customer can edit order',
73
        'CustomerCanPay' => 'Customer can pay order',
74
        'CustomerCanCancel' => 'Customer can cancel order',
75
    );
76
77
    /**
78
     * standard SS variable.
79
     *
80
     * @return array
81
     */
82
    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...
83
        'NameAndDescription' => 'Step',
84
        'ShowAsSummary' => 'Phase',
85
    );
86
87
    /**
88
     * standard SS variable.
89
     *
90
     * @return array
91
     */
92
    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...
93
        'Title' => 'Varchar',
94
        'CustomerCanEditNice' => 'Varchar',
95
        'CustomerCanPayNice' => 'Varchar',
96
        'CustomerCanCancelNice' => 'Varchar',
97
        'ShowAsUncompletedOrderNice' => 'Varchar',
98
        'ShowAsInProcessOrderNice' => 'Varchar',
99
        'ShowAsCompletedOrderNice' => 'Varchar',
100
        'HideStepFromCustomerNice' => 'Varchar',
101
        'HasCustomerMessageNice' => 'Varchar',
102
        'ShowAsSummary' => 'HTMLText',
103
        'NameAndDescription' => 'HTMLText'
104
    );
105
106
    /**
107
     * standard SS variable.
108
     *
109
     * @return array
110
     */
111
    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...
112
        'Name' => array(
113
            'title' => 'Name',
114
            'filter' => 'PartialMatchFilter',
115
        ),
116
        'Code' => array(
117
            'title' => 'Code',
118
            'filter' => 'PartialMatchFilter',
119
        ),
120
    );
121
122
123
    /**
124
     * casted variable.
125
     *
126
     * @return string
127
     */
128
    public function Title()
129
    {
130
        return $this->getTitle();
131
    }
132
    public function getTitle()
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...
133
    {
134
        return $this->Name;
0 ignored issues
show
Documentation introduced by
The property Name does not exist on object<OrderStep>. 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...
135
    }
136
137
    /**
138
     * casted variable.
139
     *
140
     * @return string
141
     */
142
    public function CustomerCanEditNice()
143
    {
144
        return $this->getCustomerCanEditNice();
145
    }
146
    public function getCustomerCanEditNice()
147
    {
148
        if ($this->CustomerCanEdit) {
0 ignored issues
show
Documentation introduced by
The property CustomerCanEdit does not exist on object<OrderStep>. 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...
149
            return _t('OrderStep.YES', 'Yes');
150
        }
151
152
        return _t('OrderStep.NO', 'No');
153
    }
154
155
    /**
156
     * casted variable.
157
     *
158
     * @return string
159
     */
160
    public function CustomerCanPayNice()
161
    {
162
        return $this->getCustomerCanPayNice();
163
    }
164
    public function getCustomerCanPayNice()
165
    {
166
        if ($this->CustomerCanPay) {
0 ignored issues
show
Documentation introduced by
The property CustomerCanPay does not exist on object<OrderStep>. 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
            return _t('OrderStep.YES', 'Yes');
168
        }
169
170
        return _t('OrderStep.NO', 'No');
171
    }
172
173
    /**
174
     * casted variable.
175
     *
176
     * @return string
177
     */
178
    public function CustomerCanCancelNice()
179
    {
180
        return $this->getCustomerCanCancelNice();
181
    }
182
    public function getCustomerCanCancelNice()
183
    {
184
        if ($this->CustomerCanCancel) {
0 ignored issues
show
Documentation introduced by
The property CustomerCanCancel does not exist on object<OrderStep>. 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...
185
            return _t('OrderStep.YES', 'Yes');
186
        }
187
188
        return _t('OrderStep.NO', 'No');
189
    }
190
191
    public function ShowAsUncompletedOrderNice()
192
    {
193
        return $this->getShowAsUncompletedOrderNice();
194
    }
195
    public function getShowAsUncompletedOrderNice()
196
    {
197
        if ($this->ShowAsUncompletedOrder) {
0 ignored issues
show
Documentation introduced by
The property ShowAsUncompletedOrder does not exist on object<OrderStep>. 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...
198
            return _t('OrderStep.YES', 'Yes');
199
        }
200
201
        return _t('OrderStep.NO', 'No');
202
    }
203
204
    /**
205
     * casted variable.
206
     *
207
     * @return string
208
     */
209
    public function ShowAsInProcessOrderNice()
210
    {
211
        return $this->getShowAsInProcessOrderNice();
212
    }
213
    public function getShowAsInProcessOrderNice()
214
    {
215
        if ($this->ShowAsInProcessOrder) {
0 ignored issues
show
Documentation introduced by
The property ShowAsInProcessOrder does not exist on object<OrderStep>. 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...
216
            return _t('OrderStep.YES', 'Yes');
217
        }
218
219
        return _t('OrderStep.NO', 'No');
220
    }
221
222
    /**
223
     * casted variable.
224
     *
225
     * @return string
226
     */
227
    public function ShowAsCompletedOrderNice()
228
    {
229
        return $this->getShowAsCompletedOrderNice();
230
    }
231
    public function getShowAsCompletedOrderNice()
232
    {
233
        if ($this->ShowAsCompletedOrder) {
0 ignored issues
show
Documentation introduced by
The property ShowAsCompletedOrder does not exist on object<OrderStep>. 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...
234
            return _t('OrderStep.YES', 'Yes');
235
        }
236
237
        return _t('OrderStep.NO', 'No');
238
    }
239
240
    /**
241
     * do not show in steps at all.
242
     * @return boolean
243
     */
244
    public function HideFromEveryone()
245
    {
246
        return false;
247
    }
248
249
    /**
250
     * casted variable.
251
     *
252
     * @return string
253
     */
254
    public function HideStepFromCustomerNice()
255
    {
256
        return $this->getHideStepFromCustomerNice();
257
    }
258
259
    public function getHideStepFromCustomerNice()
260
    {
261
        if ($this->HideStepFromCustomer) {
0 ignored issues
show
Documentation introduced by
The property HideStepFromCustomer does not exist on object<OrderStep>. 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...
262
            return _t('OrderStep.YES', 'Yes');
263
        }
264
265
        return _t('OrderStep.NO', 'No');
266
    }
267
268
    /**
269
     * standard SS variable.
270
     *
271
     * @return string
272
     */
273
    private static $singular_name = 'Order Step';
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...
274
    public function i18n_singular_name()
275
    {
276
        return _t('OrderStep.ORDERSTEP', 'Order Step');
277
    }
278
279
    /**
280
     * standard SS variable.
281
     *
282
     * @return string
283
     */
284
    private static $plural_name = 'Order Steps';
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...
285
    public function i18n_plural_name()
286
    {
287
        return _t('OrderStep.ORDERSTEPS', 'Order Steps');
288
    }
289
290
    /**
291
     * Standard SS variable.
292
     *
293
     * @var string
294
     */
295
    private static $description = 'A step that any order goes through.';
296
297
    /**
298
     * SUPER IMPORTANT TO KEEP ORDER!
299
     * standard SS variable.
300
     *
301
     * @return string
302
     */
303
    private static $default_sort = '"Sort" ASC';
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...
304
305
    /**
306
     * returns all the order steps
307
     * that the admin should / can edit....
308
     *
309
     * @return DataList
310
     */
311
    public static function admin_manageable_steps()
312
    {
313
        $lastStep = OrderStep::last_order_step();
314
315
        return OrderStep::get()->filter(array('ShowAsInProcessOrder' => 1))->exclude(array('ID' => $lastStep->ID));
316
    }
317
    /**
318
     * returns all the order steps
319
     * that the admin should / can edit....
320
     *
321
     * @return DataList
322
     */
323
    public static function non_admin_manageable_steps()
324
    {
325
        $lastStep = OrderStep::last_order_step();
326
327
        return OrderStep::get()->filterAny(array('ShowAsInProcessOrder' => 0, 'ID' => $lastStep->ID));
328
    }
329
330
    private static $_last_order_step_cache = null;
331
332
    /**
333
     * @param bool $noCacheValues
334
     * @return OrderStep
335
     */
336
    public static function last_order_step($noCacheValues = false)
337
    {
338
        if (! self::$_last_order_step_cache || $noCacheValues) {
339
            self::$_last_order_step_cache = OrderStep::get()->Last();
340
        }
341
342
        return self::$_last_order_step_cache;
343
    }
344
345
    /**
346
     * return StatusIDs (orderstep IDs) from orders that are bad....
347
     * (basically StatusID values that do not exist)
348
     *
349
     * @return array
350
     */
351
    public static function bad_order_step_ids()
352
    {
353
        $badorderStatus = Order::get()
354
            ->leftJoin('OrderStep', '"OrderStep"."ID" = "Order"."StatusID"')
355
            ->where('"OrderStep"."ID" IS NULL AND "StatusID" > 0')
356
            ->column('StatusID');
357
        if (is_array($badorderStatus)) {
358
            return array_unique(array_values($badorderStatus));
359
        } else {
360
            return array(-1);
361
        }
362
    }
363
364
    /**
365
     * turns code into ID.
366
     *
367
     * @param string $code
368
     * @param int
369
     */
370
    public static function get_status_id_from_code($code)
371
    {
372
        $otherStatus = DataObject::get_one(
373
            'OrderStep',
374
            array('Code' => $code)
375
        );
376
        if ($otherStatus) {
377
            return $otherStatus->ID;
378
        }
379
380
        return 0;
381
    }
382
383
    /**
384
     *@return array
385
     **/
386
    public static function get_codes_for_order_steps_to_include()
387
    {
388
        $newArray = array();
389
        $array = EcommerceConfig::get('OrderStep', 'order_steps_to_include');
390
        if (is_array($array) && count($array)) {
391
            foreach ($array as $className) {
392
                $code = singleton($className)->getMyCode();
393
                $newArray[$className] = strtoupper($code);
394
            }
395
        }
396
397
        return $newArray;
398
    }
399
400
    /**
401
     * returns a list of ordersteps that have not been created yet.
402
     *
403
     * @return array
0 ignored issues
show
Documentation introduced by
Should the return type not be integer|double|string|boolean|array?

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...
404
     **/
405
    public static function get_not_created_codes_for_order_steps_to_include()
406
    {
407
        $array = EcommerceConfig::get('OrderStep', 'order_steps_to_include');
408
        if (is_array($array) && count($array)) {
409
            foreach ($array as $className) {
410
                $obj = DataObject::get_one($className);
411
                if ($obj) {
412
                    unset($array[$className]);
413
                }
414
            }
415
        }
416
417
        return $array;
418
    }
419
420
    /**
421
     *@return string
422
     **/
423
    public function getMyCode()
424
    {
425
        $array = Config::inst()->get($this->ClassName, 'defaults', Config::UNINHERITED);
426
        if (!isset($array['Code'])) {
427
            user_error($this->class.' does not have a default code specified');
428
        }
429
430
        return $array['Code'];
431
    }
432
433
    /**
434
     * IMPORTANT:: MUST HAVE Code must be defined!!!
435
     * standard SS variable.
436
     *
437
     * @return array
438
     */
439
    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...
440
        'CustomerCanEdit' => 0,
441
        'CustomerCanCancel' => 0,
442
        'CustomerCanPay' => 1,
443
        'ShowAsUncompletedOrder' => 0,
444
        'ShowAsInProcessOrder' => 0,
445
        'ShowAsCompletedOrder' => 0,
446
        'Code' => 'ORDERSTEP',
447
    );
448
449
    /**
450
     * standard SS method.
451
     */
452
    public function populateDefaults()
453
    {
454
        parent::populateDefaults();
455
        $this->Description = $this->myDescription();
0 ignored issues
show
Bug introduced by
The property Description does not seem to exist. Did you mean description?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
456
    }
457
458
    /**
459
     *@return FieldList
460
     **/
461
    public function getCMSFields()
462
    {
463
        $fields = parent::getCMSFields();
464
        //replacing
465
        $queueField = $fields->dataFieldByName('OrderProcessQueueEntries');
466
        $config = $queueField->getConfig();
0 ignored issues
show
Bug introduced by
The method getConfig() does not exist on FormField. Did you maybe mean config()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
467
        $config->removeComponentsByType('GridFieldAddExistingAutocompleter');
468
        $config->removeComponentsByType('GridFieldDeleteAction');
469
        $fields->removeFieldFromTab('Root', 'OrderProcessQueueEntries');
470
        if ($this->canBeDefered()) {
471
            if ($this->DeferTimeInSeconds) {
0 ignored issues
show
Documentation introduced by
The property DeferTimeInSeconds does not exist on object<OrderStep>. 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...
472
                $fields->addFieldToTab(
473
                    'Root.Queue',
474
                    HeaderField::create(
475
                        'WhenWillThisRun',
476
                        $this->humanReadeableDeferTimeInSeconds()
477
                    )
478
                );
479
            }
480
            $fields->addFieldToTab(
481
                'Root.Queue',
482
                $deferTimeInSecondsField = TextField::create(
483
                    'DeferTimeInSeconds',
484
                    _t('OrderStep.DeferTimeInSeconds', 'Seconds in queue')
485
                )
486
                ->setRightTitle(
487
                    _t(
488
                        'OrderStep.TIME_EXPLANATION',
489
                        '86,400 seconds is one day ...
490
                        <br />To make it easier, you can also enter things like <em>1 week</em>, <em>3 hours</em>, or <em>7 minutes</em>.
491
                        <br />Non-second entries will automatically be converted to seconds.'
492
                    )
493
                )
494
            );
495
            if ($this->DeferTimeInSeconds) {
0 ignored issues
show
Documentation introduced by
The property DeferTimeInSeconds does not exist on object<OrderStep>. 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...
496
                $fields->addFieldToTab(
497
                    'Root.Queue',
498
                    $deferTimeInSecondsField = CheckboxField::create(
499
                        'DeferFromSubmitTime',
500
                        _t('OrderStep.DeferFromSubmitTime', 'Calculated from submit time?')
501
                    )
502
                    ->setDescription(
503
                        _t(
504
                            'OrderStep.DeferFromSubmitTime_HELP',
505
                            'The time in the queue can be calculated from the moment the current orderstep starts or from the moment the order was submitted (in this case, check the box above) '
506
                            )
507
                        )
508
                );
509
            }
510
            $fields->addFieldToTab(
511
                'Root.Queue',
512
                $queueField
513
            );
514
        }
515
        if ($this->hasCustomerMessage()) {
516
            $rightTitle = _t(
517
                'OrderStep.EXPLAIN_ORDER_NUMBER_IN_SUBJECT',
518
                'You can use [OrderNumber] as a tag that will be replaced with the actual Order Number.'
519
            );
520
            $fields->addFieldToTab(
521
                'Root.CustomerMessage',
522
                TextField::create('EmailSubject', _t('OrderStep.EMAILSUBJECT', 'Email Subject'))
523
                    ->setRightTitle($rightTitle)
524
            );
525
            if ($testEmailLink = $this->testEmailLink()) {
526
                $fields->addFieldToTab(
527
                    'Root.CustomerMessage',
528
                    new LiteralField(
529
                        'testEmailLink',
530
                        '<h3>
531
                            <a href="'.$testEmailLink.'" data-popup="true" target"_blank" onclick="emailPrompt(this, event);">
532
                                '._t('OrderStep.VIEW_EMAIL_EXAMPLE', 'Test Email').'
533
                            </a>
534
                        </h3>
535
                        <script language="javascript">
536
                            function emailPrompt(caller, event) {
537
                                event.preventDefault();
538
                                var href = jQuery(caller).attr("href");
539
                                var email = prompt("Enter an email address to receive a copy of this example in your inbox, leave blank to view in the browser");
540
                                if (email) {
541
                                    href += "&send=" + email;
542
                                }
543
                                window.open(href);
544
                            };
545
                        </script>'
546
                    )
547
                );
548
            }
549
550
            $fields->addFieldToTab('Root.CustomerMessage', $htmlEditorField = new HTMLEditorField('CustomerMessage', _t('OrderStep.CUSTOMERMESSAGE', 'Customer Message (if any)')));
551
            $htmlEditorField->setRows(3);
552
        } else {
553
            $fields->removeFieldFromTab('Root', 'OrderEmailRecords');
554
            $fields->removeFieldFromTab('Root.Main', 'EmailSubject');
555
            $fields->removeFieldFromTab('Root.Main', 'CustomerMessage');
556
        }
557
        //adding
558
        if (!$this->exists() || !$this->isDefaultStatusOption()) {
559
            $fields->removeFieldFromTab('Root.Main', 'Code');
560
            $fields->addFieldToTab('Root.Main', new DropdownField('ClassName', _t('OrderStep.TYPE', 'Type'), self::get_not_created_codes_for_order_steps_to_include()), 'Name');
561
        }
562
        if ($this->isDefaultStatusOption()) {
563
            $fields->replaceField('Code', $fields->dataFieldByName('Code')->performReadonlyTransformation());
564
        }
565
        //headers
566
        $fields->addFieldToTab('Root.Main', new HeaderField('WARNING1', _t('OrderStep.CAREFUL', 'CAREFUL! please edit details below with care'), 2), 'Description');
567
        $fields->addFieldToTab('Root.Main', new HeaderField('WARNING2', _t('OrderStep.CUSTOMERCANCHANGE', 'What can be changed during this step?'), 3), 'CustomerCanEdit');
568
        $fields->addFieldToTab('Root.Main', new HeaderField('WARNING5', _t('OrderStep.ORDERGROUPS', 'Order groups for customer?'), 3), 'ShowAsUncompletedOrder');
569
        $fields->addFieldToTab('Root.Main', new HeaderField('HideStepFromCustomerHeader', _t('OrderStep.HIDE_STEP_FROM_CUSTOMER_HEADER', 'Customer Interaction'), 3), 'HideStepFromCustomer');
570
        $fields->addFieldToTab('Root.Main', new HeaderField('DeferHeader', _t('OrderStep.DEFER_HEADER', 'Delay'), 3), 'DeferTimeInSeconds');
571
        //final cleanup
572
        $fields->removeFieldFromTab('Root.Main', 'Sort');
573
        $fields->addFieldToTab('Root.Main', new TextareaField('Description', _t('OrderStep.DESCRIPTION', 'Explanation for internal use only')), 'WARNING1');
574
575
        return $fields;
576
    }
577
578
    /**
579
     * link to edit the record.
580
     *
581
     * @param string | Null $action - e.g. edit
582
     *
583
     * @return string
0 ignored issues
show
Documentation introduced by
Should the return type not be null|string?

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...
584
     */
585
    public function CMSEditLink($action = null)
586
    {
587
        return CMSEditLinkAPI::find_edit_link_for_object($this, $action);
588
    }
589
590
    /**
591
     * tells the order to display itself with an alternative display page.
592
     * in that way, orders can be displayed differently for certain steps
593
     * for example, in a print step, the order can be displayed in a
594
     * PRINT ONLY format.
595
     *
596
     * When the method return null, the order is displayed using the standard display page
597
     *
598
     * @see Order::DisplayPage
599
     *
600
     * @return null|object (Page)
601
     **/
602
    public function AlternativeDisplayPage()
603
    {
604
        return;
605
    }
606
607
    /**
608
     * Allows the opportunity for the Order Step to add any fields to Order::getCMSFields
609
     * Usually this is added before ActionNextStepManually.
610
     *
611
     * @param FieldList $fields
612
     * @param Order     $order
613
     *
614
     * @return FieldList
615
     **/
616
    public function addOrderStepFields(FieldList $fields, Order $order)
617
    {
618
        return $fields;
619
    }
620
621
    /**
622
     *@return ValidationResult
623
     **/
624
    public function validate()
625
    {
626
        $result = parent::validate();
627
        $anotherOrderStepWithSameNameOrCode = OrderStep::get()
628
            ->filter(
629
                array(
630
                    'Name' => $this->Name,
0 ignored issues
show
Documentation introduced by
The property Name does not exist on object<OrderStep>. 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...
631
                    'Code' => strtoupper($this->Code),
0 ignored issues
show
Documentation introduced by
The property Code does not exist on object<OrderStep>. 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...
632
                )
633
            )
634
            ->exclude(array('ID' => intval($this->ID)))
635
            ->First();
636
        if ($anotherOrderStepWithSameNameOrCode) {
637
            $result->error(_t('OrderStep.ORDERSTEPALREADYEXISTS', 'An order status with this name already exists. Please change the name and try again.'));
638
        }
639
640
        return $result;
641
    }
642
643
    /**************************************************
644
    * moving between statusses...
645
    **************************************************/
646
    /**
647
     *initStep:
648
     * makes sure the step is ready to run.... (e.g. check if the order is ready to be emailed as receipt).
649
     * should be able to run this function many times to check if the step is ready.
650
     *
651
     * @see Order::doNextStatus
652
     *
653
     * @param Order object
654
     *
655
     * @return bool - true if the current step is ready to be run...
656
     **/
657
    public function initStep(Order $order)
658
    {
659
        user_error('Please implement the initStep method in a subclass ('.get_class().') of OrderStep', E_USER_WARNING);
660
661
        return true;
662
    }
663
664
    /**
665
     *doStep:
666
     * should only be able to run this function once
667
     * (init stops you from running it twice - in theory....)
668
     * runs the actual step.
669
     *
670
     * @see Order::doNextStatus
671
     *
672
     * @param Order object
673
     *
674
     * @return bool - true if run correctly.
675
     **/
676
    public function doStep(Order $order)
677
    {
678
        user_error('Please implement the initStep method in a subclass ('.get_class().') of OrderStep', E_USER_WARNING);
679
680
        return true;
681
    }
682
683
    /**
684
     * nextStep:
685
     * returns the next step (after it checks if everything is in place for the next step to run...).
686
     *
687
     * @see Order::doNextStatus
688
     *
689
     * @param Order $order
690
     *
691
     * @return OrderStep | Null (next step OrderStep object)
0 ignored issues
show
Documentation introduced by
Should the return type not be OrderStep|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...
692
     **/
693
    public function nextStep(Order $order)
694
    {
695
        $sort = (int) $this->Sort;
0 ignored issues
show
Documentation introduced by
The property Sort does not exist on object<OrderStep>. 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...
696
        if (! $sort) {
697
            $sort = 0;
698
        }
699
        $where = '"OrderStep"."Sort" >  '.$sort;
700
        $nextOrderStepObject = DataObject::get_one(
701
            'OrderStep',
702
            $where
703
        );
704
        if ($nextOrderStepObject) {
705
            return $nextOrderStepObject;
706
        }
707
708
        return;
709
    }
710
711
    /**************************************************
712
    * Boolean checks
713
    **************************************************/
714
715
    /**
716
     * Checks if a step has passed (been completed) in comparison to the current step.
717
     *
718
     * @param string $code:       the name of the step to check
0 ignored issues
show
Bug introduced by
There is no parameter named $code:. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
719
     * @param bool   $orIsEqualTo if set to true, this method will return TRUE if the step being checked is the current one
720
     *
721
     * @return bool
722
     **/
723
    public function hasPassed($code, $orIsEqualTo = false)
724
    {
725
        $otherStatus = DataObject::get_one(
726
            'OrderStep',
727
            array('Code' => $code)
728
        );
729
        if ($otherStatus) {
730
            if ($otherStatus->Sort < $this->Sort) {
0 ignored issues
show
Documentation introduced by
The property Sort does not exist on object<OrderStep>. 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...
731
                return true;
732
            }
733
            if ($orIsEqualTo && $otherStatus->Code == $this->Code) {
0 ignored issues
show
Documentation introduced by
The property Code does not exist on object<OrderStep>. 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...
734
                return true;
735
            }
736
        } else {
737
            user_error("could not find $code in OrderStep", E_USER_NOTICE);
738
        }
739
740
        return false;
741
    }
742
743
    /**
744
     * @param string $code
745
     *
746
     * @return bool
747
     **/
748
    public function hasPassedOrIsEqualTo($code)
749
    {
750
        return $this->hasPassed($code, true);
751
    }
752
753
    /**
754
     * @param string $code
755
     *
756
     * @return bool
757
     **/
758
    public function hasNotPassed($code)
759
    {
760
        return (bool) !$this->hasPassed($code, true);
761
    }
762
763
    /**
764
     * Opposite of hasPassed.
765
     *
766
     * @param string $code
767
     *
768
     * @return bool
769
     **/
770
    public function isBefore($code)
771
    {
772
        return (bool) $this->hasPassed($code, false) ? false : true;
773
    }
774
775
    /**
776
     *@return bool
777
     **/
778
    protected function isDefaultStatusOption()
779
    {
780
        return in_array($this->Code, self::get_codes_for_order_steps_to_include());
0 ignored issues
show
Documentation introduced by
The property Code does not exist on object<OrderStep>. 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...
781
    }
782
783
    /**************************************************
784
    * Email
785
    **************************************************/
786
787
    /**
788
     * @var string
789
     */
790
    protected $emailClassName = 'Order_InvoiceEmail';
791
792
    /**
793
     * returns the email class used for emailing the
794
     * customer during a specific step (IF ANY!).
795
     *
796
     * @return string
797
     */
798
    public function getEmailClassName()
799
    {
800
        return $this->emailClassName;
801
    }
802
803
    /**
804
     * return true if done already or mailed successfully now.
805
     *
806
     * @param order         $order
807
     * @param string        $subject
808
     * @param string        $message
809
     * @param bool          $resend
810
     * @param bool | string $adminOnlyOrToEmail you can set to false = send to customer, true: send to admin, or email = send to email
811
     * @param string        $emailClassName
812
     *
813
     * @return boolean;
0 ignored issues
show
Documentation introduced by
The doc-type boolean; could not be parsed: Expected "|" or "end of type", but got ";" at position 7. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
814
     */
815
    protected function sendEmailForStep(
816
        $order,
817
        $subject,
818
        $message = '',
819
        $resend = false,
820
        $adminOnlyOrToEmail = false,
821
        $emailClassName = ''
822
    ) {
823
        if (!$this->hasBeenSent($order) || $resend) {
824
            if (!$subject) {
825
                $subject = $this->CalculatedEmailSubject($order);
826
            }
827
            $useAlternativeEmail = $adminOnlyOrToEmail && filter_var($adminOnlyOrToEmail, FILTER_VALIDATE_EMAIL);
828
829
            //this is NOT an admin EMAIL
830
            if ($this->hasCustomerMessage() || $useAlternativeEmail) {
831
                if (! $emailClassName) {
832
                    $emailClassName = $this->getEmailClassName();
833
                }
834
                return $order->sendEmail(
835
                    $emailClassName,
836
                    $subject,
837
                    $message,
838
                    $resend,
839
                    $adminOnlyOrToEmail
840
                );
841
            //ADMIN ONLY ....
842
            } else {
843
                if (! $emailClassName) {
844
                    $emailClassName = 'Order_ErrorEmail';
845
                }
846
                //looks like we are sending an error, but we are just using this for notification
847
                $message = _t('OrderStep.THISMESSAGENOTSENTTOCUSTOMER', 'NOTE: This message was not sent to the customer.').'<br /><br /><br /><br />'.$message;
848
                $outcome = $order->sendAdminNotification(
849
                    $emailClassName,
850
                    $subject,
851
                    $message,
852
                    $resend
853
                );
854
            }
855
            if ($outcome || Director::isDev()) {
0 ignored issues
show
Unused Code introduced by
This if statement, and the following return statement can be replaced with return $outcome || \Director::isDev();.
Loading history...
856
                return true;
857
            }
858
859
            return false;
860
        }
861
862
        return true;
863
    }
864
865
    /**
866
     * sets the email class used for emailing the
867
     * customer during a specific step (IF ANY!).
868
     *
869
     * @param string
870
     */
871
    public function setEmailClassName($s)
872
    {
873
        $this->emailClassName = $s;
874
    }
875
876
    /**
877
     * returns a link that can be used to test
878
     * the email being sent during this step
879
     * this method returns NULL if no email
880
     * is being sent OR if there is no suitable Order
881
     * to test with...
882
     *
883
     * @return string
0 ignored issues
show
Documentation introduced by
Should the return type not be string|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...
884
     */
885
    protected function testEmailLink()
886
    {
887
        if ($this->getEmailClassName()) {
888
            $order = DataObject::get_one(
889
                'Order',
890
                array('StatusID' => $this->ID),
891
                $cacheDataObjectGetOne = true,
892
                'RAND() ASC'
893
            );
894
            if (! $order) {
895
                $order = Order::get()
896
                    ->where('"OrderStep"."Sort" >= '.$this->Sort)
0 ignored issues
show
Documentation introduced by
The property Sort does not exist on object<OrderStep>. 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...
897
                    ->sort('IF("OrderStep"."Sort" > '.$this->Sort.', 0, 1) ASC, "OrderStep"."Sort" ASC, RAND() ASC')
0 ignored issues
show
Documentation introduced by
The property Sort does not exist on object<OrderStep>. 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...
898
                    ->innerJoin('OrderStep', '"OrderStep"."ID" = "Order"."StatusID"')
899
                    ->first();
900
            }
901
            if ($order) {
902
                return OrderConfirmationPage::get_email_link(
903
                    $order->ID,
904
                    $this->getEmailClassName(),
905
                    $actuallySendEmail = false,
906
                    $alternativeOrderStepID = $this->ID
907
                );
908
            }
909
        }
910
    }
911
912
    /**
913
     * Has an email been sent to the customer for this
914
     * order step.
915
     *"-10 days".
916
     *
917
     * @param Order $order
918
     * @param bool  $checkDateOfOrder
919
     *
920
     * @return bool
921
     **/
922
    public function hasBeenSent(Order $order, $checkDateOfOrder = true)
923
    {
924
        //if it has been more than a XXX days since the order was last edited (submitted) then we do not send emails as
925
        //this would be embarrasing.
926
        if ($checkDateOfOrder) {
927
            if ($log = $order->SubmissionLog()) {
928
                $lastEditedValue = $log->LastEdited;
929
            } else {
930
                $lastEditedValue = $order->LastEdited;
931
            }
932
            if ((strtotime($lastEditedValue) < strtotime('-'.EcommerceConfig::get('OrderStep', 'number_of_days_to_send_update_email').' days'))) {
933
                return true;
934
            }
935
        }
936
        $count = OrderEmailRecord::get()
937
            ->Filter(array(
938
                'OrderID' => $order->ID,
939
                'OrderStepID' => $this->ID,
940
                'Result' => 1,
941
            ))
942
            ->count();
943
944
        return $count ? true : false;
945
    }
946
947
    /**
948
     * For some ordersteps this returns true...
949
     *
950
     * @return bool
951
     **/
952
    protected function hasCustomerMessage()
953
    {
954
        return false;
955
    }
956
957
958
    /**
959
     * Formatted answer for "hasCustomerMessage".
960
     *
961
     * @return string
962
     */
963
    public function HasCustomerMessageNice()
964
    {
965
        return $this->getHasCustomerMessageNice();
966
    }
967
    public function getHasCustomerMessageNice()
968
    {
969
        return $this->hasCustomerMessage() ?  _t('OrderStep.YES', 'Yes') :  _t('OrderStep.NO', 'No');
970
    }
971
972
    public function CalculatedEmailSubject($order = null)
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...
973
    {
974
        return $this->EmailSubject;
0 ignored issues
show
Documentation introduced by
The property EmailSubject does not exist on object<OrderStep>. 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...
975
    }
976
977
    public function CalculatedCustomerMessage($order = null)
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...
978
    {
979
        return $this->CustomerMessage;
0 ignored issues
show
Documentation introduced by
The property CustomerMessage does not exist on object<OrderStep>. 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...
980
    }
981
982
    /**
983
     * Formatted answer for "hasCustomerMessage".
984
     *
985
     * @return string
0 ignored issues
show
Documentation introduced by
Should the return type not be DBField?

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...
986
     */
987
    public function ShowAsSummary()
988
    {
989
        return $this->getShowAsSummary();
990
    }
991
992
    /**
993
     *
994
     *
995
     * @return string
0 ignored issues
show
Documentation introduced by
Should the return type not be DBField?

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...
996
     */
997
    public function getShowAsSummary()
998
    {
999
        $v = '<strong>';
1000
        if ($this->ShowAsUncompletedOrder) {
0 ignored issues
show
Documentation introduced by
The property ShowAsUncompletedOrder does not exist on object<OrderStep>. 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...
1001
            $v .= _t('OrderStep.UNCOMPLETED', 'Uncompleted');
1002
        } elseif ($this->ShowAsInProcessOrder) {
0 ignored issues
show
Documentation introduced by
The property ShowAsInProcessOrder does not exist on object<OrderStep>. 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...
1003
            $v .= _t('OrderStep.INPROCESS', 'In process');
1004
        } elseif ($this->ShowAsCompletedOrder) {
0 ignored issues
show
Documentation introduced by
The property ShowAsCompletedOrder does not exist on object<OrderStep>. 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...
1005
            $v .= _t('OrderStep.COMPLETED', 'Completed');
1006
        }
1007
        $v .= '</strong>';
1008
        $canArray = array();
1009
        if ($this->CustomerCanEdit) {
0 ignored issues
show
Documentation introduced by
The property CustomerCanEdit does not exist on object<OrderStep>. 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...
1010
            $canArray[] = _t('OrderStep.EDITABLE', 'edit');
1011
        }
1012
        if ($this->CustomerCanPay) {
0 ignored issues
show
Documentation introduced by
The property CustomerCanPay does not exist on object<OrderStep>. 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...
1013
            $canArray[] = _t('OrderStep.PAY', 'pay');
1014
        }
1015
        if ($this->CustomerCanCancel) {
0 ignored issues
show
Documentation introduced by
The property CustomerCanCancel does not exist on object<OrderStep>. 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...
1016
            $canArray[] = _t('OrderStep.CANCEL', 'cancel');
1017
        }
1018
        if (count($canArray)) {
1019
            $v .=  '<br />'._t('OrderStep.CUSTOMER_CAN', 'Customer Can').': '.implode(', ', $canArray).'';
1020
        }
1021
        if ($this->hasCustomerMessage()) {
1022
            $v .= '<br />'._t('OrderStep.CUSTOMER_MESSAGES', 'Includes message to customer');
1023
        }
1024
        if ($this->DeferTimeInSeconds) {
0 ignored issues
show
Documentation introduced by
The property DeferTimeInSeconds does not exist on object<OrderStep>. 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...
1025
            $v .= '<br />'.$this->humanReadeableDeferTimeInSeconds();
1026
        }
1027
1028
        return DBField::create_field('HTMLText', $v);
1029
    }
1030
1031
    /**
1032
     * @return string
0 ignored issues
show
Documentation introduced by
Should the return type not be string|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...
1033
     */
1034
    protected function humanReadeableDeferTimeInSeconds()
1035
    {
1036
        if ($this->canBeDefered()) {
1037
            $field = DBField::create_field('SS_DateTime', strtotime('+ '.$this->DeferTimeInSeconds.' seconds'));
0 ignored issues
show
Documentation introduced by
The property DeferTimeInSeconds does not exist on object<OrderStep>. 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...
1038
            $descr0 = _t('OrderStep.THE', 'The').' '.'<span style="color: #338DC1">'.$this->getTitle().'</span>';
1039
            $descr1 = _t('OrderStep.DELAY_VALUE', 'Order Step, for any order, will run');
1040
            $descr2 = $field->ago();
1041
            $descr3 = $this->DeferFromSubmitTime ?
0 ignored issues
show
Documentation introduced by
The property DeferFromSubmitTime does not exist on object<OrderStep>. 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...
1042
                    _t('OrderStep.FROM_ORDER_SUBMIT_TIME', 'from the order being submitted') :
1043
                    _t('OrderStep.FROM_START_OF_ORDSTEP', 'from the order arriving on this step');
1044
            return $descr0. ' ' . $descr1.' <span style="color: #338DC1">'.$descr2.'</span> '.$descr3.'.';
1045
        }
1046
        // $dtF = new \DateTime('@0');
1047
        // $dtT = new \DateTime("@".$this->DeferTimeInSeconds);
1048
        //
1049
        // return $dtF->diff($dtT)->format('%a days, %h hours, %i minutes and %s seconds');
1050
    }
1051
1052
    /**
1053
     * Formatted answer for "hasCustomerMessage".
1054
     *
1055
     * @return string
0 ignored issues
show
Documentation introduced by
Should the return type not be DBField?

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...
1056
     */
1057
    public function NameAndDescription()
1058
    {
1059
        return $this->getNameAndDescription();
1060
    }
1061
1062
    public function getNameAndDescription()
1063
    {
1064
        $v = '<strong>'.$this->Name.'</strong><br /><em>'.$this->Description.'</em>';
0 ignored issues
show
Documentation introduced by
The property Name does not exist on object<OrderStep>. 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...
Bug introduced by
The property Description does not seem to exist. Did you mean description?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
1065
1066
        return DBField::create_field('HTMLText', $v);
1067
    }
1068
1069
    /**
1070
     * This allows you to set the time to something other than the standard DeferTimeInSeconds
1071
     * value based on the order provided.
1072
     *
1073
     * @param Order (optional)
0 ignored issues
show
Documentation introduced by
Should the type for parameter $order not be optional|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...
1074
     *
1075
     * @return int
1076
     */
1077
    public function CalculatedDeferTimeInSeconds($order = null)
0 ignored issues
show
Unused Code introduced by
The parameter $order 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...
1078
    {
1079
        return $this->DeferTimeInSeconds;
0 ignored issues
show
Documentation introduced by
The property DeferTimeInSeconds does not exist on object<OrderStep>. 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...
1080
    }
1081
1082
    /**
1083
     * can this order step be delayed?
1084
     * in general, if there is a customer message
1085
     * we should be able to delay it
1086
     *
1087
     * This method can be overridden in any orderstep
1088
     * @return bool
1089
     **/
1090
    protected function canBeDefered()
1091
    {
1092
        return $this->hasCustomerMessage();
1093
    }
1094
1095
1096
    /**************************************************
1097
    * Order Status Logs
1098
    **************************************************/
1099
1100
    /**
1101
     * The OrderStatusLog that is relevant to the particular step.
1102
     *
1103
     * @var string
1104
     */
1105
    protected $relevantLogEntryClassName = '';
1106
1107
    /**
1108
     * @return string
1109
     */
1110
    public function getRelevantLogEntryClassName()
1111
    {
1112
        return $this->relevantLogEntryClassName;
1113
    }
1114
1115
    /**
1116
     * @param string
1117
     */
1118
    public function setRelevantLogEntryClassName($s)
1119
    {
1120
        $this->relevantLogEntryClassName = $s;
1121
    }
1122
1123
    /**
1124
     * returns the OrderStatusLog that is relevant to this step.
1125
     *
1126
     * @param Order $order
1127
     *
1128
     * @return OrderStatusLog | null
1129
     */
1130
    public function RelevantLogEntry(Order $order)
1131
    {
1132
        if ($className = $this->getRelevantLogEntryClassName()) {
0 ignored issues
show
Unused Code introduced by
$className 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...
1133
            return $this->RelevantLogEntries($order)->Last();
1134
        }
1135
    }
1136
1137
    /**
1138
     * returns the OrderStatusLogs that are relevant to this step.
1139
     * It is important that getRelevantLogEntryClassName returns
1140
     * a specific enough ClassName and not a base class name.
1141
     *
1142
     * @param Order $order
1143
     *
1144
     * @return DataObjectSet | null
1145
     */
1146
    public function RelevantLogEntries(Order $order)
1147
    {
1148
        if ($className = $this->getRelevantLogEntryClassName()) {
1149
            return $className::get()->filter(
1150
                array(
1151
                    'OrderID' => $order->ID
1152
                )
1153
            );
1154
        }
1155
    }
1156
1157
    /**************************************************
1158
    * Silverstripe Standard Data Object Methods
1159
    **************************************************/
1160
1161
    /**
1162
     * Standard SS method
1163
     * These are only created programmatically.
1164
     *
1165
     * @param Member $member
0 ignored issues
show
Documentation introduced by
Should the type for parameter $member not be Member|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...
1166
     *
1167
     * @return bool
1168
     */
1169
    public function canCreate($member = null)
1170
    {
1171
        return false;
1172
    }
1173
1174
    /**
1175
     * Standard SS method.
1176
     *
1177
     * @param Member $member
0 ignored issues
show
Documentation introduced by
Should the type for parameter $member not be Member|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...
1178
     *
1179
     * @return bool
0 ignored issues
show
Documentation introduced by
Should the return type not be boolean|string|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...
1180
     */
1181
    public function canView($member = null)
1182
    {
1183
        if (! $member) {
1184
            $member = Member::currentUser();
1185
        }
1186
        $extended = $this->extendedCan(__FUNCTION__, $member);
0 ignored issues
show
Documentation introduced by
$member is of type object<DataObject>|null, but the function expects a object<Member>|integer.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
1187
        if ($extended !== null) {
1188
            return $extended;
1189
        }
1190
        if (Permission::checkMember($member, Config::inst()->get('EcommerceRole', 'admin_permission_code'))) {
1191
            return true;
1192
        }
1193
1194
        return parent::canEdit($member);
0 ignored issues
show
Bug introduced by
It seems like $member defined by \Member::currentUser() on line 1184 can also be of type object<DataObject>; however, DataObject::canEdit() does only seem to accept object<Member>|null, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
Comprehensibility Bug introduced by
It seems like you call parent on a different method (canEdit() instead of canView()). Are you sure this is correct? If so, you might want to change this to $this->canEdit().

This check looks for a call to a parent method whose name is different than the method from which it is called.

Consider the following code:

class Daddy
{
    protected function getFirstName()
    {
        return "Eidur";
    }

    protected function getSurName()
    {
        return "Gudjohnsen";
    }
}

class Son
{
    public function getFirstName()
    {
        return parent::getSurname();
    }
}

The getFirstName() method in the Son calls the wrong method in the parent class.

Loading history...
1195
    }
1196
1197
    /**
1198
     * the default for this is TRUE, but for completed order steps
1199
     *
1200
     * we do not allow this.
1201
     *
1202
     * @param  Order $order
1203
     * @param  Member $member optional
0 ignored issues
show
Documentation introduced by
Should the type for parameter $member not be Member|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...
1204
     * @return bool
1205
     */
1206
    public function canOverrideCanViewForOrder($order, $member = null)
0 ignored issues
show
Unused Code introduced by
The parameter $order 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...
Unused Code introduced by
The parameter $member 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...
1207
    {
1208
        //return true if the order can have customer input
1209
        // orders recently saved can also be views
1210
        return
1211
            $this->CustomerCanEdit ||
0 ignored issues
show
Documentation introduced by
The property CustomerCanEdit does not exist on object<OrderStep>. 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...
1212
            $this->CustomerCanCancel ||
0 ignored issues
show
Documentation introduced by
The property CustomerCanCancel does not exist on object<OrderStep>. 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...
1213
            $this->CustomerCanPay;
0 ignored issues
show
Documentation introduced by
The property CustomerCanPay does not exist on object<OrderStep>. 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...
1214
    }
1215
1216
    /**
1217
     * standard SS method.
1218
     *
1219
     * @param Member | NULL
1220
     *
1221
     * @return bool
0 ignored issues
show
Documentation introduced by
Should the return type not be boolean|string|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...
1222
     */
1223
    public function canEdit($member = null)
1224
    {
1225
        if (! $member) {
1226
            $member = Member::currentUser();
1227
        }
1228
        $extended = $this->extendedCan(__FUNCTION__, $member);
1229
        if ($extended !== null) {
1230
            return $extended;
1231
        }
1232
        if (Permission::checkMember($member, Config::inst()->get('EcommerceRole', 'admin_permission_code'))) {
1233
            return true;
1234
        }
1235
1236
        return parent::canEdit($member);
1237
    }
1238
1239
    /**
1240
     * Standard SS method.
1241
     *
1242
     * @param Member $member
0 ignored issues
show
Documentation introduced by
Should the type for parameter $member not be Member|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...
1243
     *
1244
     * @return bool
0 ignored issues
show
Documentation introduced by
Should the return type not be boolean|string|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...
1245
     */
1246
    public function canDelete($member = null)
1247
    {
1248
        //cant delete last status if there are orders with this status
1249
        $nextOrderStepObject = $this->NextOrderStep();
1250
        if ($nextOrderStepObject) {
1251
            //do nothing
1252
        } else {
1253
            $orderCount = Order::get()
1254
                ->filter(array('StatusID' => intval($this->ID) - 0))
1255
                ->count();
1256
            if ($orderCount) {
1257
                return false;
1258
            }
1259
        }
1260
        if ($this->isDefaultStatusOption()) {
1261
            return false;
1262
        }
1263
        if (! $member) {
1264
            $member = Member::currentUser();
1265
        }
1266
        $extended = $this->extendedCan(__FUNCTION__, $member);
0 ignored issues
show
Documentation introduced by
$member is of type object<DataObject>|null, but the function expects a object<Member>|integer.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
1267
        if ($extended !== null) {
1268
            return $extended;
1269
        }
1270
        if (Permission::checkMember($member, Config::inst()->get('EcommerceRole', 'admin_permission_code'))) {
1271
            return true;
1272
        }
1273
1274
        return parent::canEdit($member);
0 ignored issues
show
Bug introduced by
It seems like $member defined by \Member::currentUser() on line 1264 can also be of type object<DataObject>; however, DataObject::canEdit() does only seem to accept object<Member>|null, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
Comprehensibility Bug introduced by
It seems like you call parent on a different method (canEdit() instead of canDelete()). Are you sure this is correct? If so, you might want to change this to $this->canEdit().

This check looks for a call to a parent method whose name is different than the method from which it is called.

Consider the following code:

class Daddy
{
    protected function getFirstName()
    {
        return "Eidur";
    }

    protected function getSurName()
    {
        return "Gudjohnsen";
    }
}

class Son
{
    public function getFirstName()
    {
        return parent::getSurname();
    }
}

The getFirstName() method in the Son calls the wrong method in the parent class.

Loading history...
1275
    }
1276
1277
    /**
1278
     * standard SS method.
1279
     */
1280
    public function onBeforeWrite()
1281
    {
1282
        parent::onBeforeWrite();
1283
        //make sure only one of three conditions applies ...
1284
        if ($this->ShowAsUncompletedOrder) {
0 ignored issues
show
Documentation introduced by
The property ShowAsUncompletedOrder does not exist on object<OrderStep>. 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...
1285
            $this->ShowAsInProcessOrder = false;
0 ignored issues
show
Documentation introduced by
The property ShowAsInProcessOrder does not exist on object<OrderStep>. 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...
1286
            $this->ShowAsCompletedOrder = false;
0 ignored issues
show
Documentation introduced by
The property ShowAsCompletedOrder does not exist on object<OrderStep>. 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...
1287
        } elseif ($this->ShowAsInProcessOrder) {
0 ignored issues
show
Documentation introduced by
The property ShowAsInProcessOrder does not exist on object<OrderStep>. 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...
1288
            $this->ShowAsUncompletedOrder = false;
0 ignored issues
show
Documentation introduced by
The property ShowAsUncompletedOrder does not exist on object<OrderStep>. 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...
1289
            $this->ShowAsCompletedOrder = false;
0 ignored issues
show
Documentation introduced by
The property ShowAsCompletedOrder does not exist on object<OrderStep>. 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...
1290
        } elseif ($this->ShowAsCompletedOrder) {
0 ignored issues
show
Documentation introduced by
The property ShowAsCompletedOrder does not exist on object<OrderStep>. 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...
1291
            $this->ShowAsUncompletedOrder = false;
0 ignored issues
show
Documentation introduced by
The property ShowAsUncompletedOrder does not exist on object<OrderStep>. 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...
1292
            $this->ShowAsInProcessOrder = false;
0 ignored issues
show
Documentation introduced by
The property ShowAsInProcessOrder does not exist on object<OrderStep>. 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...
1293
        }
1294
        if (! $this->canBeDefered()) {
1295
            $this->DeferTimeInSeconds = 0;
0 ignored issues
show
Documentation introduced by
The property DeferTimeInSeconds does not exist on object<OrderStep>. 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...
1296
            $this->DeferFromSubmitTime = 0;
0 ignored issues
show
Documentation introduced by
The property DeferFromSubmitTime does not exist on object<OrderStep>. 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...
1297
        } else {
1298
            if (is_numeric($this->DeferTimeInSeconds)) {
0 ignored issues
show
Documentation introduced by
The property DeferTimeInSeconds does not exist on object<OrderStep>. 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...
1299
                $this->DeferTimeInSeconds = intval($this->DeferTimeInSeconds);
0 ignored issues
show
Documentation introduced by
The property DeferTimeInSeconds does not exist on object<OrderStep>. 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...
Documentation introduced by
The property DeferTimeInSeconds does not exist on object<OrderStep>. 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...
1300
            } else {
1301
                $this->DeferTimeInSeconds = strtotime('+'.$this->DeferTimeInSeconds);
0 ignored issues
show
Documentation introduced by
The property DeferTimeInSeconds does not exist on object<OrderStep>. 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...
Documentation introduced by
The property DeferTimeInSeconds does not exist on object<OrderStep>. 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...
1302
                if ($this->DeferTimeInSeconds > 0) {
0 ignored issues
show
Documentation introduced by
The property DeferTimeInSeconds does not exist on object<OrderStep>. 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...
1303
                    $this->DeferTimeInSeconds = $this->DeferTimeInSeconds - time();
0 ignored issues
show
Documentation introduced by
The property DeferTimeInSeconds does not exist on object<OrderStep>. 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...
Documentation introduced by
The property DeferTimeInSeconds does not exist on object<OrderStep>. 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...
1304
                }
1305
            }
1306
        }
1307
        $this->Code = strtoupper($this->Code);
0 ignored issues
show
Documentation introduced by
The property Code does not exist on object<OrderStep>. 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...
Documentation introduced by
The property Code does not exist on object<OrderStep>. 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...
1308
    }
1309
1310
    /**
1311
     * move linked orders to the next status
1312
     * standard SS method.
1313
     */
1314
    public function onBeforeDelete()
1315
    {
1316
        $ordersWithThisStatus = Order::get()->filter(array('StatusID' => $this->ID));
1317
        if ($ordersWithThisStatus->count()) {
1318
            $previousOrderStepObject = null;
0 ignored issues
show
Unused Code introduced by
$previousOrderStepObject 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...
1319
            $bestOrderStep = $this->NextOrderStep();
1320
            //backup
1321
            if ($bestOrderStep && $bestOrderStep->exists()) {
1322
                //do nothing
1323
            } else {
1324
                $bestOrderStep = $this->PreviousOrderStep();
1325
            }
1326
            if ($bestOrderStep) {
1327
                foreach ($ordersWithThisStatus as $orderWithThisStatus) {
1328
                    $orderWithThisStatus->StatusID = $bestOrderStep->ID;
1329
                    $orderWithThisStatus->write();
1330
                }
1331
            }
1332
        }
1333
        parent::onBeforeDelete();
1334
    }
1335
1336
    /**
1337
     * standard SS method.
1338
     */
1339
    public function onAfterDelete()
1340
    {
1341
        parent::onAfterDelete();
1342
        $this->checkValidityOfOrderSteps();
1343
    }
1344
1345
    protected function NextOrderStep()
1346
    {
1347
        return OrderStep::get()
1348
            ->filter(array('Sort:GreaterThan' => $this->Sort))
0 ignored issues
show
Documentation introduced by
The property Sort does not exist on object<OrderStep>. 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...
1349
            ->First();
1350
    }
1351
1352
    protected function PreviousOrderStep()
1353
    {
1354
        return OrderStep::get()
1355
            ->filter(array('Sort:LessThan' => $this->Sort))
0 ignored issues
show
Documentation introduced by
The property Sort does not exist on object<OrderStep>. 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...
1356
            ->First();
1357
    }
1358
1359
    /**
1360
     * standard SS method
1361
     * USED TO BE: Unpaid,Query,Paid,Processing,Sent,Complete,AdminCancelled,MemberCancelled,Cart.
1362
     */
1363
    public function requireDefaultRecords()
1364
    {
1365
        parent::requireDefaultRecords();
1366
        $this->checkValidityOfOrderSteps();
1367
    }
1368
1369
    protected function checkValidityOfOrderSteps()
1370
    {
1371
        $orderStepsToInclude = EcommerceConfig::get('OrderStep', 'order_steps_to_include');
1372
        $codesToInclude = self::get_codes_for_order_steps_to_include();
1373
        $indexNumber = 0;
1374
        if ($orderStepsToInclude && count($orderStepsToInclude)) {
1375
            if ($codesToInclude && count($codesToInclude)) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $codesToInclude of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
1376
                foreach ($codesToInclude as $className => $code) {
1377
                    $code = strtoupper($code);
1378
                    $filter = array('ClassName' => $className);
1379
                    $indexNumber += 10;
1380
                    $itemCount = OrderStep::get()->filter($filter)->Count();
1381
                    if ($itemCount > 0) {
1382
                        //always reset code
1383
                        $obj = DataObject::get_one(
1384
                            'OrderStep',
1385
                            $filter,
1386
                            $cacheDataObjectGetOne = false
1387
                        );
1388
                        if ($obj->Code != $code) {
1389
                            $obj->Code = $code;
1390
                            $obj->write();
1391
                        }
1392
                        //replace default description
1393
                        $parentObj = singleton('OrderStep');
1394
                        if ($obj->Description == $parentObj->myDescription()) {
1395
                            $obj->Description = $obj->myDescription();
1396
                            $obj->write();
1397
                        }
1398
                        //check sorting order
1399
                        if ($obj->Sort != $indexNumber) {
1400
                            $obj->Sort = $indexNumber;
1401
                            $obj->write();
1402
                        }
1403
                    } else {
1404
                        $oldObjects = OrderStep::get()->filterAny(array('Code' => $code));
1405
                        foreach ($oldObjects as $oldObject) {
1406
                            DB::alteration_message('DELETING '.$oldObject->Title.' as this now appears obsolete', 'deleted');
1407
                            $oldObject->delete();
1408
                        }
1409
                        $obj = $className::create($filter);
1410
                        $obj->Code = $code;
1411
                        $obj->Description = $obj->myDescription();
1412
                        $obj->Sort = $indexNumber;
1413
                        $obj->write();
1414
                        DB::alteration_message("Created \"$code\" as $className.", 'created');
1415
                    }
1416
                    $obj = DataObject::get_one(
1417
                        'OrderStep',
1418
                        $filter,
1419
                        $cacheDataObjectGetOne = false
1420
                    );
1421
                    if (! $obj) {
1422
                        user_error("There was an error in creating the $code OrderStep");
1423
                    }
1424
                }
1425
            }
1426
        }
1427
        $steps = OrderStep::get();
1428
        foreach ($steps as $step) {
1429
            if (!$step->Description) {
1430
                $step->Description = $step->myDescription();
1431
                $step->write();
1432
            }
1433
        }
1434
    }
1435
1436
    /**
1437
     * returns the standard EcommerceDBConfig for use within OrderSteps.
1438
     *
1439
     * @return EcommerceDBConfig
1440
     */
1441
    protected function EcomConfig()
1442
    {
1443
        return EcommerceDBConfig::current_ecommerce_db_config();
1444
    }
1445
1446
    /**
1447
     * Explains the current order step.
1448
     *
1449
     * @return string
1450
     */
1451
    protected function myDescription()
1452
    {
1453
        return _t('OrderStep.DESCRIPTION', 'No description has been provided for this step.');
1454
    }
1455
}
1456