Completed
Push — master ( b2f996...40b731 )
by Nicolaas
02:54
created

OrderStep::last_order_step()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 4
nc 2
nop 1
dl 0
loc 8
rs 9.4285
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
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 $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...
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
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 = '';
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->EmailSubject;
0 ignored issues
show
Documentation introduced by
The property EmailSubject 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...
823
            }
824
            if (!$emailClassName) {
825
                $emailClassName = $this->getEmailClassName();
826
            }
827
            $adminOnlyOrToEmailIsEmail = $adminOnlyOrToEmail && filter_var($adminOnlyOrToEmail, FILTER_VALIDATE_EMAIL);
828
            if ($this->hasCustomerMessage() || $adminOnlyOrToEmailIsEmail) {
829
                return $order->sendEmail(
830
                    $emailClassName,
831
                    $subject,
832
                    $message,
833
                    $resend,
834
                    $adminOnlyOrToEmail
835
                );
836
            } else {
837
                if (!$emailClassName) {
838
                    $emailClassName = 'Order_ErrorEmail';
839
                }
840
                //looks like we are sending an error, but we are just using this for notification
841
                $message = _t('OrderStep.THISMESSAGENOTSENTTOCUSTOMER', 'NOTE: This message was not sent to the customer.').'<br /><br /><br /><br />'.$message;
842
                $outcome = $order->sendAdminNotification(
843
                    $emailClassName,
844
                    $subject,
845
                    $message,
846
                    $resend
847
                );
848
            }
849
            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...
850
                return true;
851
            }
852
853
            return false;
854
        }
855
856
        return true;
857
    }
858
859
    /**
860
     * sets the email class used for emailing the
861
     * customer during a specific step (IF ANY!).
862
     *
863
     * @param string
864
     */
865
    public function setEmailClassName($s)
866
    {
867
        $this->emailClassName = $s;
868
    }
869
870
    /**
871
     * returns a link that can be used to test
872
     * the email being sent during this step
873
     * this method returns NULL if no email
874
     * is being sent OR if there is no suitable Order
875
     * to test with...
876
     *
877
     * @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...
878
     */
879
    protected function testEmailLink()
880
    {
881
        if ($this->getEmailClassName()) {
882
            $order = DataObject::get_one(
883
                'Order',
884
                array('StatusID' => $this->ID),
885
                $cacheDataObjectGetOne = true,
886
                'RAND() ASC'
887
            );
888
            if(! $order) {
889
                $order = Order::get()
890
                    ->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...
891
                    ->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...
892
                    ->innerJoin('OrderStep', '"OrderStep"."ID" = "Order"."StatusID"')
893
                    ->first();
894
            }
895
            if ($order) {
896
                return OrderConfirmationPage::get_email_link(
897
                    $order->ID,
898
                    $this->getEmailClassName(),
899
                    $actuallySendEmail = false,
900
                    $alternativeOrderStepID = $this->ID
901
                );
902
            }
903
        }
904
    }
905
906
    /**
907
     * Has an email been sent to the customer for this
908
     * order step.
909
     *"-10 days".
910
     *
911
     * @param Order $order
912
     * @param bool  $checkDateOfOrder
913
     *
914
     * @return bool
915
     **/
916
    public function hasBeenSent(Order $order, $checkDateOfOrder = true)
917
    {
918
        //if it has been more than a XXX days since the order was last edited (submitted) then we do not send emails as
919
        //this would be embarrasing.
920
        if ($checkDateOfOrder) {
921
            if ($log = $order->SubmissionLog()) {
922
                $lastEditedValue = $log->LastEdited;
923
            } else {
924
                $lastEditedValue = $order->LastEdited;
925
            }
926
            if ((strtotime($lastEditedValue) < strtotime('-'.EcommerceConfig::get('OrderStep', 'number_of_days_to_send_update_email').' days'))) {
927
                return true;
928
            }
929
        }
930
        $count = OrderEmailRecord::get()
931
            ->Filter(array(
932
                'OrderID' => $order->ID,
933
                'OrderStepID' => $this->ID,
934
                'Result' => 1,
935
            ))
936
            ->count();
937
938
        return $count ? true : false;
939
    }
