Completed
Pull Request — master (#435)
by Mark
28:01
created

Order::getBillingAddress()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 3

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 8
ccs 2
cts 2
cp 1
rs 9.4285
cc 3
eloc 5
nc 2
nop 0
crap 3
1
<?php
2
3
/**
4
 * The order class is a databound object for handling Orders
5
 * within SilverStripe.
6
 *
7
 * @package shop
8
 */
9
class Order extends DataObject
0 ignored issues
show
Complexity introduced by
This class has 22 fields which exceeds the configured maximum of 15.

Too many fields generally indicate a class which does too much and does not follow the single responsibility principle.

We suggest taking a look at the “Code” section for further suggestions on how to fix this.

Loading history...
Complexity introduced by
This class has a complexity of 75 which exceeds the configured maximum of 50.

The class complexity is the sum of the complexity of all methods. A very high value is usually an indication that your class does not follow the single reponsibility principle and does more than one job.

Some resources for further reading:

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

Loading history...
10
{
11
    /**
12
     * Status codes and what they mean:
13
     *
14
     * Unpaid (default): Order created but no successful payment by customer yet
15
     * Query: Order not being processed yet (customer has a query, or could be out of stock)
16
     * Paid: Order successfully paid for by customer
17
     * Processing: Order paid for, package is currently being processed before shipping to customer
18
     * Sent: Order paid for, processed for shipping, and now sent to the customer
19
     * Complete: Order completed (paid and shipped). Customer assumed to have received their goods
20
     * AdminCancelled: Order cancelled by the administrator
21
     * MemberCancelled: Order cancelled by the customer (Member)
22
     */
23
    private static $db                = array(
0 ignored issues
show
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
24
        'Total'                  => 'Currency',
25
        'Reference'              => 'Varchar', //allow for customised order numbering schemes
26
        //status
27
        'Placed'                 => "SS_Datetime", //date the order was placed (went from Cart to Order)
28
        'Paid'                   => 'SS_Datetime', //no outstanding payment left
29
        'ReceiptSent'            => 'SS_Datetime', //receipt emailed to customer
30
        'Printed'                => 'SS_Datetime',
31
        'Dispatched'             => 'SS_Datetime', //products have been sent to customer
32
        'Status'                 => "Enum('Unpaid,Paid,Processing,Sent,Complete,AdminCancelled,MemberCancelled,Cart','Cart')",
33
        //customer (for guest orders)
34
        'FirstName'              => 'Varchar',
35
        'Surname'                => 'Varchar',
36
        'Email'                  => 'Varchar',
37
        'Notes'                  => 'Text',
38
        'IPAddress'              => 'Varchar(15)',
39
        //separate shipping
40
        'SeparateBillingAddress' => 'Boolean',
41
        // keep track of customer locale
42
        'Locale'                 => 'DBLocale',
43
    );
44
45
    private static $has_one           = array(
0 ignored issues
show
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
46
        'Member'          => 'Member',
47
        'ShippingAddress' => 'Address',
48
        'BillingAddress'  => 'Address',
49
    );
50
51
    private static $has_many          = array(
0 ignored issues
show
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
52
        'Items'           => 'OrderItem',
53
        'Modifiers'       => 'OrderModifier',
54
        'OrderStatusLogs' => 'OrderStatusLog',
55
    );
56
57
    private static $defaults          = array(
0 ignored issues
show
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
58
        'Status' => 'Cart',
59
    );
60
61
    private static $casting           = array(
0 ignored issues
show
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
62
        'FullBillingAddress'  => 'Text',
63
        'FullShippingAddress' => 'Text',
64
        'Total'               => 'Currency',
65
        'SubTotal'            => 'Currency',
66
        'TotalPaid'           => 'Currency',
67
        'Shipping'            => 'Currency',
68
        'TotalOutstanding'    => 'Currency',
69
    );
70
71
    private static $summary_fields    = array(
0 ignored issues
show
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
72
        'Reference'   => 'Order No',
73
        'Placed'      => 'Date',
74
        'Name'        => 'Customer',
75
        'LatestEmail' => 'Email',
76
        'Total'       => 'Total',
77
        'Status'      => 'Status',
78
    );
79
80
    private static $searchable_fields = array(
0 ignored issues
show
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
81
        'Reference' => array(),
82
        'FirstName' => array(
83
            'title' => 'Customer Name',
84
        ),
85
        'Email'     => array(
86
            'title' => 'Customer Email',
87
        ),
88
        'Status'    => array(
89
            'filter' => 'ExactMatchFilter',
90
            'field'  => 'CheckboxSetField',
91
        ),
92
    );
93
94
    private static $singular_name     = "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...
95
96
    private static $plural_name       = "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...
97
98
    private static $default_sort      = "\"Placed\" DESC, \"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...
99
100
    /**
101
     * Statuses for orders that have been placed.
102
     */
103
    private static $placed_status = array(
104
        'Paid',
105
        'Unpaid',
106
        'Processing',
107
        'Sent',
108
        'Complete',
109
        'MemberCancelled',
110
        'AdminCancelled',
111
    );
112
113
    /**
114
     * Statuses for which an order can be paid for
115
     */
116
    private static $payable_status = array(
117
        'Cart',
118
        'Unpaid',
119
        'Processing',
120
        'Sent',
121
    );
122
123
    /**
124
     * Statuses that shouldn't show in user account.
125
     */
126
    private static $hidden_status = array('Cart');
127
128
    /**
129
     * Flags to determine when an order can be cancelled.
130
     */
131
    private static $cancel_before_payment    = true;
132
133
    private static $cancel_before_processing = false;
134
135
    private static $cancel_before_sending    = false;
136
137
    private static $cancel_after_sending     = false;
138
139
    /**
140
     * Place an order before payment processing begins
141
     *
142
     * @var boolean
143
     */
144
    private static $place_before_payment = false;
145
146
    /**
147
     * Modifiers represent the additional charges or
148
     * deductions associated to an order, such as
149
     * shipping, taxes, vouchers etc.
150
     */
151
    private static $modifiers            = array();
152
153
    private static $rounding_precision   = 2;
154
155
    private static $reference_id_padding = 5;
156
157
    /**
158
     * @var boolean Will allow completion of orders with GrandTotal=0,
159
     * which could be the case for orders paid with loyalty points or vouchers.
160
     * Will send the "Paid" date on the order, even though no actual payment was taken.
161
     * Will trigger the payment related extension points:
162
     * Order->onPayment, OrderItem->onPayment, Order->onPaid.
163
     */
164
    private static $allow_zero_order_total = false;
165
166
    public static function get_order_status_options()
167
    {
168
        return singleton('Order')->dbObject('Status')->enumValues(false);
169
    }
170
171
    /**
172
     * Create CMS fields for cms viewing and editing orders
173
     */
174
    public function getCMSFields()
175
    {
176
        $fields = FieldList::create(TabSet::create('Root', Tab::create('Main')));
177
        $fs = "<div class=\"field\">";
178
        $fe = "</div>";
179
        $parts = array(
180
            DropdownField::create("Status", _t('Order.db_Status', "Status"), self::get_order_status_options()),
181
            LiteralField::create('Customer', $fs . $this->renderWith("OrderAdmin_Customer") . $fe),
182
            LiteralField::create('Addresses', $fs . $this->renderWith("OrderAdmin_Addresses") . $fe),
183
            LiteralField::create('Content', $fs . $this->renderWith("OrderAdmin_Content") . $fe),
184
        );
185
        if ($this->Notes) {
0 ignored issues
show
Documentation introduced by
The property Notes does not exist on object<Order>. 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...
186
            $parts[] = LiteralField::create('Notes', $fs . $this->renderWith("OrderAdmin_Notes") . $fe);
187
        }
188
        $fields->addFieldsToTab('Root.Main', $parts);
189
        $this->extend('updateCMSFields', $fields);
190
        if ($payments = $fields->fieldByName("Root.Payments.Payments")) {
191
            $fields->removeByName("Payments");
192
            $fields->insertAfter($payments, "Content");
193
            $payments->addExtraClass("order-payments");
194
        }
195
196
        return $fields;
197
    }
198
199
    /**
200
     * Adjust scafolded search context
201
     *
202
     * @return SearchContext the updated search context
203
     */
204
    public function getDefaultSearchContext()
205
    {
206
        $context = parent::getDefaultSearchContext();
207
        $fields = $context->getFields();
208
        $fields->push(
209
            ListboxField::create("Status", _t('Order.db_Status', "Status"))
210
                ->setSource(
211
                    array_combine(
212
                        self::config()->placed_status,
213
                        self::config()->placed_status
214
                    )
215
                )
216
                ->setMultiple(true)
217
        );
218
        //add date range filtering
219
        $fields->insertBefore(
220
            DateField::create("DateFrom", _t('Order.DATE_FROM', "Date from"))
221
                ->setConfig('showcalendar', true),
222
            'Status'
0 ignored issues
show
Documentation introduced by
'Status' is of type string, but the function expects a object<FormField>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
223
        );
224
        $fields->insertBefore(
225
            DateField::create("DateTo", _t('Order.DATE_TO', "Date to"))
226
                ->setConfig('showcalendar', true),
227
            'Status'
0 ignored issues
show
Documentation introduced by
'Status' is of type string, but the function expects a object<FormField>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
228
        );
229
        //get the array, to maniplulate name, and fullname seperately
230
        $filters = $context->getFilters();
231
        $filters['DateFrom'] = GreaterThanFilter::create('Placed');
232
        $filters['DateTo'] = LessThanFilter::create('Placed');
233
        $context->setFilters($filters);
234
235
        return $context;
236
    }
237
238
    /**
239
     * Hack for swapping out relation list with OrderItemList
240
     */
241 32
    public function getComponents($componentName, $filter = "", $sort = "", $join = "", $limit = null)
242
    {
243 32
        $components = parent::getComponents($componentName, $filter = "", $sort = "", $join = "", $limit = null);
244 32
        if ($componentName === "Items" && get_class($components) !== "UnsavedRelationList") {
245 29
            $query = $components->dataQuery();
246 29
            $components = OrderItemList::create("OrderItem", "OrderID");
247 29
            if ($this->model) {
248 29
                $components->setDataModel($this->model);
249 29
            }
250 29
            $components->setDataQuery($query);
251 29
            $components = $components->forForeignID($this->ID);
252 29
        }
253 32
        return $components;
254
    }
255
256
    /**
257
     * Returns the subtotal of the items for this order.
258
     */
259 12
    public function SubTotal()
260
    {
261 12
        if ($this->Items()->exists()) {
0 ignored issues
show
Documentation Bug introduced by
The method Items does not exist on object<Order>? 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...
262 11
            return $this->Items()->SubTotal();
0 ignored issues
show
Documentation Bug introduced by
The method Items does not exist on object<Order>? 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...
263
        }
264
265 1
        return 0;
266
    }
267
268
    /**
269
     * Calculate the total
270
     *
271
     * @return the final total
272
     */
273 8
    public function calculate()
274
    {
275 8
        if (!$this->IsCart()) {
276
            return $this->Total;
0 ignored issues
show
Documentation introduced by
The property Total does not exist on object<Order>. 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
        }
278 8
        $calculator = new OrderTotalCalculator($this);
279 8
        return $this->Total = $calculator->calculate();
0 ignored issues
show
Documentation introduced by
The property Total does not exist on object<Order>. 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...
280
    }
281
282
    /**
283
     * This is needed to maintain backwards compatiability with
284
     * some subsystems using modifiers. eg discounts
285
     */
286
    public function getModifier($className, $forcecreate = false)
287
    {
288
        $calculator = new OrderTotalCalculator($this);
289
        return $calculator->getModifier($className, $forcecreate);
290
    }
291
292
    /**
293
     * Enforce rounding precision when setting total
294
     */
295 62
    public function setTotal($val)
296
    {
297 62
        $this->setField("Total", round($val, self::$rounding_precision));
298 62
    }
299
300
    /**
301
     * Get final value of order.
302
     * Retrieves value from DataObject's record array.
303
     */
304 14
    public function Total()
305
    {
306 14
        return $this->getField("Total");
307
    }
308
309
    /**
310
     * Alias for Total.
311
     */
312 12
    public function GrandTotal()
313
    {
314 12
        return $this->Total();
315
    }
316
317
    /**
318
     * Calculate how much is left to be paid on the order.
319
     * Enforces rounding precision.
320
     */
321 10
    public function TotalOutstanding()
322
    {
323 10
        return round(
324 10
            $this->GrandTotal() - $this->TotalPaid(),
0 ignored issues
show
Documentation Bug introduced by
The method TotalPaid does not exist on object<Order>? 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...
325 10
            self::config()->rounding_precision
326 10
        );
327
    }
328
329
    /**
330
     * Get the link for finishing order processing.
331
     */
332 2
    public function Link()
333
    {
334 2
        if (Member::currentUser()) {
335 1
            return Controller::join_links(AccountPage::find_link(), 'order', $this->ID);
336
        }
337 1
        return CheckoutPage::find_link(false, "order", $this->ID);
338
    }
339
340
    /**
341
     * Returns TRUE if the order can be cancelled
342
     * PRECONDITION: Order is in the DB.
343
     *
344
     * @return boolean
345
     */
346 1
    public function canCancel()
347
    {
348 1
        switch ($this->Status) {
0 ignored issues
show
Bug introduced by
The property Status does not seem to exist. Did you mean placed_status?

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...
349 1
            case 'Unpaid' :
350 1
                return self::config()->cancel_before_payment;
351
            case 'Paid' :
352
                return self::config()->cancel_before_processing;
353
            case 'Processing' :
354
                return self::config()->cancel_before_sending;
355
            case 'Sent' :
356
            case 'Complete' :
357
                return self::config()->cancel_after_sending;
358
        }
359
        return false;
360
    }
361
362
    /**
363
     * Check if an order can be paid for.
364
     *
365
     * @return boolean
366
     */
367 2
    public function canPay($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...
368
    {
369 2
        if (!in_array($this->Status, self::config()->payable_status)) {
0 ignored issues
show
Bug introduced by
The property Status does not seem to exist. Did you mean placed_status?

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...
370
            return false;
371
        }
372 2
        if ($this->TotalOutstanding() > 0 && empty($this->Paid)) {
0 ignored issues
show
Documentation introduced by
The property Paid does not exist on object<Order>. 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...
373 2
            return true;
374
        }
375
        return false;
376
    }
377
378
    /*
379
     * Prevent deleting orders.
380
     * @return boolean
381
     */
382
    public function canDelete($member = null)
383
    {
384
        return false;
385
    }
386
387
    /**
388
     * Check if an order can be viewed.
389
     *
390
     * @return boolean
391
     */
392
    public function canView($member = null)
393
    {
394
        return true;
395
    }
396
397
    /**
398
     * Check if an order can be edited.
399
     *
400
     * @return boolean
401
     */
402
    public function canEdit($member = null)
403
    {
404
        return true;
405
    }
406
407
    /**
408
     * Prevent standard creation of orders.
409
     *
410
     * @return boolean
411
     */
412
    public function canCreate($member = null, $context = array())
0 ignored issues
show
Unused Code introduced by
The parameter $context 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...
413
    {
414
        return false;
415
    }
416
417
    /**
418
     * Return the currency of this order.
419
     * Note: this is a fixed value across the entire site.
420
     *
421
     * @return string
422
     */
423 3
    public function Currency()
424
    {
425 3
        return ShopConfig::get_site_currency();
426
    }
427
428
    /**
429
     * Get the latest email for this order.
430
     */
431 3
    public function getLatestEmail()
432
    {
433 3
        if ($this->MemberID && ($this->Member()->LastEdited > $this->LastEdited || !$this->Email)) {
0 ignored issues
show
Documentation introduced by
The property MemberID does not exist on object<Order>. 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 Email does not exist on object<Order>. 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 Bug introduced by
The method Member does not exist on object<Order>? 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...
434 3
            return $this->Member()->Email;
0 ignored issues
show
Documentation Bug introduced by
The method Member does not exist on object<Order>? 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...
435
        }
436
        return $this->getField('Email');
437
    }
438
439
    /**
440
     * Gets the name of the customer.
441
     */
442
    public function getName()
443
    {
444
        $firstname = $this->FirstName ? $this->FirstName : $this->Member()->FirstName;
0 ignored issues
show
Documentation introduced by
The property FirstName does not exist on object<Order>. 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 Bug introduced by
The method Member does not exist on object<Order>? 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...
445
        $surname = $this->FirstName ? $this->Surname : $this->Member()->Surname;
0 ignored issues
show
Documentation introduced by
The property FirstName does not exist on object<Order>. 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 Surname does not exist on object<Order>. 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 Bug introduced by
The method Member does not exist on object<Order>? 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...
446
        return implode(" ", array_filter(array($firstname, $surname)));
447
    }
448
449
    public function getTitle()
450
    {
451
        return $this->Reference . " - " . $this->dbObject('Placed')->Nice();
0 ignored issues
show
Bug introduced by
The property Reference does not seem to exist. Did you mean reference_id_padding?

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...
452
    }
453
454
    /**
455
     * Get shipping address, or member default shipping address.
456
     */
457 1
    public function getShippingAddress()
458
    {
459 1
        return $this->getAddress('Shipping');
460 1
    }
461
462
    /**
463
     * Get billing address, if marked to use seperate address, otherwise use shipping address,
464
     * or the member default billing address.
465
     */
466
    public function getBillingAddress()
467
    {
468
        if (!$this->SeparateBillingAddress && $this->ShippingAddressID === $this->BillingAddressID) {
0 ignored issues
show
Documentation introduced by
The property SeparateBillingAddress does not exist on object<Order>. 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 ShippingAddressID does not exist on object<Order>. 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 BillingAddressID does not exist on object<Order>. 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...
469
            return $this->getShippingAddress();
470
        } else {
471 1
            return $this->getAddress('Billing');
472
        }
473 1
    }
474 1
475
    /**
476
     * @param string $type - Billing or Shipping
477
     * @return Address
478
     * @throws Exception
479
     */
480
    protected function getAddress($type)
481
    {
482
        $address = $this->getComponent($type . 'Address');
483
484
        if (!$address || !$address->exists() && $this->Member()) {
0 ignored issues
show
Documentation Bug introduced by
The method Member does not exist on object<Order>? 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...
485
            $address = $this->Member()->{"Default${type}Address"}();
0 ignored issues
show
Documentation Bug introduced by
The method Member does not exist on object<Order>? 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...
486
        }
487
488
        if (empty($address->Surname) && empty($address->FirstName)) {
489
            $address->FirstName = $this->FirstName;
0 ignored issues
show
Documentation introduced by
The property FirstName does not exist on object<Order>. 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...
490
            $address->Surname = $this->Surname;
0 ignored issues
show
Documentation introduced by
The property Surname does not exist on object<Order>. 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...
491
        }
492
493
        return $address;
494
    }
495
496
    /**
497
     * Check if the two addresses saved differ.
498
     *
499 1
     * @return boolean
500
     */
501 1
    public function getAddressesDiffer()
502
    {
503
        return $this->SeparateBillingAddress || $this->ShippingAddressID !== $this->BillingAddressID;
0 ignored issues
show
Documentation introduced by
The property SeparateBillingAddress does not exist on object<Order>. 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 ShippingAddressID does not exist on object<Order>. 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 BillingAddressID does not exist on object<Order>. 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...
504
    }
505
506
    /**
507
     * Has this order been sent to the customer?
508
     * (at "Sent" status).
509
     *
510 1
     * @return boolean
511
     */
512 1
    public function IsSent()
513
    {
514
        return $this->Status == 'Sent';
0 ignored issues
show
Bug introduced by
The property Status does not seem to exist. Did you mean placed_status?

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...
515
    }
516
517
    /**
518
     * Is this order currently being processed?
519
     * (at "Sent" OR "Processing" status).
520
     *
521
     * @return boolean
522 1
     */
523
    public function IsProcessing()
524 1
    {
525
        return $this->IsSent() || $this->Status == 'Processing';
0 ignored issues
show
Bug introduced by
The property Status does not seem to exist. Did you mean placed_status?

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...
526
    }
527 80
528
    /**
529 80
     * Return whether this Order has been paid for (Status == Paid)
530
     * or Status == Processing, where it's been paid for, but is
531
     * currently in a processing state.
532
     *
533
     * @return boolean
534
     */
535 63
    public function IsPaid()
536
    {
537 63
        return (boolean)$this->Paid || $this->Status == 'Paid';
0 ignored issues
show
Documentation introduced by
The property Paid does not exist on object<Order>. 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 placed_status?

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...
538 63
    }
539 63
540
    public function IsCart()
541 63
    {
542 63
        return $this->Status == 'Cart';
0 ignored issues
show
Bug introduced by
The property Status does not seem to exist. Did you mean placed_status?

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...
543 63
    }
544 63
545 63
    /**
546 63
     * Create a unique reference identifier string for this order.
547 63
     */
548
    public function generateReference()
549
    {
550
        $reference = str_pad($this->ID, self::$reference_id_padding, '0', STR_PAD_LEFT);
551
        $this->extend('generateReference', $reference);
552 63
        $candidate = $reference;
553
        //prevent generating references that are the same
554 63
        $count = 0;
555
        while (DataObject::get_one('Order', "\"Reference\" = '$candidate'")) {
556
            $count++;
557
            $candidate = $reference . "" . $count;
558
        }
559
        $this->Reference = $candidate;
0 ignored issues
show
Bug introduced by
The property Reference does not seem to exist. Did you mean reference_id_padding?

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...
560 84
    }
561
562 84
    /**
563 84
     * Get the reference for this order, or fall back to order ID.
564 63
     */
565 63
    public function getReference()
566
    {
567
        return $this->getField('Reference') ? $this->getField('Reference') : $this->ID;
568
    }
569 84
570 84
    /**
571 84
     * Force creating an order reference
572 84
     */
573
    public function onBeforeWrite()
574
    {
575
        parent::onBeforeWrite();
576
        if (!$this->getField("Reference") && in_array($this->Status, self::$placed_status)) {
0 ignored issues
show
Bug introduced by
The property Status does not seem to exist. Did you mean placed_status?

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...
577 1
            $this->generateReference();
578
        }
579 1
580 1
        // While the order is unfinished/cart, always store the current locale with the order.
581 1
        // We do this everytime an order is saved, because the user might change locale (language-switch).
582 1
        if ($this->Status == 'Cart') {
0 ignored issues
show
Bug introduced by
The property Status does not seem to exist. Did you mean placed_status?

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...
583 1
            $this->Locale = ShopTools::get_current_locale();
0 ignored issues
show
Documentation introduced by
The property Locale does not exist on object<Order>. 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...
584 1
        }
585
    }
586
587
    /**
588
     * delete attributes, statuslogs, and payments
589
     */
590
    public function onBeforeDelete()
591
    {
592
        $this->Items()->removeAll();
0 ignored issues
show
Documentation Bug introduced by
The method Items does not exist on object<Order>? 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...
593
        $this->Modifiers()->removeAll();
0 ignored issues
show
Documentation Bug introduced by
The method Modifiers does not exist on object<Order>? 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...
594
        $this->OrderStatusLogs()->removeAll();
0 ignored issues
show
Documentation Bug introduced by
The method OrderStatusLogs does not exist on object<Order>? 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...
595
        $this->Payments()->removeAll();
0 ignored issues
show
Documentation Bug introduced by
The method Payments does not exist on object<Order>? 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...
596
        parent::onBeforeDelete();
597
    }
598
599
    public function debug()
600
    {
601
        $val = "<div class='order'><h1>$this->class</h1>\n<ul>\n";
602
        if ($this->record) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->record of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
603
            foreach ($this->record as $fieldName => $fieldVal) {
604
                $val .= "\t<li>$fieldName: " . Debug::text($fieldVal) . "</li>\n";
605
            }
606
        }
607
        $val .= "</ul>\n";
608 2
        $val .= "<div class='items'><h2>Items</h2>";
609
        if ($items = $this->Items()) {
0 ignored issues
show
Documentation Bug introduced by
The method Items does not exist on object<Order>? 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...
Unused Code introduced by
$items is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
610
            $val .= $this->Items()->debug();
0 ignored issues
show
Documentation Bug introduced by
The method Items does not exist on object<Order>? 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...
611
        }
612
        $val .= "</div><div class='modifiers'><h2>Modifiers</h2>";
613
        if ($modifiers = $this->Modifiers()) {
0 ignored issues
show
Documentation Bug introduced by
The method Modifiers does not exist on object<Order>? 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...
614
            $val .= $modifiers->debug();
615
        }
616
        $val .= "</div></div>";
617
618
        return $val;
619
    }
620
}
621