Completed
Push — master ( 1552c3...bf9266 )
by Nicolaas
15:17
created

OrderStep::CalculatedEmailSubject()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 1
dl 0
loc 4
rs 10
c 0
b 0
f 0
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
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.

You can fix this by adding a namespace to your class:

namespace YourVendor;

class YourClass { }

When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.

Loading history...
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...
Unused Code introduced by
The property $db is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

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
Unused Code introduced by
The property $indexes is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
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...
Unused Code introduced by
The property $has_many is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

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...
Unused Code introduced by
The property $field_labels is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

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...
Unused Code introduced by
The property $summary_fields is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

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...
Unused Code introduced by
The property $casting is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

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...
Unused Code introduced by
The property $searchable_fields is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

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...
Unused Code introduced by
The property $singular_name is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

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...
Unused Code introduced by
The property $plural_name is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

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.';
0 ignored issues
show
Unused Code introduced by
The property $description is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
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...
Unused Code introduced by
The property $default_sort is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

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...
Unused Code introduced by
The property $defaults is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

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
553
        } else {
554
            $fields->removeFieldFromTab('Root', 'OrderEmailRecords');
555
            $fields->removeFieldFromTab('Root.Main', 'EmailSubject');
556
            $fields->removeFieldFromTab('Root.Main', 'CustomerMessage');
557
        }
558
        //adding
559
        if (!$this->exists() || !$this->isDefaultStatusOption()) {
560
            $fields->removeFieldFromTab('Root.Main', 'Code');
561
            $fields->addFieldToTab('Root.Main', new DropdownField('ClassName', _t('OrderStep.TYPE', 'Type'), self::get_not_created_codes_for_order_steps_to_include()), 'Name');
562
        }
563
        if ($this->isDefaultStatusOption()) {
564
            $fields->replaceField('Code', $fields->dataFieldByName('Code')->performReadonlyTransformation());
565
        }
566
        //headers
567
        $fields->addFieldToTab('Root.Main', new HeaderField('WARNING1', _t('OrderStep.CAREFUL', 'CAREFUL! please edit details below with care'), 2), 'Description');
568
        $fields->addFieldToTab('Root.Main', new HeaderField('WARNING2', _t('OrderStep.CUSTOMERCANCHANGE', 'What can be changed during this step?'), 3), 'CustomerCanEdit');
569
        $fields->addFieldToTab('Root.Main', new HeaderField('WARNING5', _t('OrderStep.ORDERGROUPS', 'Order groups for customer?'), 3), 'ShowAsUncompletedOrder');
570
        $fields->addFieldToTab('Root.Main', new HeaderField('HideStepFromCustomerHeader', _t('OrderStep.HIDE_STEP_FROM_CUSTOMER_HEADER', 'Customer Interaction'), 3), 'HideStepFromCustomer');
571
        $fields->addFieldToTab('Root.Main', new HeaderField('DeferHeader', _t('OrderStep.DEFER_HEADER', 'Delay'), 3), 'DeferTimeInSeconds');
572
        //final cleanup
573
        $fields->removeFieldFromTab('Root.Main', 'Sort');
574
        $fields->addFieldToTab('Root.Main', new TextareaField('Description', _t('OrderStep.DESCRIPTION', 'Explanation for internal use only')), 'WARNING1');
575
576
        return $fields;
577
    }
578
579
    /**
580
     * link to edit the record.
581
     *
582
     * @param string | Null $action - e.g. edit
583
     *
584
     * @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...
585
     */
586
    public function CMSEditLink($action = null)
587
    {
588
        return CMSEditLinkAPI::find_edit_link_for_object($this, $action);
589
    }
590
591
    /**
592
     * tells the order to display itself with an alternative display page.
593
     * in that way, orders can be displayed differently for certain steps
594
     * for example, in a print step, the order can be displayed in a
595
     * PRINT ONLY format.
596
     *
597
     * When the method return null, the order is displayed using the standard display page
598
     *
599
     * @see Order::DisplayPage
600
     *
601
     * @return null|object (Page)
602
     **/
603
    public function AlternativeDisplayPage()
604
    {
605
        return;
606
    }
607
608
    /**
609
     * Allows the opportunity for the Order Step to add any fields to Order::getCMSFields
610
     * Usually this is added before ActionNextStepManually.
611
     *
612
     * @param FieldList $fields
613
     * @param Order     $order
614
     *
615
     * @return FieldList
616
     **/