940
941
    /**
942
     * For some ordersteps this returns true...
943
     *
944
     * @return bool
945
     **/
946
    protected function hasCustomerMessage()
947
    {
948
        return false;
949
    }
950
951
952
    /**
953
     * Formatted answer for "hasCustomerMessage".
954
     *
955
     * @return string
956
     */
957
    public function HasCustomerMessageNice()
958
    {
959
        return $this->getHasCustomerMessageNice();
960
    }
961
    public function getHasCustomerMessageNice()
962
    {
963
        return $this->hasCustomerMessage() ?  _t('OrderStep.YES', 'Yes') :  _t('OrderStep.NO', 'No');
964
    }
965
966
    /**
967
     * Formatted answer for "hasCustomerMessage".
968
     *
969
     * @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...
970
     */
971
    public function ShowAsSummary()
972
    {
973
        return $this->getShowAsSummary();
974
    }
975
976
    /**
977
     *
978
     *
979
     * @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...
980
     */
981
    public function getShowAsSummary()
982
    {
983
        $v = '<strong>';
984
        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...
985
            $v .= _t('OrderStep.UNCOMPLETED', 'Uncompleted');
986
        } 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...
987
            $v .= _t('OrderStep.INPROCESS', 'In process');
988
        } 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...
989
            $v .= _t('OrderStep.COMPLETED', 'Completed');
990
        }
991
        $v .= '</strong>';
992
        $canArray = array();
993
        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...
994
            $canArray[] = _t('OrderStep.EDITABLE', 'edit');
995
        }
996
        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...
997
            $canArray[] = _t('OrderStep.PAY', 'pay');
998
        }
999
        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...
1000
            $canArray[] = _t('OrderStep.CANCEL', 'cancel');
1001
        }
1002
        if (count($canArray)) {
1003
            $v .=  '<br />'._t('OrderStep.CUSTOMER_CAN', 'Customer Can').': '.implode(', ', $canArray).'';
1004
        }
1005
        if ($this->hasCustomerMessage()) {
1006
            $v .= '<br />'._t('OrderStep.CUSTOMER_MESSAGES', 'Includes message to customer');
1007
        }
1008
        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...
1009
            $v .= '<br />'.$this->humanReadeableDeferTimeInSeconds();
1010
        }
1011
1012
        return DBField::create_field('HTMLText', $v);
1013
    }
1014
1015
    /**
1016
     * @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...
1017
     */
1018
    protected function humanReadeableDeferTimeInSeconds()
1019
    {
1020
        if ($this->canBeDefered()) {
1021
            $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...
1022
            $descr0 = _t('OrderStep.THE', 'The').' '.'<span style="color: #338DC1">'.$this->getTitle().'</span>';
1023
            $descr1 = _t('OrderStep.DELAY_VALUE', 'Order Step, for any order, will run');
1024
            $descr2 = $field->ago();
1025
            $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...
1026
                    _t('OrderStep.FROM_ORDER_SUBMIT_TIME', 'from the order being submitted') :
1027
                    _t('OrderStep.FROM_START_OF_ORDSTEP', 'from the order arriving on this step');
1028
            return $descr0. ' ' . $descr1.' <span style="color: #338DC1">'.$descr2.'</span> '.$descr3.'.';
1029
        }
1030
        // $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...
1031
        // $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...
1032
        //
1033
        // 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...
1034
    }
1035
1036
    /**
1037
     * Formatted answer for "hasCustomerMessage".
1038
     *
1039
     * @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...
1040
     */
1041
    public function NameAndDescription()
1042
    {
1043
        return $this->getNameAndDescription();
1044
    }
1045
1046
    public function getNameAndDescription()
