Completed
Push — master ( c22f60...21d98e )
by Nicolaas
01:15
created

RepeatOrder::HasAnOrderToday()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 6
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 0
1
<?php
2
3
/**
4
 * @author michael@ sunnysideup . co . nz
5
 */
6
7
class RepeatOrder extends DataObject
8
{
9
10
11
    /**
12
     * Minimum of days in the future that the order is lodged.
13
     * @var int
14
     */
15
    private static $minimum_days_in_the_future = 1;
16
17
    /**
18
     * Standard SS variable
19
     */
20
    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...
21
        'Status' => "Enum('Pending, Active, MemberCancelled, AdminCancelled, Finished', 'Pending')",
22
        //dates
23
        'Start' => 'Date',
24
        'End' => 'Date',
25
        'Period' => 'Varchar',
26
        'DeliveryDay' => 'Text',
27
        //payment
28
        'PaymentMethod' => 'Varchar',
29
        "CreditCardOnFile" => "Boolean",
30
        "PaymentNote" => "Text",
31
        //computed values and notes
32
        'ItemsForSearchPurposes' => 'Text', //FOR SEARCH PURPOSES ONLY!
33
        'Notes' => 'Text'
34
    ];
35
36
    /**
37
     * Standard SS variable
38
     */
39
    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...
40
        'Member' => 'Member',
41
        'OriginatingOrder' => 'Order'
42
    ];
43
44
45
    /**
46
     * Standard SS variable
47
     */
48
    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...
49
        'OrderItems' => 'RepeatOrder_OrderItem', //products & quanitites
50
        'Orders' => 'Order'
51
    ];
52
53
    /**
54
     * Standard SS variable.
55
     */
56
    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...
57
        "Status" => true
58
    ];
59
60
    /**
61
     * Standard SS variable
62
     */
63
    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...
64
        "OrderItemList" => "Text",
65
        "FirstOrderDate" => "Date",
66
        "LastOrderDate" => "Date",
67
        "TodaysOrderDate" => "Date",
68
        "NextOrderDate" => "Date",
69
        "FinalOrderDate" => "Date",
70
        "DeliverySchedule" => "Text"
71
    ];
72
73
74
    /**
75
     * Standard SS variable
76
     */
77
    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...
78
        "ItemsForSearchPurposes" => "PartialMatchFilter",
79
        "Period" => "ExactMatchFilter",
80
        "DeliveryDay" => "ExactMatchFilter",
81
        "Status" => "ExactMatchFilter"
82
    ];
83
84
    /**
85
     * Standard SS variable
86
     */
87
    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...
88
        'ID' => 'Repeat Order ID',
89
        'Member.Surname' => 'Surname',
90
        'Member.Email' => 'Email',
91
        'OrderItemList' => 'Order Item List',
92
        'Start' => 'Start',
93
        'End' => 'End',
94
        'Period' => 'Period',
95
        'DeliveryDay' => 'Delivery Day',
96
        'Status' => 'Status'
97
    ];
98
99
    /**
100
     * Standard SS variable
101
     */
102
    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...
103
104
105
    /**
106
     * Dropdown options for Period
107
     * @var array 'strtotime period' > 'nice name'
108
     */
109
    private static $period_fields = [
110
        '1 day' => 'Daily',
111
        '1 week' => 'Weekly',
112
        '2 weeks' => 'Fornightly',
113
        '1 month' => 'Monthly'
114
    ];
115
116
    public static function default_period_key()
117
    {
118
        if ($a = Config::inst()->get('RepeatOrder', 'period_fields')) {
119
            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...
120
                return $k;
121
            }
122
        }
123
    }
124
125
    /**
126
     * @var Array
127
     */
128
    private static $schedule = [];
129
130
131
    /**
132
     * @array
133
     */
134
    private static $status_nice = array(
135
        'Pending' => 'Pending',
136
        'Active' => 'Active',
137
        'MemberCancelled' => 'Pending Cancellation',
138
        'AdminCancelled' => 'Cancelled',
139
        'Finished' => 'Finished',
140
    );
141
142
143
    /**
144
     * @var array
145
     */
146
    protected static $payment_methods = array(
147
        'DirectCreditPayment' => 'Direct Credit (payment into bank account)'
148
    );