617
    public function addOrderStepFields(FieldList $fields, Order $order)
618
    {
619
        return $fields;
620
    }
621
622
    /**
623
     *@return ValidationResult
624
     **/
625
    public function validate()
626
    {
627
        $result = parent::validate();
628
        $anotherOrderStepWithSameNameOrCode = OrderStep::get()
629
            ->filter(
630
                array(
631
                    '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...
632
                    '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...
633
                )
634
            )
635
            ->exclude(array('ID' => intval($this->ID)))
636
            ->First();
637
        if ($anotherOrderStepWithSameNameOrCode) {
638
            $result->error(_t('OrderStep.ORDERSTEPALREADYEXISTS', 'An order status with this name already exists. Please change the name and try again.'));
639
        }
640
641
        return $result;
642
    }
643
644
/**************************************************
645
* moving between statusses...
646
**************************************************/
647
    /**
648
     *initStep:
649
     * makes sure the step is ready to run.... (e.g. check if the order is ready to be emailed as receipt).
650
     * should be able to run this function many times to check if the step is ready.
651
     *
652
     * @see Order::doNextStatus
653
     *
654
     * @param Order object
655
     *
656
     * @return bool - true if the current step is ready to be run...
657
     **/
658
    public function initStep(Order $order)
659
    {
660
        user_error('Please implement the initStep method in a subclass ('.get_class().') of OrderStep', E_USER_WARNING);
661
662
        return true;
663
    }
664
665
    /**
666
     *doStep:
667
     * should only be able to run this function once
668
     * (init stops you from running it twice - in theory....)
669
     * runs the actual step.
670
     *
671
     * @see Order::doNextStatus
672
     *
673
     * @param Order object
674
     *
675
     * @return bool - true if run correctly.
676
     **/
677
    public function doStep(Order $order)
678
    {
679
        user_error('Please implement the initStep method in a subclass ('.get_class().') of OrderStep', E_USER_WARNING);
680
681
        return true;
682
    }
683
684
    /**
685
     * nextStep:
686
     * returns the next step (after it checks if everything is in place for the next step to run...).
687
     *
688
     * @see Order::doNextStatus
689
     *
690
     * @param Order $order
691
     *
692
     * @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...
693
     **/
694
    public function nextStep(Order $order)
695
    {
696
        $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...
697
        $nextOrderStepObject = DataObject::get_one(
698
            'OrderStep',
699
            $where
700
        );
701
        if ($nextOrderStepObject) {
702
            return $nextOrderStepObject;
703
        }
704
705
        return;
706
    }
707
708
/**************************************************
709
* Boolean checks
710
**************************************************/
711
712
    /**
713
     * Checks if a step has passed (been completed) in comparison to the current step.
714
     *
715
     * @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...
716
     * @param bool   $orIsEqualTo if set to true, this method will return TRUE if the step being checked is the current one
717
     *
718
     * @return bool
719
     **/
720
    public function hasPassed($code, $orIsEqualTo = false)
721
    {
722
        $otherStatus = DataObject::get_one(
723
            'OrderStep',
724
            array('Code' => $code)
725
        );
726
        if ($otherStatus) {
727
            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...
728
                return true;
729
            }
730
            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...
731
                return true;
732
            }
733
        } else {
734
            user_error("could not find $code in OrderStep", E_USER_NOTICE);
735
        }
736
737
        return false;
738
    }
739
740
    /**
741
     * @param string $code
742
     *
743
     * @return bool
744
     **/
745
    public function hasPassedOrIsEqualTo($code)
746
    {
747
        return $this->hasPassed($code, true);
748
    }
749
750
    /**
751
     * @param string $code
752
     *
753
     * @return bool
754
     **/
755
    public function hasNotPassed($code)
756
    {
757
        return (bool) !$this->hasPassed($code, true);
758
    }
759
760
    /**
761
     * Opposite of hasPassed.
762
     *
763
     * @param string $code
764
     *
765
     * @return bool
766
     **/
767
    public function isBefore($code)
768
    {
769
        return (bool) $this->hasPassed($code, false) ? false : true;
770
    }
771
772
    /**
773
     *@return bool
774
     **/
775
    protected function isDefaultStatusOption()
776
    {
777
        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...
778
    }
779
780
/**************************************************
781
* Email
782
**************************************************/
783
784
    /**
785
     * @var string
786
     */