1047
    {
1048
        $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...
1049
1050
        return DBField::create_field('HTMLText', $v);
1051
    }
1052
1053
    /**
1054
     * This allows you to set the time to something other than the standard DeferTimeInSeconds
1055
     * value based on the order provided.
1056
     *
1057
     * @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...
1058
     *
1059
     * @return int
1060
     */
1061
    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...
1062
    {
1063
        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...
1064
    }
1065
1066
    /**
1067
     * can this order step be delayed?
1068
     * in general, if there is a customer message
1069
     * we should be able to delay it
1070
     *
1071
     * This method can be overridden in any orderstep
1072
     * @return bool
1073
     **/
1074
    protected function canBeDefered()
1075
    {
1076
        return $this->hasCustomerMessage();
1077
    }
1078
1079
1080
/**************************************************
1081
* Order Status Logs
1082
**************************************************/
1083
1084
    /**
1085
     * The OrderStatusLog that is relevant to the particular step.
1086
     *
1087
     * @var string
1088
     */
1089
    protected $relevantLogEntryClassName = '';
1090
1091
    /**
1092
     * @return string
1093
     */
1094
    public function getRelevantLogEntryClassName()
1095
    {
1096
        return $this->relevantLogEntryClassName;
1097
    }
1098
1099
    /**
1100
     * @param string
1101
     */
1102
    public function setRelevantLogEntryClassName($s)
1103
    {
1104
        $this->relevantLogEntryClassName = $s;
1105
    }
1106
1107
    /**
1108
     * returns the OrderStatusLog that is relevant to this step.
1109
     *
1110
     * @param Order $order
1111
     *
1112
     * @return OrderStatusLog | null
1113
     */
1114
    public function RelevantLogEntry(Order $order)
1115
    {
1116
        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...
1117
            return $this->RelevantLogEntries($order)->Last();
1118
        }
1119
    }
1120
1121
    /**
1122
     * returns the OrderStatusLogs that are relevant to this step.
1123
     * It is important that getRelevantLogEntryClassName returns
1124
     * a specific enough ClassName and not a base class name.
1125
     *
1126
     * @param Order $order
1127
     *
1128
     * @return DataObjectSet | null
1129
     */
1130
    public function RelevantLogEntries(Order $order)
1131
    {
1132
        if ($className = $this->getRelevantLogEntryClassName()) {
1133
            return $className::get()->filter(
1134
                array(
1135
                    'OrderID' => $order->ID
1136
                )
1137
            );
1138
        }
1139
    }
1140
1141
/**************************************************
1142
* Silverstripe Standard Data Object Methods
1143
**************************************************/
1144
1145
    /**
1146
     * Standard SS method
1147
     * These are only created programmatically.
1148
     *
1149
     * @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...
1150
     *
1151
     * @return bool
1152
     */
1153
    public function canCreate($member = null)
1154
    {
1155
        return false;
1156
    }
1157
1158
    /**
1159
     * Standard SS method.
1160
     *
1161
     * @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...
1162
     *
1163
     * @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...
1164
     */
1165
    public function canView($member = null)
1166
    {
1167
        if (! $member) {
1168
            $member = Member::currentUser();
1169
        }
1170
        $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...
1171
        if ($extended !== null) {
1172
            return $extended;
1173
        }
1174
        if (Permission::checkMember($member, Config::inst()->get('EcommerceRole', 'admin_permission_code'))) {
1175
            return true;
1176
        }
1177
1178
        return parent::canEdit($member);
0 ignored issues
show
Bug introduced by
It seems like $member defined by \Member::currentUser() on line 1168 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...
1179
    }
1180
1181
    /**
1182
     * the default for this is TRUE, but for completed order steps
1183
     *
1184
     * we do not allow this.
1185
     *
1186
     * @param  Order $order
1187
     * @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...
1188
     * @return bool
1189
     */
1190
    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...