149
    public static function set_payment_methods($a)
150
    {
151
        self::$payment_methods = $a;
152
    }
153
154
    public static function default_payment_method_key()
155
    {
156
        $a = Config::inst()->get('RepeatOrder', 'payment_methods');
157
        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...
158
            return $k;
159
        }
160
    }
161
162
    /**
163
     * Can it be edited, alias for canEdit
164
     * @return Boolean
165
     */
166
    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...
167
    {
168
        return $this->canEdit();
169
    }
170
171
    /**
172
     * Link for viewing
173
     * @return String
174
     */
175
    public function Link()
176
    {
177
        return RepeatOrdersPage::get_repeat_order_link('view', $this->ID);
178
    }
179
180
    /**
181
     * Link for editing
182
     * @return String
183
     */
184
    public function ModifyLink()
185
    {
186
        return RepeatOrdersPage::get_repeat_order_link('modify', $this->ID);
187
    }
188
189
190
    /**
191
     * Link for cancelling
192
     * @return String
193
     */
194
    public function CancelLink()
195
    {
196
        return RepeatOrdersPage::get_repeat_order_link('cancel', $this->ID);
197
    }
198
199
    /**
200
     * Link for end of view / edit / cancel session
201
     * @return String
202
     */
203
    public function DoneLink()
204
    {
205
        $page = DataObject::get_one("RepeatOrdersPage");
206
        if (!$page) {
207
            $page = DataObject::get_one("CheckoutPage");
208
            if (!$page) {
209
                $page = DataObject::get_one("Page");
210
            }
211
        }
212
        return $page->Link();
213
    }
214
215
    /**
216
     * returns a list of actual orders that have been created from this repeat order.
217
     * @return DOS | Null
0 ignored issues
show
Documentation introduced by
Should the return type not be ArrayList|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...
218
     */
219
    public function AutomaticallyCreatedOrders()
220
    {
221
        $orders = Order::get()->filter(["RepeatOrderID" => $this->ID])->sort(["OrderDate" => "ASC"]);
222
        $dos = ArrayList::create();
223
        if ($orders) {
224
            foreach ($orders as $order) {
225
                $dos->push($order);
226
            }
227
        }
228
        if ($dos && $dos->count()) {
229
            return $dos;
230
        }
231
    }
232
233
//====================================================================================================================================================================================
234
235
    /**
236
     * Create due draft orders
237
     */
238
    public static function create_automatically_created_orders()
239
    {
240
        set_time_limit(0); //might take a while with lots of orders
241
        //get all Repeat orders
242
        $repeatOrders = RepeatOrder::get()->filter(['Status' => 'Active']);
243
        if ($repeatOrders) {
244
            foreach ($repeatOrders as $repeatOrder) {
245
                $repeatOrder->addAutomaticallyCreatedOrders();
246
            }
247
        }
248
    }
249
250
251
    /**
252
     * adds the orders that
253
     */
254
    public function addAutomaticallyCreatedOrders()
255
    {
256
        //current time + period is less than LastCreated and less then end
257
        $today = (strtotime(date('Y-m-d')));
258
        $firstOrderDate = $this->FirstOrderDate();
259
        if ($firstOrderDate) {
260
            $startTime = strtotime($firstOrderDate->format("Y-m-d"));
261
        }
262
        if (!$firstOrderDate) {
263
            $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...
264
            $this->write();
265
            return;
266
        } else {
267
            $endTime = strtotime($this->dbObject("End")->format("Y-m-d"));
268
            if ($today > $endTime) {
269
                $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...
270
                $this->write();
271
                return;
272
            } elseif ($startTime < $today) {
0 ignored issues
show
Bug introduced by
The variable $startTime 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...
273
                $a = $this->workOutSchedule();
274
                if (count($a)) {
275
                    foreach ($a as $orderDateInteger => $orderDateLong) {
276
                        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...
277
                            USER_ERROR("Can not create Order without member linked in RepeatOrder #".$this->ID, E_USER_ERROR);
278
                        } elseif (!$orderDateInteger) {
279
                            USER_ERROR("Can not create Order without date for in RepeatOrder #".$this->ID, E_USER_ERROR);
280
                        } elseif ($orderDateInteger <= $today) {
281
                            $this->createOrderFromRepeatOrder($orderDateInteger);
282
                        }
283
                    }
284
                }
285
            }
286
        }