787
    protected $emailClassName = 'Order_InvoiceEmail';
788
789
    /**
790
     * returns the email class used for emailing the
791
     * customer during a specific step (IF ANY!).
792
     *
793
     * @return string
794
     */
795
    public function getEmailClassName()
796
    {
797
        return $this->emailClassName;
798
    }
799
800
    /**
801
     * return true if done already or mailed successfully now.
802
     *
803
     * @param order         $order
804
     * @param string        $subject
805
     * @param string        $message
806
     * @param bool          $resend
807
     * @param bool | string $adminOnlyOrToEmail you can set to false = send to customer, true: send to admin, or email = send to email
808
     * @param string        $emailClassName
809
     *
810
     * @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...
811
     */
812
    protected function sendEmailForStep(
813
        $order,
814
        $subject,
815
        $message = '',
816
        $resend = false,
817
        $adminOnlyOrToEmail = false,
818
        $emailClassName = ''
819
    ) {
820
        if (!$this->hasBeenSent($order) || $resend) {
821
            if (!$subject) {
822
                $subject = $this->CalculatedEmailSubject($order);
823
            }
824
            $useAlternativeEmail = $adminOnlyOrToEmail && filter_var($adminOnlyOrToEmail, FILTER_VALIDATE_EMAIL);
825
826
            //this is NOT an admin EMAIL
827
            if ($this->hasCustomerMessage() || $useAlternativeEmail) {
828
                if (! $emailClassName) {
829
                    $emailClassName = $this->getEmailClassName();
830
                }
831
                return $order->sendEmail(
832
                    $emailClassName,
833
                    $subject,
834
                    $message,
835
                    $resend,
836
                    $adminOnlyOrToEmail
837
                );
838
            //ADMIN ONLY ....
839
            } else {
840
                if (! $emailClassName) {
841
                    $emailClassName = 'Order_ErrorEmail';
842
                }
843
                //looks like we are sending an error, but we are just using this for notification
844
                $message = _t('OrderStep.THISMESSAGENOTSENTTOCUSTOMER', 'NOTE: This message was not sent to the customer.').'<br /><br /><br /><br />'.$message;
845
                $outcome = $order->sendAdminNotification(
846
                    $emailClassName,
847
                    $subject,
848
                    $message,
849
                    $resend
850
                );
851
            }
852
            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...
853
                return true;
854
            }
855
856
            return false;
857
        }
858
859
        return true;
860
    }
861
862
    /**
863
     * sets the email class used for emailing the
864
     * customer during a specific step (IF ANY!).
865
     *
866
     * @param string
867
     */
868
    public function setEmailClassName($s)
869
    {
870
        $this->emailClassName = $s;
871
    }
872
873
    /**
874
     * returns a link that can be used to test
875
     * the email being sent during this step
876
     * this method returns NULL if no email
877
     * is being sent OR if there is no suitable Order
878
     * to test with...
879
     *
880
     * @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...
881
     */
882
    protected function testEmailLink()
883
    {
884
        if ($this->getEmailClassName()) {
885
            $order = DataObject::get_one(
886
                'Order',
887
                array('StatusID' => $this->ID),
888
                $cacheDataObjectGetOne = true,
889
                'RAND() ASC'
890
            );
891
            if(! $order) {
892
                $order = Order::get()
893
                    ->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...
894
                    ->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...
895
                    ->innerJoin('OrderStep', '"OrderStep"."ID" = "Order"."StatusID"')
896
                    ->first();
897
            }
898
            if ($order) {
899
                return OrderConfirmationPage::get_email_link(
900
                    $order->ID,
901
                    $this->getEmailClassName(),
902
                    $actuallySendEmail = false,
903
                    $alternativeOrderStepID = $this->ID
904
                );
905
            }
906
        }
907
    }
908
909
    /**
910
     * Has an email been sent to the customer for this
911
     * order step.
912
     *"-10 days".
913
     *
914
     * @param Order $order
915
     * @param bool  $checkDateOfOrder
916
     *
917
     * @return bool
918
     **/
919
    public function hasBeenSent(Order $order, $checkDateOfOrder = true)