1191
    {
1192
        //return true if the order can have customer input
1193
        // orders recently saved can also be views
1194
        return
1195
            $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...
1196
            $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...
1197
            $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...
1198
    }
1199
1200
    /**
1201
     * standard SS method.
1202
     *
1203
     * @param Member | NULL
1204
     *
1205
     * @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...
1206
     */
1207
    public function canEdit($member = null)
1208
    {
1209
        if (! $member) {
1210
            $member = Member::currentUser();
1211
        }
1212
        $extended = $this->extendedCan(__FUNCTION__, $member);
1213
        if ($extended !== null) {
1214
            return $extended;
1215
        }
1216
        if (Permission::checkMember($member, Config::inst()->get('EcommerceRole', 'admin_permission_code'))) {
1217
            return true;
1218
        }
1219
1220
        return parent::canEdit($member);
1221
    }
1222
1223
    /**
1224
     * Standard SS method.
1225
     *
1226
     * @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...
1227
     *
1228
     * @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...
1229
     */
1230
    public function canDelete($member = null)
1231
    {
1232
        //cant delete last status if there are orders with this status
1233
        $nextOrderStepObject = $this->NextOrderStep();
1234
        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...
1235
            //do nothing
1236
        } else {
1237
            $orderCount = Order::get()
1238
                ->filter(array('StatusID' => intval($this->ID) - 0))
1239
                ->count();
1240
            if ($orderCount) {
1241
                return false;
1242
            }
1243
        }
1244
        if ($this->isDefaultStatusOption()) {
1245
            return false;
1246
        }
1247
        if (! $member) {
1248
            $member = Member::currentUser();
1249
        }
1250
        $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...
1251
        if ($extended !== null) {
1252
            return $extended;
1253
        }
1254
        if (Permission::checkMember($member, Config::inst()->get('EcommerceRole', 'admin_permission_code'))) {
1255
            return true;
1256
        }
1257
1258
        return parent::canEdit($member);
0 ignored issues
show
Bug introduced by
It seems like $member defined by \Member::currentUser() on line 1248 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...
1259
    }
1260
1261
    /**
1262
     * standard SS method.
1263
     */
1264
    public function onBeforeWrite()
1265
    {
1266
        parent::onBeforeWrite();
1267
        //make sure only one of three conditions applies ...
1268
        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...
1269
            $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...
1270
            $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...
1271
        } 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...
1272
            $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...
1273
            $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...
1274
        } 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...
1275
            $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...
1276
            $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...
1277
        }
1278
        if (! $this->canBeDefered()) {
1279
            $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...
1280
            $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...
1281
        } else {
1282
            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...
1283
                $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...
1284
            } else {
1285
                $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...
1286
                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...
1287
                    $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...
1288
                }
1289
            }
1290
        }
1291
        $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...
1292
    }
1293
1294
    /**
1295
     * move linked orders to the next status
1296
     * standard SS method.
1297
     */
1298
    public function onBeforeDelete()
1299
    {
1300
        $ordersWithThisStatus = Order::get()->filter(array('StatusID' => $this->ID));
1301
        if ($ordersWithThisStatus->count()) {
1302
            $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...
1303
            $bestOrderStep = $this->NextOrderStep();
1304
            //backup
1305
            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...
1306
                //do nothing
1307
            } else {
1308
                $bestOrderStep = $this->PreviousOrderStep();
1309
            }
1310
            if ($bestOrderStep) {
1311
                foreach ($ordersWithThisStatus as $orderWithThisStatus) {
1312
                    $orderWithThisStatus->StatusID = $bestOrderStep->ID;
1313
                    $orderWithThisStatus->write();
1314
                }
1315
            }
1316
        }
1317
        parent::onBeforeDelete();
1318
    }
1319
1320
    /**
1321
     * standard SS method.
1322
     */
1323
    public function onAfterDelete()
1324
    {
1325
        parent::onAfterDelete();
1326
        $this->requireDefaultRecords();
1327
    }