287
    }
288
289
290
    /**
291
     * creates order from repeatorder for a specific day.
292
     * IF it does not already exists.
293
     *
294
     */
295
    protected function createOrderFromRepeatOrder($orderDateInteger)
296
    {
297
        $order = Order::get()
298
            ->filter(["OrderDateInteger" => $orderDateInteger, "RepeatOrderID" => $this->ID])
299
            ->first();
300
        if ($order) {
301
            //do nothing
302
        } else {
303
            $order = Order::create();
304
            $order->OrderDate = date("Y-m-d", $orderDateInteger);
305
            $order->OrderDateInteger = $orderDateInteger;
306
            $order->RepeatOrderID = $this->ID;
307
            $order->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...
308
            $order->CustomerOrderNote = "Created as part of a repeating order.";
309
            $order->write();
310
            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...
311
                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...
312
                    $product = Product::get()->byID($repeatOrderOrderItem->ProductID);
313
                    if ($product) {
314
                        //START CHECK AVAILABILITY
315
                        // if (class_exists("ProductStockCalculatedQuantity")) {
316
                        //     $numberAvailable = ProductStockCalculatedQuantity::get_quantity_by_product_id($product->ID);
317
                        //     if ($numberAvailable < $repeatOrderOrderItem->Quantity) {
318
                        //         $alternatives = $repeatOrderOrderItem->AlternativesPerProduct();
319
                        //         $product = null;
320
                        //         if ($dos) {
321
                        //             foreach ($alternatives as $alternative) {
322
                        //                 $stillLookingForAlternative = true;
323
                        //                 $numberAvailable = ProductStockCalculatedQuantity::get_quantity_by_product_id($alternative->ID);
324
                        //                 if ($numberAvailable > $repeatOrderOrderItem->Quantity && $stillLookingForAlternative) {
325
                        //                     $stillLookingForAlternative = false;
326
                        //                     $product = $alternative;
327
                        //                 }
328
                        //             }
329
                        //         }
330
                        //     }
331
                        // }
332
                        //END CHECK AVAILABILITY
333
                        if ($product) {
334
                            $newProductOrderItem = Product_OrderItem::create();
335
                            $newProductOrderItem->addBuyableToOrderItem($product, $repeatOrderOrderItem->Quantity);
336
                            $newProductOrderItem->OrderID = $order->ID;
337
                            $newProductOrderItem->write();
338
                        }
339
                    } else {
340
                        USER_ERROR("Product does not exist", E_USER_WARNING);
341
                    }
342
                }
343
            } else {
344
                USER_ERROR("There are no order items", E_USER_WARNING);
345
            }
346
            //FINALISE!!!
347
            $order->write();
348
            $order->tryToFinaliseOrder();
349
        }
350
    }
351
352
353
/**
354
     * Create a RepeatOrder from a regular Order and its Order Items
355
     * @param Order $Order
356
     * @return RepeatOrder
357
     */
358
    public static function create_repeat_order_from_order(Order $Order)
359
    {
360
        $repeatOrder = RepeatOrder();
361
        $repeatOrder->Status = 'Pending';
362
        $repeatOrder->MemberID = $Order->MemberID;
363
        $repeatOrder->write();
364
        $orderItems = $Order->Items();
365
        if ($orderItems) {
366
            foreach ($orderItems as $orderItem) {
367
                $buyable = $orderItem->Buyable();
368
                if ($buyable && $buyable instanceof Product) {
369
                    $repeatOrder_orderItem = RepeatOrder_OrderItem();
370
                    $repeatOrder_orderItem->OrderID = $repeatOrder->ID;
371
                    $repeatOrder_orderItem->ProductID = $orderItem->BuyableID;
372
                    $repeatOrder_orderItem->Quantity = $orderItem->Quantity;
373
                    $repeatOrder_orderItem->write();
374
                }
375
            }
376
        }
377
        $repeatOrder->write();
378
        return $repeatOrder;
379
    }
380
381
382
383
384
385
//================================================================================================================================================================================
386
387
    /**
388
     * @return string
389
     */