920
    {
921
        //if it has been more than a XXX days since the order was last edited (submitted) then we do not send emails as
922
        //this would be embarrasing.
923
        if ($checkDateOfOrder) {
924
            if ($log = $order->SubmissionLog()) {
925
                $lastEditedValue = $log->LastEdited;
926
            } else {
927
                $lastEditedValue = $order->LastEdited;
928
            }
929
            if ((strtotime($lastEditedValue) < strtotime('-'.EcommerceConfig::get('OrderStep', 'number_of_days_to_send_update_email').' days'))) {
930
                return true;
931
            }
932
        }
933
        $count = OrderEmailRecord::get()
934
            ->Filter(array(
935
                'OrderID' => $order->ID,
936
                'OrderStepID' => $this->ID,
937
                'Result' => 1,
938
            ))
939
            ->count();
940
941
        return $count ? true : false;
942
    }
943
944
    /**
945
     * For some ordersteps this returns true...
946
     *
947
     * @return bool
948
     **/
949
    protected function hasCustomerMessage()
950
    {
951
        return false;
952
    }
953
954
955
    /**
956
     * Formatted answer for "hasCustomerMessage".
957
     *
958
     * @return string
959
     */
960
    public function HasCustomerMessageNice()
961
    {
962
        return $this->getHasCustomerMessageNice();
963
    }
964
    public function getHasCustomerMessageNice()
965
    {
966
        return $this->hasCustomerMessage() ?  _t('OrderStep.YES', 'Yes') :  _t('OrderStep.NO', 'No');
967
    }
968
969
    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...
970
    {
971
        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...
972
    }
973
974
    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...
975
    {
976
        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...
977
    }
978
979
    /**
980
     * Formatted answer for "hasCustomerMessage".
981
     *
982
     * @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...
983
     */
984
    public function ShowAsSummary()
985
    {
986
        return $this->getShowAsSummary();
987
    }
988
989
    /**
990
     *
991
     *
992
     * @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...
993
     */
994
    public function getShowAsSummary()
995
    {
996
        $v = '<strong>';
997
        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...
998
            $v .= _t('OrderStep.UNCOMPLETED', 'Uncompleted');
999
        } 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...
1000
            $v .= _t('OrderStep.INPROCESS', 'In process');
1001
        } 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...
1002
            $v .= _t('OrderStep.COMPLETED', 'Completed');
1003
        }
1004
        $v .= '</strong>';
1005
        $canArray = array();
1006
        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...
1007
            $canArray[] = _t('OrderStep.EDITABLE', 'edit');
1008
        }
1009
        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...
1010
            $canArray[] = _t('OrderStep.PAY', 'pay');
1011
        }
1012
        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...
1013
            $canArray[] = _t('OrderStep.CANCEL', 'cancel');
1014
        }
1015
        if (count($canArray)) {
1016
            $v .=  '<br />'._t('OrderStep.CUSTOMER_CAN', 'Customer Can').': '.implode(', ', $canArray).'';
1017
        }
1018
        if ($this->hasCustomerMessage()) {
1019
            $v .= '<br />'._t('OrderStep.CUSTOMER_MESSAGES', 'Includes message to customer');
1020
        }
1021
        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...
1022
            $v .= '<br />'.$this->humanReadeableDeferTimeInSeconds();
1023
        }
1024
1025
        return DBField::create_field('HTMLText', $v);
1026
    }
1027
1028
    /**
1029
     * @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...
1030
     */
1031
    protected function humanReadeableDeferTimeInSeconds()
1032
    {
1033
        if ($this->canBeDefered()) {
1034
            $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...
1035
            $descr0 = _t('OrderStep.THE', 'The').' '.'<span style="color: #338DC1">'.$this->getTitle().'</span>';
1036
            $descr1 = _t('OrderStep.DELAY_VALUE', 'Order Step, for any order, will run');
1037
            $descr2 = $field->ago();
1038
            $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...
1039
                    _t('OrderStep.FROM_ORDER_SUBMIT_TIME', 'from the order being submitted') :
1040
                    _t('OrderStep.FROM_START_OF_ORDSTEP', 'from the order arriving on this step');
1041
            return $descr0. ' ' . $descr1.' <span style="color: #338DC1">'.$descr2.'</span> '.$descr3.'.';
1042
        }
1043
        // $dtF = new \DateTime('@0');
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
1044
        // $dtT = new \DateTime("@".$this->DeferTimeInSeconds);
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
1045
        //
1046
        // return $dtF->diff($dtT)->format('%a days, %h hours, %i minutes and %s seconds');
0 ignored issues
show
Unused Code Comprehensibility introduced by
74% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
1047
    }
