Completed
Push — master ( 21d98e...803d86 )
by Nicolaas
01:18
created

RepeatOrder::getFinalOrderDate()   A

Complexity

Conditions 4
Paths 5

Size

Total Lines 12

Duplication

Lines 12
Ratio 100 %

Importance

Changes 0
Metric Value
dl 12
loc 12
rs 9.8666
c 0
b 0
f 0
cc 4
nc 5
nop 0
1
<?php
2
3
/**
4
 * @author michael@ sunnysideup . co . nz
5
 */
6
7
class RepeatOrder extends DataObject
8
{
9
10
11
    #######################
12
    ### Names Section
13
    #######################
14
15
    private static $singular_name = 'Repeat Order';
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...
16
17
    public function i18n_singular_name()
18
    {
19
        return _t(self::class.'.SINGULAR_NAME', 'Repeat Order');
20
    }
21
22
    private static $plural_name = 'Repeat Orders';
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...
23
24
    public function i18n_plural_name()
25
    {
26
        return _t(self::class.'.PLURAL_NAME', 'Repeat Orders');
27
    }
28
29
30
31
    /**
32
     * Minimum of days in the future that the order is lodged.
33
     * @var int
34
     */
35
    private static $minimum_days_in_the_future = 1;
36
37
    /**
38
     * Standard SS variable
39
     */
40
    private static $db = [
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...
41
        'Status' => 'Enum(\'Pending, Active, MemberCancelled, AdminCancelled, Finished\', \'Pending\')',
42
        //dates
43
        'Start' => 'Date',
44
        'End' => 'Date',
45
        'Period' => 'Varchar',
46
        //payment
47
        'PaymentMethod' => 'Varchar',
48
        'CreditCardOnFile' => 'Boolean',
49
        'PaymentNote' => 'Text',
50
        //computed values and notes
51
        'ItemsForSearchPurposes' => 'Text', //FOR SEARCH PURPOSES ONLY!
52
        'Notes' => 'Text'
53
    ];
54
55
    /**
56
     * Standard SS variable
57
     */
58
    private static $has_one = [
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...
59
        'Member' => 'Member',
60
        'OriginatingOrder' => 'Order'
61
    ];
62
63
64
    /**
65
     * Standard SS variable
66
     */
67
    private static $has_many = [
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...
68
        'OrderItems' => 'RepeatOrder_OrderItem', //products & quanitites
69
        'Orders' => 'Order'
70
    ];
71
72
    /**
73
     * Standard SS variable.
74
     */
75
    private static $indexes = [
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...
76
        'Status' => true,
77
        'Start' => true,
78
        'End' => true,
79
        'Period' => true,
80
        'ItemsForSearchPurposes' => true
81
    ];
82
83
    /**
84
     * Standard SS variable
85
     */
86
    private static $casting = [
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...
87
        'OrderItemList' => 'Text',
88
        'FirstOrderDate' => 'Date',
89
        'LastOrderDate' => 'Date',
90
        'TodaysOrderDate' => 'Date',
91
        'NextOrderDate' => 'Date',
92
        'FinalOrderDate' => 'Date',
93
        'DeliverySchedule' => 'Text',
94
        'HasFutureOrders' => 'Boolean'
95
    ];
96
97
    #######################
98
    ### Field Names and Presentation Section
99
    #######################
100
101
    /**
102
     * Standard SS variable
103
     */
104
    private static $searchable_fields = [
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...
105
        'Status' => 'ExactMatchFilter',
106
        'Period' => 'PartialMatchFilter',
107
        //payment
108
        'PaymentMethod' => 'PartialMatchFilter',
109
        'CreditCardOnFile' => 'ExactMatchFilter',
110
        'PaymentNote' => 'PartialMatchFilter',
111
        //computed values and notes
112
        'Notes' => 'PartialMatchFilter',
113
        'ItemsForSearchPurposes' => 'PartialMatchFilter',
114
    ];
115
116
    /**
117
     * Standard SS variable
118
     */
119
    private static $summary_fields = [
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...
120
        'ID' => 'Repeat Order ID',
121
        'Member.Surname' => 'Surname',
122
        'Member.Email' => 'Email',
123
        'HasFutureOrders.Nice' => 'Future Orders',
124
        'OrderItemList' => 'Order Item List',
125
        'Start' => 'Start',
126
        'End' => 'End',
127
        'Period' => 'Period',
128
        'Status' => 'Status'
129
    ];
130
131
132
133
    private static $field_labels = [
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...
134
        'Status' => 'Status',
135
        //dates
136
        'Start' => 'Start Date',
137
        'End' => 'End Date',
138
        'Period' => 'Repeat Schedule',
139
        //payment
140
        'PaymentMethod' => 'Payment Type',
141
        'CreditCardOnFile' => 'Credit Card on File',
142
        'PaymentNote' => 'Payment Notes',
143
        'Notes' => 'Notes'
144
    ];
145
146
147
148
    /**
149
     * Standard SS variable
150
     */
151
    private static $default_sort = 'Created DESC';
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...
152
153
154
    /**
155
     * Dropdown options for Period
156
     * @var array 'strtotime period' > 'nice name'
157
     */
158
    private static $period_fields = [
159
        '1 day' => 'Daily',
160
        '1 week' => 'Weekly',
161
        '2 weeks' => 'Fornightly',
162
        '1 month' => 'Monthly'
163
    ];
164
165
    /**
166
     * @return string
0 ignored issues
show
Documentation introduced by
Should the return type not be integer|string?

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

Loading history...
167
     */
168
    public static function default_period_key()
169
    {
170
        if ($a = Config::inst()->get('RepeatOrder', 'period_fields')) {
171
            foreach ($a as $k => $v) {
0 ignored issues
show
Bug introduced by
The expression $a of type array|integer|double|string|boolean is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
172
                return $k;
173
            }
174
        }
175
176
        return '';
177
    }
178
179
180
    /**
181
     * @var array
182
     */
183
    private static $status_nice = array(
184
        'Pending' => 'Pending',
185
        'Active' => 'Active',
186
        'MemberCancelled' => 'Pending Cancellation',
187
        'AdminCancelled' => 'Cancelled',
188
        'Finished' => 'Finished',
189
    );
190
191
192
    /**
193
     * @var array
194
     */
195
    protected static $payment_methods = array(
196
        'DirectCreditPayment' => 'Direct Credit (payment into bank account)'
197
    );
198
199
    /**
200
     *
201
     * @return string
0 ignored issues
show
Documentation introduced by
Should the return type not be integer|string?

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

Loading history...
202
     */
203
    public static function default_payment_method_key()
204
    {
205
        $a = Config::inst()->get('RepeatOrder', 'payment_methods');
206
        foreach ($a as $k => $v) {
0 ignored issues
show
Bug introduced by
The expression $a of type array|integer|double|string|boolean is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
207
            return $k;
208
        }
209
        return '';
210
    }
211
212
    /**
213
     * Can it be edited, alias for canEdit
214
     *
215
     * @return bool
216
     */
217
    public function canModify($member = null)
0 ignored issues
show
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...
218
    {
219
        return $this->canEdit();
220
    }
221
222
    /**
223
     * Link for viewing
224
     * @return string
225
     */
226
    public function Link()
227
    {
228
        return RepeatOrdersPage::get_repeat_order_link('view', $this->ID);
229
    }
230
231
    /**
232
     * Link for editing
233
     * @return string
234
     */
235
    public function ModifyLink()
236
    {
237
        return RepeatOrdersPage::get_repeat_order_link('modify', $this->ID);
238
    }
239
240
241
    /**
242
     * Link for cancelling
243
     * @return string
244
     */
245
    public function CancelLink()
246
    {
247
        return RepeatOrdersPage::get_repeat_order_link('cancel', $this->ID);
248
    }
249
250
    /**
251
     * Link for end of view / edit / cancel session
252
     * @return string
253
     */
254
    public function DoneLink()
255
    {
256
        $page = DataObject::get_one("RepeatOrdersPage");
257
        if (!$page) {
258
            $page = DataObject::get_one("CheckoutPage");
259
            if (!$page) {
260
                $page = DataObject::get_one("Page");
261
            }
262
        }
263
        return $page->Link();
264
    }
265
266
    /**
267
     * returns a list of actual orders that have been created from this repeat order.
268
     * @return ArrayList|null
269
     */
270
    public function AutomaticallyCreatedOrders()
271
    {
272
        $orders = Order::get()->filter(["RepeatOrderID" => $this->ID])->sort(["OrderDate" => "ASC"]);
273
        $dos = ArrayList::create();
274
        if ($orders) {
275
            foreach ($orders as $order) {
276
                $dos->push($order);
277
            }
278
        }
279
        if ($dos && $dos->count()) {
280
            return $dos;
281
        }
282
    }
283
284
    //===================================================
285
    //===================================================
286
    //===================================================
287
288
    /**
289
     * Create due draft orders
290
     */
291
    public static function create_automatically_created_orders()
292
    {
293
        set_time_limit(600); //might take a while with lots of orders
294
        //get all Repeat orders
295
        $repeatOrders = RepeatOrder::get()->filter(['Status' => 'Active']);
296
        if ($repeatOrders) {
297
            foreach ($repeatOrders as $repeatOrder) {
298
                $repeatOrder->addAutomaticallyCreatedOrders();
299
            }
300
        }
301
    }
302
303
304
    /**
305
     * adds the orders that
306
     */
307
    public function addAutomaticallyCreatedOrders()
308
    {
309
        //current time + period is less than LastCreated and less then end
310
        $today = (strtotime(date('Y-m-d')));
311
        $firstOrderDate = $this->FirstOrderDate();
312
        if ($firstOrderDate) {
313
            $startTime = strtotime($firstOrderDate->format("Y-m-d"));
314
        } else {
315
            $this->Status = 'Pending';
0 ignored issues
show
Bug introduced by
The property Status does not seem to exist. Did you mean status_nice?

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...
316
            $this->write();
317
318
            return;
319
        }
320
321
        $endTime = strtotime($this->dbObject("End")->format("Y-m-d"));
322
        if ($today > $endTime) {
323
            $this->Status = 'Finished';
0 ignored issues
show
Bug introduced by
The property Status does not seem to exist. Did you mean status_nice?

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...
324
            $this->write();
325
326
            return;
327
        } elseif ($startTime < $today) {
328
            $a = $this->workOutSchedule();
329
            if (count($a)) {
330
                foreach ($a as $orderDateInteger => $orderDateLong) {
331
                    if (!$this->MemberID) {
0 ignored issues
show
Documentation introduced by
The property MemberID does not exist on object<RepeatOrder>. 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...
332
                        continue;
333
                    } elseif (!$orderDateInteger) {
334
                        continue;
335
                    } elseif ($orderDateInteger <= $today) {
336
                        $this->createOrderFromRepeatOrder($orderDateInteger);
337
                    }
338
                }
339
            }
340
        }
341
    }
342
343
344
345
    /**
346
     * creates order from repeatorder for a specific day.
347
     * IF it does not already exists.
348
     *
349
     */
350
    protected function createOrderFromRepeatOrder($orderDateInteger)
351
    {
352
        $filter = ["OrderDateInteger" => $orderDateInteger, "RepeatOrderID" => $this->ID];
353
        $newOrder = Order::get()
354
            ->filter($filter)
355
            ->first();
356
        if ($newOrder) {
357
            //do nothing
358
        } else {
359
            $originatingOrder = $this->OriginatingOrder();
0 ignored issues
show
Documentation Bug introduced by
The method OriginatingOrder does not exist on object<RepeatOrder>? Since you implemented __call, maybe consider adding a @method annotation.

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

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

class ParentClass {
    private $data = array();

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

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

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
360
            if($originatingOrder && $originatingOrder->exists()) {
361
                $shoppingCart = ShoppingCart::singleton();
362
                $newOrder = Order::create($filter);
363
                $newOrder->OrderDate = date("Y-m-d", $orderDateInteger);
364
                $newOrder->MemberID = $this->MemberID;
0 ignored issues
show
Documentation introduced by
The property MemberID does not exist on object<RepeatOrder>. 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...
365
                $newOrder->CustomerOrderNote = "Created as part of a repeating order.";
366
                $newOrder = $shoppingCart->CopyOrderOnly($originatingOrder, $newOrder);
367
                //load the order
368
                $newOrder->write();
369
                if ($this->OrderItems()) {
0 ignored issues
show
Documentation Bug introduced by
The method OrderItems does not exist on object<RepeatOrder>? Since you implemented __call, maybe consider adding a @method annotation.

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

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

class ParentClass {
    private $data = array();

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

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

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
370
                    $buyables = [];
371
                    foreach ($this->OrderItems() as $repeatOrderOrderItem) {
0 ignored issues
show
Documentation Bug introduced by
The method OrderItems does not exist on object<RepeatOrder>? Since you implemented __call, maybe consider adding a @method annotation.

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

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

class ParentClass {
    private $data = array();

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

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

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
372
                        $product = Product::get()->byID($repeatOrderOrderItem->ProductID);
373
                        if ($product) {
374
                            $buyables[] = $product;
375
                        }
376
                    }
377
                    if(count($buyables)) {
378
                        $newOrder = $shoppingCart->CopyBuyablesToNewOrder($newOrder, $buyables);
379
                    }
380
                }
381
            }
382
            //FINALISE!!!
383
            $newOrder->write();
384
            $newOrder->tryToFinaliseOrder();
385
        }
386
    }
387
388
389
/**
390
     * Create a RepeatOrder from a regular Order and its Order Items
391
     * @param Order $Order
392
     * @return RepeatOrder
393
     */
394
    public static function create_repeat_order_from_order(Order $Order)
395
    {
396
        $repeatOrder = RepeatOrder::create();
397
        $repeatOrder->Status = 'Pending';
0 ignored issues
show
Bug introduced by
The property Status does not seem to exist. Did you mean status_nice?

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...
398
        $repeatOrder->MemberID = $Order->MemberID;
0 ignored issues
show
Documentation introduced by
The property MemberID does not exist on object<RepeatOrder>. 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...
399
        $repeatOrder->write();
400
        $orderItems = $Order->Items();
401
        if ($orderItems) {
402
            foreach ($orderItems as $orderItem) {
403
                $buyable = $orderItem->Buyable();
404
                if ($buyable && $buyable instanceof Product) {
405
                    $repeatOrder_orderItem = RepeatOrder_OrderItem();
406
                    $repeatOrder_orderItem->OrderID = $repeatOrder->ID;
407
                    $repeatOrder_orderItem->ProductID = $orderItem->BuyableID;
408
                    $repeatOrder_orderItem->Quantity = $orderItem->Quantity;
409
                    $repeatOrder_orderItem->write();
410
                }
411
            }
412
        }
413
        $repeatOrder->write();
414
415
        return $repeatOrder;
416
    }
417
418
419
420
421
422
423
    /**
424
     * @return string
425
     */
426
    public function TablePaymentMethod()
427
    {
428
        $methods = Config::inst()->get('RepeatOrder', 'payment_methods');
429
        if (isset($methods[$this->PaymentMethod])) {
0 ignored issues
show
Documentation introduced by
The property PaymentMethod does not exist on object<RepeatOrder>. 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...
430
            return $methods[$this->PaymentMethod];
0 ignored issues
show
Documentation introduced by
The property PaymentMethod does not exist on object<RepeatOrder>. 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...
431
        }
432
        return '';
433
    }
434
435
    /**
436
     * @return string
437
     */
438
    public function TableStatus()
439
    {
440
        $status = Config::inst()->get('RepeatOrder', 'status_nice');
441
        if (isset($status[$this->Status])) {
0 ignored issues
show
Bug introduced by
The property Status does not seem to exist. Did you mean status_nice?

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...
442
            return $status[$this->Status];
0 ignored issues
show
Bug introduced by
The property Status does not seem to exist. Did you mean status_nice?

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...
443
        }
444
        return '';
445
    }
446
447
448
//==========================================================================================================================================================
449
450
451
452
    public function getCMSFields()
453
    {
454
        $fields = parent::getCMSFields();
455
456
        $firstCreated = "can not be computed";
457
        if ($firstCreatedObj = $this->FirstOrderDate()) {
458
            $firstCreated = $firstCreatedObj->Long();
459
        }
460
        $lastCreated = "no orders have been placed yet";
461
        if ($lastCreatedObj = $this->LastOrderDate()) {
462
            $lastCreated = $lastCreatedObj->Long();
463
        }
464
        $finalCreated = "can not be computed";
465
        if ($finalCreatedObj = $this->FinalOrderDate()) {
466
            $finalCreated = $finalCreatedObj->Long();
467
        }
468
        if ($this->Status == "Active") {
0 ignored issues
show
Bug introduced by
The property Status does not seem to exist. Did you mean status_nice?

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...
469
            $nextCreated = "can not be computed";
470
            if ($nextCreatedObj = $this->NextOrderDate()) {
471
                $nextCreated = $nextCreatedObj->Long();
472
            }
473
        } else {
474
            $nextCreated = "Repeat Order not active - no next date is available if the Repeat Order is not active.";
475
        }
476
477
478
        $fields->replaceField(
479
            'PaymentMethod',
480
            ListboxField::create(
481
                'PaymentMethod',
482
                'Payment Method',
483
                Config::inst()->get('RepeatOrder', 'payment_methods'),
484
                null,
485
                count(Config::inst()->get('RepeatOrder', 'payment_methods'))
486
            )
487
        );
488
        $fields->replaceField(
489
            'Period',
490
            ListboxField::create(
491
                'Period',
492
                'Period',
493
                Config::inst()->get('RepeatOrder', 'period_fields'),
494
                null,
495
                count(Config::inst()->get('RepeatOrder', 'period_fields'))
496
            )
497
        );
498
        $fields->replaceField(
499
            'Status',
500
            DropdownField::create(
501
                'Status',
502
                'Status',
503
                Config::inst()->get('RepeatOrder', 'status_nice')
504
            )
505
        );
506
507
        $fields->addFieldsToTab(
508
            'Root.Details',
509
            [
510
                LiteralField::create(
511
                    'Readonly[ID]',
512
                    '<p>Repeat Order Number: '.$this->ID.'</p>'
513
                ),
514
                LiteralField::create(
515
                    'Readonly[Member]',
516
<<<HTML
517
<div class="field readonly " id="Readonly[Member]">
518
    <label for="Form_EditForm_Readonly-Member" class="left">Member</label>
519
    <div class="middleColumn">
520
        <span class="readonly" id="Form_EditForm_Readonly-Member">{$this->Member()->getTitle()} ({$this->Member()->Email}) </span>
0 ignored issues
show
Documentation Bug introduced by
The method Member does not exist on object<RepeatOrder>? Since you implemented __call, maybe consider adding a @method annotation.

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

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

class ParentClass {
    private $data = array();

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

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

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
521
        <input type="hidden" value="{$this->Member()->getTitle()} ({$this->Member()->Email})" name="Readonly[Member]"/>
0 ignored issues
show
Documentation Bug introduced by
The method Member does not exist on object<RepeatOrder>? Since you implemented __call, maybe consider adding a @method annotation.

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

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

class ParentClass {
    private $data = array();

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

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

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
522
    </div>
523
</div>
524
HTML
525
                ),
526
            ]
527
        );
528
        $fields->addFieldsToTab(
529
            'Root.Orders',
530
            [
531
                ReadonlyField::create("DeliveryScheduleFormatted", "Delivery Schedule", $this->DeliverySchedule()),
532
                ReadonlyField::create("FirstCreatedFormatted", "First Order", $firstCreated),
533
                ReadonlyField::create("LastCreatedFormatted", "Last Order", $lastCreated),
534
                ReadonlyField::create("NextCreatedFormatted", "Next Order", $nextCreated),
535
                ReadonlyField::create("FinalCreatedFormatted", "Final Order", $finalCreated)
536
            ]
537
        );
538
539
540
        return $fields;
541
    }
542
543
544
    //============
545
    //============
546
    //============
547
548
    public function onBeforeWrite()
549
    {
550
        parent::onBeforeWrite();
551
        $this->ItemsForSearchPurposes = $this->OrderItemList();
0 ignored issues
show
Documentation introduced by
The property ItemsForSearchPurposes does not exist on object<RepeatOrder>. 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...
552
    }
553
554
555
    //============
556
    //============
557
    //============
558
559
    /**
560
     * List of products
561
     *
562
     * @return string
563
     */
564
    public function OrderItemList()
565
    {
566
        return $this->getOrderItemList();
567
    }
568
    /**
569
     *
570
     * @return string
571
     */
572
    public function getOrderItemList()
573
    {
574
        $a = [];
575
        if ($list = $this->OrderItems()) {
0 ignored issues
show
Documentation Bug introduced by
The method OrderItems does not exist on object<RepeatOrder>? Since you implemented __call, maybe consider adding a @method annotation.

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

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

class ParentClass {
    private $data = array();

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

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

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
576
            foreach ($list as $item) {
577
                $a[] = $item->Quantity . " x " . $item->Title();
578
            }
579
        }
580
        if (!count($a)) {
581
            return "No products listed";
582
        }
583
        if (count($a) == 1) {
584
            return "Product: ".implode(", ", $a).".";
585
        }
586
        return "Products: ".implode(", ", $a).".";
587
    }
588
589
//===========================================================================================================================================================================================
590
591
    /**
592
     * The first order date
593
     *
594
     * @return Date|null
595
     */
596
    public function FirstOrderDate()
597
    {
598
        return $this->getFirstOrderDate();
599
    }
600
601 View Code Duplication
    public function getFirstOrderDate()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
602
    {
603
        $a = $this->workOutSchedule();
604
        if (count($a)) {
605
            foreach ($a as $orderDateInteger => $orderDateLong) {
606
                return Date::create($className = "Date", $value = Date("Y-m-d", $orderDateInteger));
607
            }
608
        }
609
    }
610
611
    /**
612
     * Last date that an order was placed
613
     *
614
     * @return Date|null
615
     */
616
    public function LastOrderDate()
617
    {
618
        return $this->getLastOrderDate();
619
    }
620
621
    /**
622
     * Last date that an order was placed
623
     *
624
     * @return Date|null
625
     */
626
    public function getLastOrderDate()
627
    {
628
        $a = $this->workOutSchedule();
629
        $today = strtotime(Date("Y-m-d"));
630
        $i = 0;
631
        if (count($a)) {
632
            foreach ($a as $orderDateInteger => $orderDateLong) {
633
                if ($orderDateInteger > $today && $i > 0 && $previousoOrderDateInteger < $today) {
634
                    return Date::create($className = "Date", $value = Date("Y-m-d", $previousoOrderDateInteger));
0 ignored issues
show
Bug introduced by
The variable $previousoOrderDateInteger does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
635
                }
636
                $previousoOrderDateInteger = $orderDateInteger;
637
                $i++;
638
            }
639
        }
640
    }
641
642
    /**
643
     * today's' date for the order - if ANY!
644
     *
645
     * @return Date|null
646
     */
647
    public function TodaysOrderDate()
648
    {
649
        return $this->getTodaysOrderDate();
650
    }
651
652
    /**
653
     * today's' date for the order - if ANY!
654
     *
655
     * @return Date|null
656
     */
657 View Code Duplication
    public function getTodaysOrderDate()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
658
    {
659
        $a = $this->workOutSchedule();
660
        $today = strtotime(Date("Y-m-d"));
661
        if (count($a)) {
662
            foreach ($a as $orderDateInteger => $orderDateLong) {
663
                if ($orderDateInteger == $today) {
664
                    return Date::create($className = "Date", $value = Date("Y-m-d", $orderDateInteger));
665
                }
666
            }
667
        }
668
    }
669
670
    /**
671
     * Next date (from the viewpoint of today)
672
     *
673
     * @return Date|null
674
     */
675
    public function NextOrderDate()
676
    {
677
        return $this->getNextOrderDate();
678
    }
679
680 View Code Duplication
    public function getNextOrderDate()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
681
    {
682
        $a = $this->workOutSchedule();
683
        $today = strtotime(Date("Y-m-d"));
684
        if (count($a)) {
685
            foreach ($a as $orderDateInteger => $orderDateLong) {
686
                if ($orderDateInteger > $today) {
687
                    return Date::create($className = "Date", $value = Date("Y-m-d", $orderDateInteger));
688
                }
689
            }
690
        }
691
    }
692
693
694
    /**
695
     * Last Delivery Date
696
     *
697
     * @return Date|null
698
     */
699
    public function FinalOrderDate()
700
    {
701
        return $this->getFinalOrderDate();
702
    }
703
704 View Code Duplication
    public function getFinalOrderDate()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
705
    {
706
        $a = $this->workOutSchedule();
707
        if (count($a)) {
708
            foreach ($a as $orderDateInteger => $orderDateLong) {
709
                //do nothing wait for last one...
710
            }
711
            if ($orderDateInteger) {
712
                return Date::create($className = "Date", $value = Date("Y-m-d", $orderDateInteger));
0 ignored issues
show
Bug introduced by
The variable $orderDateInteger seems to be defined by a foreach iteration on line 708. Are you sure the iterator is never empty, otherwise this variable is not defined?

It seems like you are relying on a variable being defined by an iteration:

foreach ($a as $b) {
}

// $b is defined here only if $a has elements, for example if $a is array()
// then $b would not be defined here. To avoid that, we recommend to set a
// default value for $b.


// Better
$b = 0; // or whatever default makes sense in your context
foreach ($a as $b) {
}

// $b is now guaranteed to be defined here.
Loading history...
713
            }
714
        }
715
    }
716
717
    /**
718
     * List of delivery dates
719
     *
720
     * @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...
721
     */
722
    public function DeliverySchedule()
723
    {
724
        return $this->getDeliverySchedule();
725
    }
726
727
    public function getDeliverySchedule()
728
    {
729
        $a = $this->workOutSchedule();
730
        if (count($a)) {
731
            return implode("; ", $a);
732
        }
733
    }
734
735
    /**
736
     * @var Array
737
     */
738
    private static $_schedule = [];
739
740
    /**
741
     * Work out the delivery schedule
742
     * @return Array
743
     */
744
    protected function workOutSchedule()
745
    {
746
        //caching value for quicker response
747
        if (!isset(self::$_schedule[$this->ID])) {
748
            $a = [];
749
            if ($this->Period && $this->End && $this->Start &&  $this->Status == "Active") {
0 ignored issues
show
Bug introduced by
The property Period does not seem to exist. Did you mean period_fields?

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...
Documentation introduced by
The property End does not exist on object<RepeatOrder>. Since you implemented __get, maybe consider adding a @property annotation.

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

<?php

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

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

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

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

}

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

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

See also the PhpDoc documentation for @property.

Loading history...
Documentation introduced by
The property Start does not exist on object<RepeatOrder>. 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 Status does not seem to exist. Did you mean status_nice?

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...
750
                $startTime = strtotime($this->Start);
0 ignored issues
show
Documentation introduced by
The property Start does not exist on object<RepeatOrder>. 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...
751
                $firstTime = $startTime;
752
                $endTime = strtotime($this->End);
0 ignored issues
show
Documentation introduced by
The property End does not exist on object<RepeatOrder>. 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...
753
                $nextTime = $firstTime;
754
                if ($firstTime && $nextTime && $endTime) {
755
                    if ($firstTime < $endTime) {
756
                        $i = 0;
757
                        while ($nextTime <= $endTime && $i < 999) {
758
                            $a[$nextTime] = Date("j F Y", $nextTime);
759
                            $nextTime = strtotime("+ ".$this->Period, $nextTime);
0 ignored issues
show
Bug introduced by
The property Period does not seem to exist. Did you mean period_fields?

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...
760
                            $i++;
761
                        }
762
                    }
763
                }
764
            }
765
            self::$_schedule[$this->ID] = $a;
766
        }
767
        return self::$_schedule[$this->ID];
768
    }
769
770
771
    /**
772
     * Are there any orders scheduled for the future
773
     * @return bool
774
     */
775
    public function HasFutureOrders()
776
    {
777
        return $this->getHasFutureOrders();
778
    }
779
780
    /**
781
     * Are there any orders scheduled for the future
782
     * @return bool
783
     */
784
    public function getHasFutureOrders()
785
    {
786
        if ($this->NextOrderDate()) {
0 ignored issues
show
Unused Code introduced by
This if statement, and the following return statement can be replaced with return (bool) $this->NextOrderDate();.
Loading history...
787
            return true;
788
        }
789
790
        return false;
791
    }
792
793
    /**
794
     * Are there any orders scheduled for today
795
     * @return bool
796
     */
797
    public function HasAnOrderToday()
798
    {
799
        if ($this->TodaysOrderDate()) {
0 ignored issues
show
Unused Code introduced by
This if statement, and the following return statement can be replaced with return (bool) $this->TodaysOrderDate();.
Loading history...
800
            return true;
801
        }
802
        return false;
803
    }
804
805
//===========================================================================================================================================================================================
806
807
    public function canView($member = null)
808
    {
809
        $member = Member::currentUser();
810
        if ($member) {
811
            if ($member->IsShopAdmin()) {
812
                return true;
813
            }
814
            if ($this->MemberID == $member->ID) {
0 ignored issues
show
Documentation introduced by
The property MemberID does not exist on object<RepeatOrder>. 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...
815
                return true;
816
            }
817
        }
818
        return false;
819
    }
820
821 View Code Duplication
    public function canEdit($member = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
822
    {
823
        if (in_array($this->Status, ['Pending', 'Active'])) {
0 ignored issues
show
Bug introduced by
The property Status does not seem to exist. Did you mean status_nice?

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...
824
            return $this->canView($member);
825
        } else {
826
            return false;
827
        }
828
    }
829
830 View Code Duplication
    public function canDelete($member = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
831
    {
832
        if (in_array($this->Status, ['Pending'])) {
0 ignored issues
show
Bug introduced by
The property Status does not seem to exist. Did you mean status_nice?

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...
833
834
            return $this->canView($member);
835
        } else {
836
837
            return false;
838
        }
839
    }
840
}
841