390
    public function TableDeliveryDay()
391
    {
392
        return $this->DeliveryDay;
0 ignored issues
show
Documentation introduced by
The property DeliveryDay 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...
393
    }
394
395
    /**
396
     * @return string
397
     */
398
    public function TablePaymentMethod()
399
    {
400
        if (isset(self::$payment_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...
401
            return self::$payment_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...
402
        }
403
        return "";
404
    }
405
406
    /**
407
     * @return string
408
     */
409
    public function TableStatus()
410
    {
411
        return self::$status_nice[$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...
412
    }
413
414
415
//==========================================================================================================================================================
416
417
418
419
    /**
420
     * CMS Fields for ModelAdmin, use different fields for adding/editing
421
     * @see sapphire/core/model/DataObject#getCMSFields($params)
422
     */
423
    public function getCMSFields()
424
    {
425
        if ($this->exists()) {
426
            $this->addAutomaticallyCreatedOrders();
427
            return $this->getCMSFields_edit();
428
        } else {
429
            return $this->getCMSFields_add();
430
        }
431
    }
432
433
    /**
434
     * CMS Fields to adding via ModelAdmin
435
     * @return FieldList
436
     */
437
    public function getCMSFields_add()
438
    {
439
        $fields = FieldList::create(
440
            TabSet::create('Root',
441
                Tab::create('Main',
442
                    ListboxField::create(
443
                        'PaymentMethod',
444
                        'Payment Method',
445
                        Config::inst()->get('RepeatOrder', 'payment_methods'),
446
                        null,
447
                        count(Config::inst()->get('RepeatOrder', 'payment_methods'))
448
                     ),
449
                    DateField::create('Start', 'Start'),
450
                    DateField::create('End', 'End (Optional)'),
451
                    ListboxField::create(
452
                        'Period',
453
                        'Period',
454
                        Config::inst()->get('RepeatOrder', 'period_fields'),
455
                        null,
456
                        count(Config::inst()->get('RepeatOrder', 'period_fields'))
457
                    ),
458
                    TextareaField::create('Notes', 'Notes')
459
                )
460
            )
461
        );
462
        return $fields;
463
    }
464
465
    /**
466
     * CMS Fields to adding via ModelAdmin
467
     * @return FieldList
468
     */
469
    public function getCMSFields_edit()
470
    {
471
        $firstCreated = "can not be computed";
472
        if ($firstCreatedObj = $this->FirstOrderDate()) {
473
            $firstCreated = $firstCreatedObj->Long();
474
        }
475
        $lastCreated = "no orders have been placed yet";
476
        if ($lastCreatedObj = $this->LastOrderDate()) {
477
            $lastCreated = $lastCreatedObj->Long();
478
        }
479
        $finalCreated = "can not be computed";
480
        if ($finalCreatedObj = $this->FinalOrderDate()) {
481
            $finalCreated = $finalCreatedObj->Long();
482
        }
483
        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...
484
            $nextCreated = "can not be computed";
485
            if ($nextCreatedObj = $this->NextOrderDate()) {
486
                $nextCreated = $nextCreatedObj->Long();
487
            }
488
        } else {
489
            $nextCreated = "Repeat Order not active - no next date is available if the Repeat Order is not active.";
490
        }
491
        if (!$this->DeliveryDay) {
0 ignored issues
show
Documentation introduced by
The property DeliveryDay 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...
492
            $firstCreated = $finalCreated = $lastCreated = $nextCreated = "Please select a delivery day first.";
493
        }
494
        $fields = FieldList::create(
495
            TabSet::create(
496
                'Root',
497
                Tab::create(
498
                    'Main',
499
                    LiteralField::create(
500
                        'Readonly[ID]',
501
                        '<p>Repeat Order Number: '.$this->ID.'</p>'
502
                    ),
503
                    LiteralField::create(
504
                        'Readonly[Member]',
505
<<<HTML
506
    <div class="field readonly " id="Readonly[Member]">
507
        <label for="Form_EditForm_Readonly-Member" class="left">Member</label>
508
        <div class="middleColumn">
509
            <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...
510
            <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...
511
        </div>
512
    </div>
513
HTML
514
                    ),
515
                    DropdownField::create('Status', 'Status', self::$status_nice),
516
                    DateField::create('Start', 'Start'),
517
                    DateField::create('End', 'End (Optional)'),
518
                    ListboxField::create(
519
                        'Period',
520
                        'Period',
521
                        Config::inst()->get('RepeatOrder', 'period_fields'),
522
                        null,
523
                        count(Config::inst()->get('RepeatOrder', 'period_fields'))
524
                    ),
525
                    TextareaField::create('Notes', 'Notes')
526
                ),
527
                Tab::create(
528
                    'Products',
529
                    $this->getCMSProductsTable()
530
                ),
531
                Tab::create(
532
                    'Orders',
533
                    $this->getCMSPreviousOrders(),
534
                    ReadonlyField::create("DeliveryScheduleFormatted", "Delivery Schedule", $this->DeliverySchedule()),
535
                    ReadonlyField::create("FirstCreatedFormatted", "First Order", $firstCreated),
536
                    ReadonlyField::create("LastCreatedFormatted", "Last Order", $lastCreated),
537
                    ReadonlyField::create("NextCreatedFormatted", "Next Order", $nextCreated),
538
                    ReadonlyField::create("FinalCreatedFormatted", "Final Order", $finalCreated)
539
                ),
540
                Tab::create(
541
                    'Payment',
542
                    CheckboxField::create("CreditCardOnFile", "Credit Card on File"),
543
                    ListboxField::create(
544
                        'PaymentMethod',
545
                        'Payment Method',
546
                        Config::inst()->get('RepeatOrder', 'payment_methods'),
547
                        null,
548
                        count(Config::inst()->get('RepeatOrder', 'payment_methods'))
549
                    ),
550
                    TextareaField::create('PaymentNote', 'Payment Note')
551
                )
552
            )
553
        );
554
        return $fields;
555
    }
556
557
    /**
558
     * CMS Fields for Popup
559
     * @return FieldList
560
     */
561
    public function getCMSFields_forPopup()
562
    {
563
        $fields = FieldList::create(
564
            TabSet::create('Root',
565
                Tab::create('Main',
566
                    ReadonlyField::create('Readonly[Member]', 'Member', $this->Member()->getTitle().' ('.$this->Member()->Email.')'),
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...
567
                    DropdownField::create('Status', 'Status', self::$status_nice),
568
                    ListboxField::create(
569
                        'PaymentMethod',
570
                        'Payment Method',
571
                        Config::inst()->get('RepeatOrder', 'payment_methods'),
572
                        null,
573
                        count(Config::inst()->get('RepeatOrder', 'payment_methods'))
574
                    ),
575
                    DateField::create('Start', 'Start'),
576
                    DateField::create('End', 'End (Optional)'),
577
                    DropdownField::create(
578
                        'Period',
579
                        'Period',
580
                        Config::inst()->get('RepeatOrder', 'period_fields')
581
                    ),
582
                    TextField::create('DeliveryDay', 'Delivery Day'),
583
                    TextareaField::create('Notes', 'Notes')
584
                ),
585
                Tab::create('Products',
586
                    $this->getCMSProductsTable()
587
                )
588
            )
589
        );
590
        return $fields;
591
    }
592
593
594
595
    /**
596
     * Get previous actual order table
597
     * @return ComplexTableField
598
     */
599
    public function getCMSPreviousOrders()
600
    {
601
        $table = ComplexTableField::create(
602
            $controller = $this,
603
            $name = "PreviousOrders",
604
            $sourceClass = "Order",
605
            $fieldList = array(
606
                "Title" => "Summary",
607
                "Total" => "Total",
608
                "CustomerStatus" => "Status",
609
                "OrderDate" => "Planned Date",
610
                "RetrieveLink" => "RetrieveLink"
611
            ),
612
            $detailFormFields = null,
613
            $sourceFilter = "RepeatOrderID = ".$this->ID,
614
            $sourceSort = "OrderDateInteger DESC",
615
            $sourceJoin = ""
616
        );
617
        $table->setFieldCasting(array(
618
            'OrderDate' => 'Date->Long',
619
            'Total' => 'Currency->Nice'
620
        ));
621
        $table->setShowPagination(false);
622
        $table->setAddTitle('Previous Orders');
623
        $table->setPermissions(array("export", "show"));
624
        return $table;
625
    }
626
627
    /**
628
     * Get products table
629
     * @return ComplexTableField
630
     */
631
    public function getCMSProductsTable()
632
    {
633
        $table = ComplexTableField::create(
634
            $this,
635
            'OrderItems',
636
            'RepeatOrder_OrderItem',
637
            array(
638
                'Product.Title' => 'Title',
639
                'Quantity' => 'Qty',
640
            )
641
        );
642
643
        $table->setShowPagination(false);
644
        $table->setAddTitle('Product');
645
        $table->setPermissions(array('add', 'edit', 'delete'));
646
647
        return $table;
648
    }
649
650
651
652
653
//========================================================================================================================================================================================================================================================================
654
655
    public function onBeforeWrite()
656
    {
657
        parent::onBeforeWrite();
658
        $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...
659
    }
660
661
//===========================================================================================================================================================================================
662
663
    /**
664
     * List of products
665
     *
666
     * @return String
667
     */
668
    public function OrderItemList()
669
    {
670
        return $this->getOrderItemList();
671
    }
672
    public function getOrderItemList()
673
    {
674
        $a = [];
675
        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...
676
            foreach ($list as $item) {
677
                $a[] = $item->Quantity . " x " . $item->Title();
678
            }
679
        }
680
        if (!count($a)) {
681
            return "No products listed";
682
        }
683
        if (count($a) == 1) {
684
            return "Product: ".implode(", ", $a).".";
685
        }
686
        return "Products: ".implode(", ", $a).".";
687
    }