1048
1049
    /**
1050
     * Formatted answer for "hasCustomerMessage".
1051
     *
1052
     * @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...
1053
     */
1054
    public function NameAndDescription()
1055
    {
1056
        return $this->getNameAndDescription();
1057
    }
1058
1059
    public function getNameAndDescription()
1060
    {
1061
        $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...
1062
1063
        return DBField::create_field('HTMLText', $v);
1064
    }
1065
1066
    /**
1067
     * This allows you to set the time to something other than the standard DeferTimeInSeconds
1068
     * value based on the order provided.
1069
     *
1070
     * @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...
1071
     *
1072
     * @return int
1073
     */
1074
    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...
1075
    {
1076
        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...
1077
    }
1078
1079
    /**
1080
     * can this order step be delayed?
1081
     * in general, if there is a customer message
1082
     * we should be able to delay it
1083
     *
1084
     * This method can be overridden in any orderstep
1085
     * @return bool
1086
     **/
1087
    protected function canBeDefered()
1088
    {
1089
        return $this->hasCustomerMessage();
1090
    }
1091
1092
1093
/**************************************************
1094
* Order Status Logs
1095
**************************************************/
1096
1097
    /**
1098
     * The OrderStatusLog that is relevant to the particular step.
1099
     *
1100
     * @var string
1101
     */
1102
    protected $relevantLogEntryClassName = '';
1103
1104
    /**
1105
     * @return string
1106
     */
1107
    public function getRelevantLogEntryClassName()
1108
    {
1109
        return $this->relevantLogEntryClassName;
1110
    }
1111
1112
    /**
1113
     * @param string
1114
     */
1115
    public function setRelevantLogEntryClassName($s)
1116
    {
1117
        $this->relevantLogEntryClassName = $s;
1118
    }
1119
1120
    /**
1121
     * returns the OrderStatusLog that is relevant to this step.
1122
     *
1123
     * @param Order $order
1124
     *
1125
     * @return OrderStatusLog | null
1126
     */
1127
    public function RelevantLogEntry(Order $order)
1128
    {
1129
        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...
1130
            return $this->RelevantLogEntries($order)->Last();
1131
        }
1132
    }
1133
1134
    /**
1135
     * returns the OrderStatusLogs that are relevant to this step.
1136
     * It is important that getRelevantLogEntryClassName returns
1137
     * a specific enough ClassName and not a base class name.
1138
     *
1139
     * @param Order $order
1140
     *
1141
     * @return DataObjectSet | null
1142
     */
1143
    public function RelevantLogEntries(Order $order)
1144
    {
1145
        if ($className = $this->getRelevantLogEntryClassName()) {
1146
            return $className::get()->filter(
1147
                array(
1148
                    'OrderID' => $order->ID
1149
                )
1150
            );
1151
        }
1152
    }
1153
1154
/**************************************************
1155
* Silverstripe Standard Data Object Methods
1156
**************************************************/
1157
1158
    /**
1159
     * Standard SS method
1160
     * These are only created programmatically.
1161
     *
1162
     * @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...
1163
     *
1164
     * @return bool
1165
     */
1166
    public function canCreate($member = null)
1167
    {
1168
        return false;
1169
    }
1170
1171
    /**
1172
     * Standard SS method.
1173
     *
1174
     * @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...
1175
     *
1176
     * @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...
1177
     */
1178
    public function canView($member = null)
1179
    {
1180
        if (! $member) {
1181
            $member = Member::currentUser();
1182
        }
1183
        $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...
1184
        if ($extended !== null) {
1185
            return $extended;
1186
        }
1187
        if (Permission::checkMember($member, Config::inst()->get('EcommerceRole', 'admin_permission_code'))) {
1188
            return true;
1189
        }
1190
1191
        return parent::canEdit($member);
0 ignored issues
show
Bug introduced by
It seems like $member defined by \Member::currentUser() on line 1181 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...
1192
    }
1193
1194
    /**
1195
     * the default for this is TRUE, but for completed order steps
1196
     *
1197
     * we do not allow this.
1198
     *
1199
     * @param  Order $order
1200
     * @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...
1201
     * @return bool
1202
     */
1203
    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...