1328
1329
    protected function NextOrderStep()
1330
    {
1331
        return OrderStep::get()
1332
            ->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...
1333
            ->First();
1334
    }
1335
1336
    protected function PreviousOrderStep()
1337
    {
1338
        return OrderStep::get()
1339
            ->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...
1340
            ->First();
1341
    }
1342
1343
    /**
1344
     * standard SS method
1345
     * USED TO BE: Unpaid,Query,Paid,Processing,Sent,Complete,AdminCancelled,MemberCancelled,Cart.
1346
     */
1347
    public function requireDefaultRecords()
1348
    {
1349
        parent::requireDefaultRecords();
1350
        $orderStepsToInclude = EcommerceConfig::get('OrderStep', 'order_steps_to_include');
1351
        $codesToInclude = self::get_codes_for_order_steps_to_include();
1352
        $indexNumber = 0;
1353
        if ($orderStepsToInclude && count($orderStepsToInclude)) {
1354
            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...
1355
                foreach ($codesToInclude as $className => $code) {
1356
                    $code = strtoupper($code);
1357
                    $filter = array('ClassName' => $className);
1358
                    $indexNumber += 10;
1359
                    $itemCount = OrderStep::get()->filter($filter)->Count();
1360
                    if ($itemCount > 0) {
1361
                        //always reset code
1362
                        $obj = DataObject::get_one(
1363
                            'OrderStep',
1364
                            $filter,
1365
                            $cacheDataObjectGetOne = false
1366
                        );
1367
                        if ($obj->Code != $code) {
1368
                            $obj->Code = $code;
1369
                            $obj->write();
1370
                        }
1371
                        //replace default description
1372
                        $parentObj = singleton('OrderStep');
1373
                        if ($obj->Description == $parentObj->myDescription()) {
1374
                            $obj->Description = $obj->myDescription();
1375
                            $obj->write();
1376
                        }
1377
                        //check sorting order
1378
                        if ($obj->Sort != $indexNumber) {
1379
                            $obj->Sort = $indexNumber;
1380
                            $obj->write();
1381
                        }
1382
                    } else {
1383
                        $oldObjects = OrderStep::get()->filterAny(array('Code' => $code));
1384
                        foreach($oldObjects as $oldObject) {
1385
                            DB::alteration_message('DELETING '.$oldObject->Title.' as this now appears obsolete', 'deleted');
1386
                            $oldObject->delete();
1387
                        }
1388
                        $obj = $className::create($filter);
1389
                        $obj->Code = $code;
1390
                        $obj->Description = $obj->myDescription();
1391
                        $obj->Sort = $indexNumber;
1392
                        $obj->write();
1393
                        DB::alteration_message("Created \"$code\" as $className.", 'created');
1394
                    }
1395
                    $obj = DataObject::get_one(
1396
                        'OrderStep',
1397
                        $filter,
1398
                        $cacheDataObjectGetOne = false
1399
                    );
1400
                    if (! $obj) {
1401
                        user_error("There was an error in creating the $code OrderStep");
1402
                    }
1403
                }
1404
            }
1405
        }
1406
        $steps = OrderStep::get();
1407
        foreach ($steps as $step) {
1408
            if (!$step->Description) {
1409
                $step->Description = $step->myDescription();
1410
                $step->write();
1411
            }
1412
        }
1413
    }
1414
1415
    /**
1416
     * returns the standard EcommerceDBConfig for use within OrderSteps.
1417
     *
1418
     * @return EcommerceDBConfig
1419
     */
1420
    protected function EcomConfig()
1421
    {
1422
        return EcommerceDBConfig::current_ecommerce_db_config();
1423
    }
1424
1425
    /**
1426
     * Explains the current order step.
1427
     *
1428
     * @return string
1429
     */
1430
    protected function myDescription()
1431
    {
1432
        return _t('OrderStep.DESCRIPTION', 'No description has been provided for this step.');
1433
    }
1434
}
1435