688
689
//===========================================================================================================================================================================================
690
691
    /**
692
     * The first order date
693
     *
694
     * @return Date | Null
0 ignored issues
show
Documentation introduced by
Should the return type not be Date|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...
695
     */
696
    public function FirstOrderDate()
697
    {
698
        return $this->getFirstOrderDate();
699
    }
700 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...
701
    {
702
        $a = $this->workOutSchedule();
703
        if (count($a)) {
704
            foreach ($a as $orderDateInteger => $orderDateLong) {
705
                return Date::create($className = "Date", $value = Date("Y-m-d", $orderDateInteger));
706
            }
707
        }
708
    }
709
710
    /**
711
     * Last date that an order was placed
712
     *
713
     * @return Date | Null
0 ignored issues
show
Documentation introduced by
Should the return type not be Date|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...
714
     */
715
    public function LastOrderDate()
716
    {
717
        return $this->getLastOrderDate();
718
    }
719
    public function getLastOrderDate()
720
    {
721
        $a = $this->workOutSchedule();
722
        $today = strtotime(Date("Y-m-d"));
723
        $i = 0;
724
        if (count($a)) {
725
            foreach ($a as $orderDateInteger => $orderDateLong) {
726
                if ($orderDateInteger > $today && $i > 0 && $previousoOrderDateInteger < $today) {
727
                    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...
728
                }
729
                $previousoOrderDateInteger = $orderDateInteger;
730
                $i++;
731
            }
732
        }
733
    }