1204
    {
1205
        //return true if the order can have customer input
1206
        // orders recently saved can also be views
1207
        return
1208
            $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...
1209
            $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...
1210
            $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...
1211
    }
1212
1213
    /**
1214
     * standard SS method.
1215
     *
1216
     * @param Member | NULL
1217
     *
1218
     * @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...
1219
     */
1220
    public function canEdit($member = null)
1221
    {
1222
        if (! $member) {
1223
            $member = Member::currentUser();
1224
        }
1225
        $extended = $this->extendedCan(__FUNCTION__, $member);
1226
        if ($extended !== null) {
1227
            return $extended;
1228
        }
1229
        if (Permission::checkMember($member, Config::inst()->get('EcommerceRole', 'admin_permission_code'))) {
1230
            return true;
1231
        }
1232
1233
        return parent::canEdit($member);
1234
    }
1235
1236
    /**
1237
     * Standard SS method.
1238
     *
1239
     * @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...
1240
     *
1241
     * @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...
1242
     */
1243
    public function canDelete($member = null)
1244
    {
1245
        //cant delete last status if there are orders with this status
1246
        $nextOrderStepObject = $this->NextOrderStep();
1247
        if ($nextOrderStepObject) {
0 ignored issues
show
Unused Code introduced by
This if statement is empty and can be removed.

This check looks for the bodies of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These if bodies can be removed. If you have an empty if but statements in the else branch, consider inverting the condition.

if (rand(1, 6) > 3) {
//print "Check failed";
} else {
    print "Check succeeded";
}

could be turned into

if (rand(1, 6) <= 3) {
    print "Check succeeded";
}

This is much more concise to read.

Loading history...
1248
            //do nothing
1249
        } else {
1250
            $orderCount = Order::get()
1251
                ->filter(array('StatusID' => intval($this->ID) - 0))
1252
                ->count();
1253
            if ($orderCount) {
1254
                return false;
1255
            }
1256
        }
1257
        if ($this->isDefaultStatusOption()) {
1258
            return false;
1259
        }
1260
        if (! $member) {
1261
            $member = Member::currentUser();
1262
        }
1263
        $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...
1264
        if ($extended !== null) {
1265
            return $extended;
1266
        }
1267
        if (Permission::checkMember($member, Config::inst()->get('EcommerceRole', 'admin_permission_code'))) {
1268
            return true;
1269
        }
1270
1271
        return parent::canEdit($member);
0 ignored issues
show
Bug introduced by
It seems like $member defined by \Member::currentUser() on line 1261 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...
1272
    }
1273
1274
    /**
1275
     * standard SS method.
1276
     */
1277
    public function onBeforeWrite()
1278
    {
1279
        parent::onBeforeWrite();
1280
        //make sure only one of three conditions applies ...
1281
        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...
1282
            $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...
1283
            $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...
1284
        } 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...
1285
            $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...
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->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...
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->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...
1290
        }
1291
        if (! $this->canBeDefered()) {
1292
            $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...
1293
            $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...
1294
        } else {
1295
            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...
1296
                $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...
1297
            } else {
1298
                $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...
1299
                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...
1300
                    $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...
1301
                }
1302
            }
1303
        }
1304
        $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...
1305
    }
1306
1307
    /**
1308
     * move linked orders to the next status
1309
     * standard SS method.
1310
     */
1311
    public function onBeforeDelete()
1312
    {
1313
        $ordersWithThisStatus = Order::get()->filter(array('StatusID' => $this->ID));
1314
        if ($ordersWithThisStatus->count()) {
1315
            $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...
1316
            $bestOrderStep = $this->NextOrderStep();
1317
            //backup
1318
            if ($bestOrderStep && $bestOrderStep->exists()) {
0 ignored issues
show
Unused Code introduced by
This if statement is empty and can be removed.

This check looks for the bodies of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These if bodies can be removed. If you have an empty if but statements in the else branch, consider inverting the condition.

if (rand(1, 6) > 3) {
//print "Check failed";
} else {
    print "Check succeeded";
}

could be turned into

if (rand(1, 6) <= 3) {
    print "Check succeeded";
}

This is much more concise to read.

Loading history...
1319
                //do nothing
1320
            } else {
1321
                $bestOrderStep = $this->PreviousOrderStep();
1322
            }
1323
            if ($bestOrderStep) {
1324
                foreach ($ordersWithThisStatus as $orderWithThisStatus) {
1325
                    $orderWithThisStatus->StatusID = $bestOrderStep->ID;
1326
                    $orderWithThisStatus->write();
1327
                }
1328
            }
1329
        }
1330
        parent::onBeforeDelete();
1331
    }
