RepeatOrder::FinalOrderDate()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

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