734
735
    /**
736
     * today's' date for the order - if ANY!
737
     *
738
     * @return Date | Null
0 ignored issues
show
Documentation introduced by
Should the return type not be Date|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...
739
     */
740
    public function TodaysOrderDate()
741
    {
742
        return $this->getTodaysOrderDate();
743
    }
744 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...
745
    {
746
        $a = $this->workOutSchedule();
747
        $today = strtotime(Date("Y-m-d"));
748
        if (count($a)) {
749
            foreach ($a as $orderDateInteger => $orderDateLong) {
750
                if ($orderDateInteger == $today) {
751
                    return Date::create($className = "Date", $value = Date("Y-m-d", $orderDateInteger));
752
                }
753
            }
754
        }
755
    }
756
757
    /**
758
     * Next date (from the viewpoint of today)
759
     *
760
     * @return Date | Null
0 ignored issues
show
Documentation introduced by
Should the return type not be Date|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...
761
     */
762
    public function NextOrderDate()
763
    {
764
        return $this->getNextOrderDate();
765
    }
766 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...
767
    {
768
        $a = $this->workOutSchedule();
769
        $today = strtotime(Date("Y-m-d"));
770
        if (count($a)) {
771
            foreach ($a as $orderDateInteger => $orderDateLong) {
772
                if ($orderDateInteger > $today) {
773
                    return Date::create($className = "Date", $value = Date("Y-m-d", $orderDateInteger));
774
                }
775
            }
776
        }
777
    }