1332
1333
    /**
1334
     * standard SS method.
1335
     */
1336
    public function onAfterDelete()
1337
    {
1338
        parent::onAfterDelete();
1339
        $this->requireDefaultRecords();
1340
    }
1341
1342
    protected function NextOrderStep()
1343
    {
1344
        return OrderStep::get()
1345
            ->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...
1346
            ->First();
1347
    }
1348
1349
    protected function PreviousOrderStep()
1350
    {
1351
        return OrderStep::get()
1352
            ->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...
1353
            ->First();
1354
    }
1355
1356
    /**
1357
     * standard SS method
1358
     * USED TO BE: Unpaid,Query,Paid,Processing,Sent,Complete,AdminCancelled,MemberCancelled,Cart.
1359
     */
1360
    public function requireDefaultRecords()
1361
    {
1362
        parent::requireDefaultRecords();
1363
        $orderStepsToInclude = EcommerceConfig::get('OrderStep', 'order_steps_to_include');
1364
        $codesToInclude = self::get_codes_for_order_steps_to_include();
1365
        $indexNumber = 0;
1366
        if ($orderStepsToInclude && count($orderStepsToInclude)) {
1367
            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...
1368
                foreach ($codesToInclude as $className => $code) {
1369
                    $code = strtoupper($code);
1370
                    $filter = array('ClassName' => $className);
1371
                    $indexNumber += 10;
1372
                    $itemCount = OrderStep::get()->filter($filter)->Count();
1373
                    if ($itemCount > 0) {
1374
                        //always reset code
1375
                        $obj = DataObject::get_one(
1376
                            'OrderStep',
1377
                            $filter,
1378
                            $cacheDataObjectGetOne = false
1379
                        );
1380
                        if ($obj->Code != $code) {
1381
                            $obj->Code = $code;
1382
                            $obj->write();
1383
                        }
1384
                        //replace default description
1385
                        $parentObj = singleton('OrderStep');
1386
                        if ($obj->Description == $parentObj->myDescription()) {
1387
                            $obj->Description = $obj->myDescription();
1388
                            $obj->write();
1389
                        }
1390
                        //check sorting order
1391
                        if ($obj->Sort != $indexNumber) {
1392
                            $obj->Sort = $indexNumber;
1393
                            $obj->write();
1394
                        }
1395
                    } else {
1396
                        $oldObjects = OrderStep::get()->filterAny(array('Code' => $code));
1397
                        foreach($oldObjects as $oldObject) {
1398
                            DB::alteration_message('DELETING '.$oldObject->Title.' as this now appears obsolete', 'deleted');
1399
                            $oldObject->delete();
1400
                        }
1401
                        $obj = $className::create($filter);
1402
                        $obj->Code = $code;
1403
                        $obj->Description = $obj->myDescription();
1404
                        $obj->Sort = $indexNumber;
1405
                        $obj->write();
1406
                        DB::alteration_message("Created \"$code\" as $className.", 'created');
1407
                    }
1408
                    $obj = DataObject::get_one(
1409
                        'OrderStep',
1410
                        $filter,
1411
                        $cacheDataObjectGetOne = false
1412
                    );
1413
                    if (! $obj) {
1414
                        user_error("There was an error in creating the $code OrderStep");
1415
                    }
1416
                }
1417
            }
1418
        }
1419
        $steps = OrderStep::get();
1420
        foreach ($steps as $step) {
1421
            if (!$step->Description) {
1422
                $step->Description = $step->myDescription();
1423
                $step->write();
1424
            }
1425
        }
1426
    }
1427
1428
    /**
1429
     * returns the standard EcommerceDBConfig for use within OrderSteps.
1430
     *
1431
     * @return EcommerceDBConfig
1432
     */
1433
    protected function EcomConfig()
1434
    {
1435
        return EcommerceDBConfig::current_ecommerce_db_config();
1436
    }
1437
1438
    /**
1439
     * Explains the current order step.
1440
     *
1441
     * @return string
1442
     */
1443
    protected function myDescription()
1444
    {
1445
        return _t('OrderStep.DESCRIPTION', 'No description has been provided for this step.');
1446
    }
1447
}
1448