778
779
780
    /**
781
     * Last Delivery Date
782
     *
783
     * @return Date | Null
0 ignored issues
show
Documentation introduced by
Should the return type not be Date|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...
784
     */
785
    public function FinalOrderDate()
786
    {
787
        return $this->getFinalOrderDate();
788
    }
789 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...
790
    {
791
        $a = $this->workOutSchedule();
792
        if (count($a)) {
793
            foreach ($a as $orderDateInteger => $orderDateLong) {
794
                //do nothing wait for last one...
795
            }
796
            if ($orderDateInteger) {
797
                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 793. 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...
798
            }
799
        }
800
    }
801
802
    /**
803
     * List of delivery dates
804
     *
805
     * @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...
806
     */
807
    public function DeliverySchedule()
808
    {
809
        return $this->getDeliverySchedule();
810
    }
811
    public function getDeliverySchedule()
812
    {
813
        $a = $this->workOutSchedule();
814
        if (count($a)) {
815
            return implode("; ", $a);
816
        }
817
    }
818
819
820
    /**
821
     * Work out the delivery schedule
822
     * @return Array
823
     */
824
    protected function workOutSchedule()
825
    {
826
        //caching value for quicker response
827
        if (!isset(self::$schedule[$this->ID])) {
828
            $a = [];
829
            if ($this->Period && $this->End && $this->Start && $this->DeliveryDay && $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...
Documentation introduced by
The property DeliveryDay 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...
830
                $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...
831
                if (Date("l", $startTime) == $this->DeliveryDay) {
0 ignored issues
show
Documentation introduced by
The property DeliveryDay 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...
832
                    $firstTime = $startTime;
833
                } else {
834
                    $phrase = "Next ".$this->DeliveryDay;
0 ignored issues
show
Documentation introduced by
The property DeliveryDay 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...
835
                    $firstTime = strtotime($phrase, $startTime);
836
                }
837
                $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...
838
                $nextTime = $firstTime;
839
                if ($firstTime && $nextTime && $endTime) {
840
                    if ($firstTime < $endTime) {
841
                        $i = 0;
842
                        while ($nextTime <= $endTime && $i < 999) {
843
                            $a[$nextTime] = Date("j F Y", $nextTime);
844
                            $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...
845
                            $i++;
846
                        }
847
                    }
848
                }
849
            }
850
            self::$schedule[$this->ID] = $a;
851
        }
852
        return self::$schedule[$this->ID];
853
    }
854
855
856
    /**
857
     * Are there any orders scheduled for the future
858
     * @return Boolean
0 ignored issues
show
Documentation introduced by
Should the return type not be boolean|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...
859
     */
860
    public function HasFutureOrders()
861
    {
862
        if ($this->NextOrderDate()) {
863
            return true;
864
        }
865
    }
866
867
    /**
868
     * Are there any orders scheduled for today
869
     * @return Boolean
0 ignored issues
show
Documentation introduced by
Should the return type not be boolean|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...
870
     */
871
    public function HasAnOrderToday()
872
    {
873
        if ($this->TodaysOrderDate()) {
874
            return true;
875
        }
876
    }
877
878
//===========================================================================================================================================================================================
879
880
    public function canView($member = null)
881
    {
882
        $member = Member::currentUser();
883
        if ($member) {
884
            if ($member->IsShopAdmin()) {
885
                return true;
886
            }
887
            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...
888
                return true;
889
            }
890
        }
891
        return false;
892
    }
893
894 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...
895
    {
896
        if (in_array($this->Status, array('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...
897
            return $this->canView($member);
898
        } else {
899
            return false;
900
        }
901
    }
902
903 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...
904
    {
905
        if (in_array($this->Status, array('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...
906
            return $this->canView($member);
907
        } else {
908
            return false;
909
        }
910
    }
911
}
912