Completed
Push — master ( 613b2e...a2195f )
by Nicolaas
03:28
created

OrderItem   F

Complexity

Total Complexity 133

Size/Duplication

Total Lines 982
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 24

Importance

Changes 0
Metric Value
dl 0
loc 982
rs 1.133
c 0
b 0
f 0
wmc 133
lcom 1
cbo 24

53 Methods

Rating   Name   Duplication   Size   Complexity  
A i18n_singular_name() 0 4 1
A i18n_plural_name() 0 4 1
A get_version() 0 9 1
C getCMSFields() 0 84 7
A canDelete() 0 4 1
A scaffoldSearchFields() 0 7 1
A addBuyableToOrderItem() 0 7 1
B updateForAjax() 0 65 4
C runUpdate() 0 24 7
C onBeforeWrite() 0 22 10
A onAfterWrite() 0 11 3
A hasSameContent() 0 8 4
A reset_calculated_buyable_price() 0 4 1
A UnitPrice() 0 4 1
C getUnitPrice() 0 23 7
A UnitPriceAsMoney() 0 4 1
A getUnitPriceAsMoney() 0 4 1
A Total() 0 4 1
B getTotal() 0 15 5
A TotalAsMoney() 0 4 1
A getTotalAsMoney() 0 4 1
A InternalItemID() 0 4 1
A getInternalItemID() 0 6 2
A QuantityField() 0 4 1
A TotalAsCurrencyObject() 0 4 1
A reset_price_has_been_fixed() 0 5 1
B priceHasBeenFixed() 0 16 6
A Buyable() 0 4 1
D getBuyable() 0 58 17
A BuyableTitle() 0 4 1
A getBuyableTitle() 0 11 3
A BuyableLink() 0 4 1
B getBuyableLink() 0 13 5
A BuyableExists() 0 4 1
A getBuyableExists() 0 10 3
A BuyableFullName() 0 4 1
A getBuyableFullName() 0 9 3
A BuyableMoreDetails() 0 4 1
B getBuyableMoreDetails() 0 14 5
A Link() 0 4 1
A getLink() 0 9 2
A AbsoluteLink() 0 4 1
A getAbsoluteLink() 0 4 1
A CheckoutLink() 0 4 1
A AddLink() 0 4 1
A IncrementLink() 0 4 1
A DecrementLink() 0 4 1
A RemoveLink() 0 4 1
A RemoveAllLink() 0 4 1
A RemoveAllAndEditLink() 0 4 1
A SetSpecificQuantityItemLink() 0 4 1
B linkParameters() 0 12 5
A debug() 0 10 1

How to fix   Complexity   

Complex Class

Complex classes like OrderItem often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use OrderItem, and based on these observations, apply Extract Interface, too.

1
<?php
2
/**
3
 * @description: An order item is a product which has been added to an order.
4
 * An order item links to a Buyable (product) by class name
5
 * That is, we only store the BuyableID and the ClassName
6
 *
7
 *
8
 * @authors: Nicolaas [at] Sunny Side Up .co.nz
9
 * @package: ecommerce
10
 * @sub-package: model
11
 * @inspiration: Silverstripe Ltd, Jeremy
12
 **/
13
class OrderItem extends OrderAttribute
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.

You can fix this by adding a namespace to your class:

namespace YourVendor;

class YourClass { }

When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.

Loading history...
14
{
15
    /**
16
     * what variables are accessible through  http://mysite.com/api/ecommerce/v1/OrderItem/.
17
     *
18
     * @var array
19
     */
20
    private static $api_access = array(
0 ignored issues
show
Unused Code introduced by
The property $api_access is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
21
        'view' => array(
22
            'InternalItemID',
23
            'CalculatedTotal',
24
            'TableTitle',
25
            'TableSubTitleNOHTML',
26
            'Name',
27
            'TableValue',
28
            'Quantity',
29
            'BuyableID',
30
            'BuyableClassName',
31
            'Version',
32
            'UnitPrice',
33
            'Total',
34
            'Order',
35
        ),
36
     );
37
38
    /**
39
     * stardard SS variable.
40
     *
41
     * @var array
42
     */
43
    private static $db = array(
0 ignored issues
show
Unused Code introduced by
The property $db is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
44
        'Quantity' => 'Double',
45
        'BuyableID' => 'Int',
46
        'BuyableClassName' => 'Varchar(60)',
47
        'Version' => 'Int',
48
    );
49
50
    /**
51
     * @var array
52
     *            stardard SS definition
53
     */
54
    private static $indexes = array(
0 ignored issues
show
Unused Code introduced by
The property $indexes is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
55
        'Quantity' => true,
56
        'BuyableID' => true,
57
        'BuyableClassName' => true,
58
    );
59
60
    /**
61
     * @var array
62
     *            stardard SS definition
63
     */
64
    private static $casting = array(
0 ignored issues
show
Unused Code introduced by
The property $casting is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
65
        'UnitPrice' => 'Currency',
66
        'UnitPriceAsMoney' => 'Money',
67
        'Total' => 'Currency',
68
        'TotalAsMoney' => 'Money',
69
        'InternalItemID' => 'Varchar',
70
        'Link' => 'Varchar',
71
        'AbsoluteLink' => 'Varchar',
72
        'BuyableLink' => 'Varchar',
73
        'BuyableExists' => 'Boolean',
74
        'BuyableFullName' => 'Varchar',
75
        'BuyableMoreDetails' => 'Varchar'
76
    );
77
78
    ######################
79
    ## CMS CONFIG ##
80
    ######################
81
82
    /**
83
     * @var array
84
     *            stardard SS definition
85
     */
86
    private static $searchable_fields = array(
0 ignored issues
show
Unused Code introduced by
The property $searchable_fields is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
87
        'OrderID' => array(
88
            'field' => 'NumericField',
89
            'title' => 'Order Number',
90
        ),
91
        //"TableTitle" => "PartialMatchFilter",
0 ignored issues
show
Unused Code Comprehensibility introduced by
67% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
92
        //"UnitPrice",
93
        'Quantity',
94
        //"Total"
95
    );
96
97
    /**
98
     * @var array
99
     *            stardard SS definition
100
     */
101
    private static $field_labels = array(
0 ignored issues
show
Unused Code introduced by
The property $field_labels is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
102
        //@todo - complete
103
    );
104
105
    /**
106
     * @var array
107
     * stardard SS definition
108
     */
109
    private static $summary_fields = array(
0 ignored issues
show
Unused Code introduced by
The property $summary_fields is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
110
        'OrderID' => 'Order ID',
111
        'BuyableFullName' => 'Item',
112
        'BuyableMoreDetails' => 'Details ... ',
113
        'UnitPrice' => 'Unit Price',
114
        'Quantity' => 'Quantity',
115
        'Total' => 'Total Price',
116
    );
117
118
    /**
119
     * singular name of the object. it is recommended to override this
120
     * in any extensions of this class.
121
     *
122
     * @var string
123
     */
124
    private static $singular_name = 'Order Item';
0 ignored issues
show
Unused Code introduced by
The property $singular_name is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
125
    public function i18n_singular_name()
126
    {
127
        return _t('OrderItem.ORDERITEM', 'Order Item');
128
    }
129
130
    /**
131
     * plural name of the object. it is recommended to override this
132
     * in any extensions of this class.
133
     *
134
     * @var string
135
     */
136
    private static $plural_name = 'Order Items';
0 ignored issues
show
Unused Code introduced by
The property $plural_name is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
137
    public function i18n_plural_name()
138
    {
139
        return _t('OrderItem.ORDERITEMS', 'Order Items');
140
    }
141
142
    /**
143
     * Standard SS variable.
144
     *
145
     * @var string
146
     */
147
    private static $description = 'Any item that is added to an order and sits before the sub-total. ';
0 ignored issues
show
Unused Code introduced by
The property $description is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
148
149
    /**
150
     * HACK: Versioned is BROKEN this method helps in fixing it.
151
     * Basically, in Versioned, you get a hard-coded error
152
     * when you retrieve an older version of a DataObject.
153
     * This method returns null if it does not exist.
154
     *
155
     * Idea is from Jeremy: https://github.com/burnbright/silverstripe-shop/blob/master/code/products/FixVersioned.php
156
     *
157
     * @param string $class
158
     * @param int    $id
159
     * @param int    $version
160
     *
161
     * @return DataObject | Null
0 ignored issues
show
Documentation introduced by
Should the return type not be DataObject|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...
162
     */
163
    public static function get_version($class, $id, $version)
164
    {
165
        $oldMode = Versioned::get_reading_mode();
166
        Versioned::set_reading_mode('');
167
        $versionedObject = Versioned::get_version($class, $id, $version);
168
        Versioned::set_reading_mode($oldMode);
169
170
        return $versionedObject;
171
    }
172
173
    /**
174
     * Standard SS method.
175
     *
176
     * @var string
177
     */
178
    public function getCMSFields()
179
    {
180
        $fields = parent::getCMSFields();
181
        $fields->replaceField('BuyableID', HiddenField::create('BuyableID'));
182
        $fields->replaceField('BuyableClassName', HiddenField::create('BuyableClassName'));
183
        $fields->replaceField('Version', HiddenField::create('Version'));
184
        if ($this->OrderID && $this->exists()) {
0 ignored issues
show
Documentation introduced by
The property OrderID does not exist on object<OrderItem>. Since you implemented __get, maybe consider adding a @property annotation.

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

<?php

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

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

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

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

}

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

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

See also the PhpDoc documentation for @property.

Loading history...
185
            $fields->replaceField('OrderID', $fields->dataFieldByName('OrderID')->performReadonlyTransformation());
186
            $fields->addFieldsToTab(
187
                'Root.Advanced',
188
                array(
189
                    HeaderField::create('BuyableHeading', 'Buyable'),
190
191
                    ReadonlyField::create('BuyableIDCheck', 'BuyableID', $this->BuyableID),
0 ignored issues
show
Documentation introduced by
The property BuyableID does not exist on object<OrderItem>. 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...
192
                    ReadonlyField::create('BuyableClassNameCheck', 'BuyableClassName', $this->BuyableClassName),
0 ignored issues
show
Bug introduced by
The property BuyableClassName does not seem to exist. Did you mean ClassName?

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...
193
                    ReadonlyField::create('VersionCheck', 'Version', $this->Version),
0 ignored issues
show
Documentation introduced by
The property Version does not exist on object<OrderItem>. 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...
194
                    $linkField1 = ReadonlyField::create('BuyableLinkExample', 'Buyable Link', '<a href="'.$this->BuyableLink().'">'.$this->BuyableLink().'</a>'),
195
                    ReadonlyField::create('TableTitle', 'TableTitle', $this->TableTitle),
0 ignored issues
show
Documentation introduced by
The property TableTitle does not exist on object<OrderItem>. 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...
196
                    ReadonlyField::create('Subtitle', 'Table SubTitle', $this->TableSubTitleNOHTML()),
197
                    ReadonlyField::create('InternalItemID', 'InternalItemID', $this->InternalItemID()),
198
                    ReadonlyField::create('Name', 'Name', $this->Name),
0 ignored issues
show
Documentation introduced by
The property Name does not exist on object<OrderItem>. 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...
199
200
                    HeaderField::create('OrderItemHeading', 'Order Item'),
201
                    $linkField2 = ReadonlyField::create('LinkExample', 'Link', '<a href="'.$this->Link().'">'.$this->Link().'</a>'),
202
203
                    ReadonlyField::create('ClassName'),
204
                    ReadonlyField::create('Created'),
205
                    ReadonlyField::create('LastEdited'),
206
207
                    HeaderField::create('PricingHeading', 'Pricing'),
208
                    ReadonlyField::create('QuantityCheck', 'Quantity', $this->Quantity),
0 ignored issues
show
Documentation introduced by
The property Quantity does not exist on object<OrderItem>. 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...
209
                    ReadonlyField::create('UnitPrice', 'UnitPrice', $this->UnitPrice),
0 ignored issues
show
Documentation introduced by
The property UnitPrice does not exist on object<OrderItem>. 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...
210
                    ReadonlyField::create('CalculatedTotal', 'Total', $this->CalculatedTotal),
0 ignored issues
show
Documentation introduced by
The property CalculatedTotal does not exist on object<OrderItem>. 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...
211
                    ReadonlyField::create('TableValue', 'Table Value', $this->TableValue),
0 ignored issues
show
Documentation introduced by
The property TableValue does not exist on object<OrderItem>. 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...
212
                    ReadonlyField::create('Total', 'Total', $this->Total),
0 ignored issues
show
Documentation introduced by
The property Total does not exist on object<OrderItem>. 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...
213
                    ReadonlyField::create('TotalAsMoney', 'Total as Money Object', $this->TotalAsMoney()->Nice())
214
                )
215
            );
216
            $linkField1->dontEscape = true;
217
            $linkField2->dontEscape = true;
218
        } else {
219
            $fields->replaceField('OrderID', NumericField::create('OrderID', _t('Order.SINGULARNAME', 'Order')));
220
        }
221
        $fields->removeByName('Sort');
222
        $fields->removeByName('CalculatedTotal');
223
        $fields->removeByName('GroupSort');
224
        $fields->removeByName('OrderAttribute_GroupID');
225
        if ($order = $this->Order()) {
226
            if ($order->IsSubmitted()) {
227
                if ($buyable = $this->Buyable()) {
228
                    if ($this->BuyableExists()) {
229
                        $buyableLink = '<a href="'.$buyable->CMSEditLink().'">'.$this->getBuyableFullName().'</a>';
230
                    } else {
231
                        $buyableLink = $this->getBuyableFullName()
232
                        . _t('OrderItem.NO_LONGER_AVAILABLE', ' - NO LONGER AVAILABLE');
233
                    }
234
                } else {
235
                    $buyableLink = _t('OrderItem.BUYABLE_NOT_FOUND', 'item not found');
236
                }
237
                $fields->addFieldToTab(
238
                    'Root.Main',
239
                    HeaderField::create('buyableLink',  $buyableLink),
240
                    'Quantity'
241
                );
242
243
                $fields->addFieldToTab(
244
                    'Root.Main',
245
                    ReadonlyField::create('TableTitle', _t('OrderItem.ROW_TITLE', 'Row Title'), $this->TableTitle()),
246
                    'Quantity'
247
                );
248
                $fields->addFieldToTab(
249
                    'Root.Main',
250
                    ReadonlyField::create('TableSubTitleNOHTML', _t('OrderItem.SUB_TITLE', 'Sub Title'), $this->BuyableMoreDetails()),
251
                    'Quantity'
252
                );
253
            } else {
254
                $fields->addFieldToTab('Root.Main', BuyableSelectField::create('FindBuyable', _t('OrderItem.SELECITEM', 'Select Item'), $this->Buyable()));
255
            }
256
        } else {
257
            $fields->addFieldToTab('Root.Main', BuyableSelectField::create('FindBuyable', _t('OrderItem.SELECITEM', 'Select Item'), $this->Buyable()));
258
        }
259
260
        return $fields;
261
    }
262
263
    /**
264
     * standard SS method.
265
     *
266
     * @param Member $member
0 ignored issues
show
Documentation introduced by
Should the type for parameter $member not be Member|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
267
     *
268
     * @return bool
269
     **/
270
    public function canDelete($member = null)
271
    {
272
        return $this->canEdit($member);
273
    }
274
275
    /**
276
     * Determine which properties on the DataObject are
277
     * searchable, and map them to their default {@link FormField}
278
     * representations. Used for scaffolding a searchform for {@link ModelAdmin}.
279
     *
280
     * Some additional logic is included for switching field labels, based on
281
     * how generic or specific the field type is.
282
     *
283
     * Used by {@link SearchContext}.
284
     *
285
     * @param array $_params
0 ignored issues
show
Documentation introduced by
Should the type for parameter $_params not be array|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
286
     *                       'fieldClasses': Associative array of field names as keys and FormField classes as values
287
     *                       'restrictFields': Numeric array of a field name whitelist
288
     *
289
     * @return FieldList
290
     */
291
    public function scaffoldSearchFields($_params = null)
292
    {
293
        $fields = parent::scaffoldSearchFields($_params);
294
        $fields->replaceField('OrderID', new NumericField('OrderID', 'Order Number'));
295
296
        return $fields;
297
    }
298
299
    /**
300
     * standard SS method.
301
     *
302
     * @param BuyableModel $buyable
303
     * @param float        $quantity
0 ignored issues
show
Documentation introduced by
Should the type for parameter $quantity not be integer?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
304
     *
305
     * @return FieldList
0 ignored issues
show
Documentation introduced by
Should the return type not be FieldList|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...
306
     **/
307
    public function addBuyableToOrderItem(BuyableModel $buyable, $quantity = 1)
308
    {
309
        $this->Version = $buyable->Version;
0 ignored issues
show
Documentation introduced by
The property Version does not exist on object<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...
Bug introduced by
Accessing Version on the interface BuyableModel suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
310
        $this->BuyableID = $buyable->ID;
0 ignored issues
show
Documentation introduced by
The property BuyableID does not exist on object<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...
Bug introduced by
Accessing ID on the interface BuyableModel suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
311
        $this->BuyableClassName = $buyable->ClassName;
0 ignored issues
show
Bug introduced by
The property BuyableClassName does not seem to exist. Did you mean ClassName?

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...
Bug introduced by
Accessing ClassName on the interface BuyableModel suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
312
        $this->Quantity = $quantity;
0 ignored issues
show
Documentation introduced by
The property Quantity does not exist on object<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...
313
    }
314
315
    /**
316
     * used to return data for ajax.
317
     *
318
     * @param array
319
     *
320
     * @return array used to create JSON for AJAX
321
     **/
322
    public function updateForAjax(array $js)
323
    {
324
        $function = EcommerceConfig::get('OrderItem', 'ajax_total_format');
325
        if (is_array($function)) {
326
            list($function, $format) = $function;
327
        }
328
        $total = $this->$function();
329
        if (isset($format)) {
330
            $total = $total->$format();
331
        }
332
        $ajaxObject = $this->AJAXDefinitions();
333
        if ($this->Quantity) {
0 ignored issues
show
Documentation introduced by
The property Quantity does not exist on object<OrderItem>. 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...
334
            $js[] = array(
335
                't' => 'id',
336
                's' => $ajaxObject->TableID(),
337
                'p' => 'hide',
338
                'v' => 0,
339
            );
340
            $js[] = array(
341
                't' => 'name',
342
                's' => $ajaxObject->QuantityFieldName(),
343
                'p' => 'value',
344
                'v' => $this->Quantity,
0 ignored issues
show
Documentation introduced by
The property Quantity does not exist on object<OrderItem>. 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...
345
            );
346
            $js[] = array(
347
                't' => 'id',
348
                's' => $ajaxObject->TableTitleID(),
349
                'p' => 'innerHTML',
350
                'v' => $this->TableTitle(),
351
            );
352
            $js[] = array(
353
                't' => 'id',
354
                's' => $ajaxObject->CartTitleID(),
355
                'p' => 'innerHTML',
356
                'v' => $this->CartTitle(),
357
            );
358
            $js[] = array(
359
                't' => 'id',
360
                's' => $ajaxObject->TableSubTitleID(),
361
                'p' => 'innerHTML',
362
                'v' => $this->TableSubTitle(),
363
            );
364
            $js[] = array(
365
                't' => 'id',
366
                's' => $ajaxObject->CartSubTitleID(),
367
                'p' => 'innerHTML',
368
                'v' => $this->CartSubTitle(),
369
            );
370
            $js[] = array(
371
                't' => 'id',
372
                's' => $ajaxObject->TableTotalID(),
373
                'p' => 'innerHTML',
374
                'v' => $total,
375
            );
376
        } else {
377
            $js[] = array(
378
                't' => 'id',
379
                's' => $ajaxObject->TableID(),
380
                'p' => 'hide',
381
                'v' => 1,
382
            );
383
        }
384
385
        return $js;
386
    }
387
388
    /**
389
     * saves details about the Order Item before the order is submittted.
390
     *
391
     * @param bool $recalculate - run it, even if it has run already
392
     **/
393
    public function runUpdate($recalculate = false)
394
    {
395
        $buyable = $this->Buyable(true);
396
        if ($buyable && $buyable->canPurchase()) {
397
            if (isset($buyable->Version)) {
398
                if ($this->Version != $buyable->Version) {
0 ignored issues
show
Documentation introduced by
The property Version does not exist on object<OrderItem>. 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...
399
                    $this->Version = $buyable->Version;
0 ignored issues
show
Documentation introduced by
The property Version does not exist on object<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...
400
                    $this->write();
401
                }
402
            }
403
            $oldValue = $this->CalculatedTotal - 0;
0 ignored issues
show
Documentation introduced by
The property CalculatedTotal does not exist on object<OrderItem>. 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...
404
            $newValue = ($this->getUnitPrice() * $this->Quantity) - 0;
0 ignored issues
show
Documentation introduced by
The property Quantity does not exist on object<OrderItem>. 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...
405
            if ((round($newValue, 5) != round($oldValue, 5)) || $recalculate) {
406
                $this->CalculatedTotal = $newValue;
0 ignored issues
show
Documentation introduced by
The property CalculatedTotal does not exist on object<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
                $this->write();
408
            }
409
        } else {
410
            //if it can not be purchased or it does not exist
411
            //then we do not accept it!!!!
412
            $this->delete();
413
        }
414
415
        return parent::runUpdate($recalculate);
416
    }
417
418
419
    /**
420
     * Standard SS method.
421
     * If the quantity is zero then we set it to 1.
422
     * TODO: evaluate this rule.
423
     */
424
    public function onBeforeWrite()
425
    {
426
        if (Session::get('EcommerceOrderGETCMSHack') && !$this->OrderID) {
0 ignored issues
show
Documentation introduced by
The property OrderID does not exist on object<OrderItem>. 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...
427
            $this->OrderID = intval(Session::get('EcommerceOrderGETCMSHack'));
0 ignored issues
show
Documentation introduced by
The property OrderID does not exist on object<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...
428
        }
429
        if (!$this->exists()) {
430
            if ($buyable = $this->Buyable(true)) {
431
                if ($this->ClassName == 'OrderItem' && $this->BuyableClassName != 'OrderItem') {
0 ignored issues
show
Bug introduced by
The property BuyableClassName does not seem to exist. Did you mean ClassName?

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...
432
                    $this->setClassName($buyable->classNameForOrderItem());
433
                }
434
            }
435
        }
436
        //now we can do the parent thing
437
        parent::onBeforeWrite();
438
        //always keep quantity above 0
439
        if (floatval($this->Quantity) == 0) {
0 ignored issues
show
Documentation introduced by
The property Quantity does not exist on object<OrderItem>. 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...
440
            $this->Quantity = 1;
0 ignored issues
show
Documentation introduced by
The property Quantity does not exist on object<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...
441
        }
442
        if (!$this->Version && $buyable = $this->Buyable(true)) {
0 ignored issues
show
Documentation introduced by
The property Version does not exist on object<OrderItem>. 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...
443
            $this->Version = $buyable->Version;
0 ignored issues
show
Documentation introduced by
The property Version does not exist on object<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...
444
        }
445
    }
446
447
    /**
448
     * Standard SS method
449
     * the method below is very important...
450
     * We initialise the order once it has an OrderItem.
451
     */
452
    public function onAfterWrite()
453
    {
454
        parent::onAfterWrite();
455
        $order = $this->Order();
456
        if ($order) {
457
            if (!$order->StatusID) {
0 ignored issues
show
Documentation introduced by
The property StatusID 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...
458
                //this adds the modifiers and automatically WRITES AGAIN - WATCH RACING CONDITIONS!
459
                $order->init(true);
460
            }
461
        }
462
    }
463
464
    /**
465
     * Check if two Order Items are the same.
466
     * Useful when adding two items to cart.
467
     *
468
     * @param OrderItem $orderItem
469
     *
470
     * @return bool
471
     **/
472
    public function hasSameContent(OrderItem $orderItem)
473
    {
474
        return
475
            is_a($orderItem, Object::getCustomClass('OrderItem')) &&
476
            $this->BuyableID == $orderItem->BuyableID &&
0 ignored issues
show
Documentation introduced by
The property BuyableID does not exist on object<OrderItem>. 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...
477
            $this->BuyableClassName == $orderItem->BuyableClassName &&
0 ignored issues
show
Bug introduced by
The property BuyableClassName does not seem to exist. Did you mean ClassName?

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...
478
            $this->Version == $orderItem->Version;
0 ignored issues
show
Documentation introduced by
The property Version does not exist on object<OrderItem>. 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...
479
    }
480
481
    ######################
482
    ## TEMPLATE METHODS ##
483
    ######################
484
485
    protected static $calculated_buyable_price = array();
486
    public static function reset_calculated_buyable_price()
487
    {
488
        self::$calculated_buyable_price = array();
489
    }
490
491
    public function UnitPrice($recalculate = false)
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
492
    {
493
        return $this->getUnitPrice($recalculate);
494
    }
495
    public function getUnitPrice($recalculate = false)
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
496
    {
497
        if ($this->priceHasBeenFixed($recalculate) && !$recalculate) {
498
            if (! $this->Quantity) {
0 ignored issues
show
Documentation introduced by
The property Quantity does not exist on object<OrderItem>. 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...
499
                $this->Quantity = 1;
0 ignored issues
show
Documentation introduced by
The property Quantity does not exist on object<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...
500
            }
501
502
            return $this->CalculatedTotal / $this->Quantity;
0 ignored issues
show
Documentation introduced by
The property CalculatedTotal does not exist on object<OrderItem>. 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 Quantity does not exist on object<OrderItem>. 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...
503
        } elseif ($buyable = $this->Buyable()) {
504
            if (!isset(self::$calculated_buyable_price[$this->ID]) || $recalculate) {
505
                self::$calculated_buyable_price[$this->ID] = $buyable->getCalculatedPrice();
506
            }
507
            $unitPrice = self::$calculated_buyable_price[$this->ID];
508
        } else {
509
            $unitPrice = 0;
510
        }
511
        //$updatedUnitPrice = $this->extend('updateUnitPrice', $price);
0 ignored issues
show
Unused Code Comprehensibility introduced by
65% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
512
        //if ($updatedUnitPrice !== null && is_array($updatedUnitPrice) && count($updatedUnitPrice)) {
0 ignored issues
show
Unused Code Comprehensibility introduced by
58% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
513
        //    $unitPrice = $updatedUnitPrice[0];
0 ignored issues
show
Unused Code Comprehensibility introduced by
60% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
514
        //}
515
516
        return $unitPrice;
517
    }
518
519
    public function UnitPriceAsMoney($recalculate = false)
520
    {
521
        return $this->getUnitPriceAsMoney($recalculate);
522
    }
523
    public function getUnitPriceAsMoney($recalculate = false)
524
    {
525
        return EcommerceCurrency::get_money_object_from_order_currency($this->getUnitPrice($recalculate), $this->Order());
526
    }
527
528
    /**
529
     * @param bool $recalculate - forces recalculation of price
530
     *
531
     * @return float
532
     */
533
    public function Total($recalculate = false)
0 ignored issues
show
Unused Code introduced by
The parameter $recalculate 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...
534
    {
535
        return $this->getTotal();
536
    }
537
    public function getTotal($recalculate = false)
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
538
    {
539
        if ($this->priceHasBeenFixed()) {
540
            //get from database
541
            $total = $this->CalculatedTotal;
0 ignored issues
show
Documentation introduced by
The property CalculatedTotal does not exist on object<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...
542
        } else {
543
            $total = $this->getUnitPrice($recalculate) * $this->Quantity;
0 ignored issues
show
Documentation introduced by
The property Quantity does not exist on object<OrderItem>. 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...
544
        }
545
        $updatedTotal = $this->extend('updateTotal', $total);
546
        if ($updatedTotal !== null && is_array($updatedTotal) && count($updatedTotal)) {
547
            $total = $updatedTotal[0];
548
        }
549
550
        return $total;
551
    }
552
553
    /**
554
     * @param bool $recalculate - forces recalculation of price
555
     *
556
     * @return Money
557
     */
558
    public function TotalAsMoney($recalculate = false)
559
    {
560
        return $this->getTotalAsMoney($recalculate);
561
    }
562
    public function getTotalAsMoney($recalculate = false)
563
    {
564
        return EcommerceCurrency::get_money_object_from_order_currency($this->getTotal($recalculate), $this->Order());
565
    }
566
567
    /**
568
     * Casted variable
569
     * returns InternalItemID from Buyable.
570
     */
571
    public function InternalItemID()
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
572
    {
573
        return $this->getInternalItemID();
574
    }
575
    public function getInternalItemID()
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
576
    {
577
        if ($buyable = $this->Buyable()) {
578
            return $buyable->InternalItemID;
579
        }
580
    }
581
582
    /**
583
     * @return Field (EcomQuantityField)
0 ignored issues
show
Documentation introduced by
Should the return type not be EcomQuantityField?

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...
584
     **/
585
    public function QuantityField()
586
    {
587
        return EcomQuantityField::create($this);
588
    }
589
590
    /**
591
     * @return Currency (DB Object)
592
     **/
593
    public function TotalAsCurrencyObject()
594
    {
595
        return DBField::create_field('Currency', $this->Total());
596
    }
597
598
    ##########################
599
    ## OTHER LOOKUP METHODS ##
600
    ##########################
601
602
    /**
603
     * Helps in speeding up code.
604
     * This can be a static variable as it is the same for all OrderItems for an Order.
605
     *
606
     * @var array
607
     */
608
    private static $_price_has_been_fixed = array();
609
610
    /**
611
     * @param int $orderID
612
     */
613
    public static function reset_price_has_been_fixed($orderID = 0)
614
    {
615
        $orderID = ShoppingCart::current_order_id($orderID);
616
        self::$_price_has_been_fixed[$orderID] = array();
617
    }
618
619
    /**
620
     * @description - tells you if an order item price has been "fixed"
621
     * meaning that is has been saved in the CalculatedTotal field so that
622
     * it can not be altered.
623
     *
624
     * Default returns false; this is good for uncompleted orders
625
     * but not so good for completed ones.
626
     *
627
     * @return bool
628
     **/
629
    protected function priceHasBeenFixed($recalculate = false)
630
    {
631
        if (empty(self::$_price_has_been_fixed[$this->OrderID]) || $recalculate) {
0 ignored issues
show
Documentation introduced by
The property OrderID does not exist on object<OrderItem>. Since you implemented __get, maybe consider adding a @property annotation.

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

<?php

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

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

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

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

}

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

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

See also the PhpDoc documentation for @property.

Loading history...
632
            self::$_price_has_been_fixed[$this->OrderID] = false;
0 ignored issues
show
Documentation introduced by
The property OrderID does not exist on object<OrderItem>. Since you implemented __get, maybe consider adding a @property annotation.

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

<?php

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

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

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

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

}

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

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

See also the PhpDoc documentation for @property.

Loading history...
633
            if ($order = $this->Order()) {
634
                if ($order->IsSubmitted()) {
635
                    self::$_price_has_been_fixed[$this->OrderID] = true;
0 ignored issues
show
Documentation introduced by
The property OrderID does not exist on object<OrderItem>. 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...
636
                    if ($recalculate) {
637
                        user_error('You are trying to recalculate an order that is already submitted.', E_USER_NOTICE);
638
                    }
639
                }
640
            }
641
        }
642
643
        return self::$_price_has_been_fixed[$this->OrderID];
0 ignored issues
show
Documentation introduced by
The property OrderID does not exist on object<OrderItem>. 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...
644
    }
645
646
    /**
647
     * Store for buyables.
648
     * We store this here to speed up things a little
649
     * Format is like this
650
     * Array(
651
     *  0 => Buyable (versioned)
652
     *  1 => Buyable (current)
653
     * );.
654
     *
655
     * @var array
656
     */
657
    protected $tempBuyableStore = array();
658
659
    /**
660
     * @param bool $current - is this a current one, or an older VERSION ?
661
     *
662
     * @return DataObject (Any type of Data Object that is buyable)
663
     **/
664
    public function Buyable($current = false)
665
    {
666
        return $this->getBuyable($current);
667
    }
668
669
    /**
670
     * @param bool $current - is this a current one, or an older VERSION ?
671
     *
672
     * @return DataObject (Any type of Data Object that is buyable)
673
     **/
674
    public function getBuyable($current = false)
675
    {
676
        $tempBuyableStoreType = $current ? 'current' : 'version';
677
        if (!isset($this->tempBuyableStore[$tempBuyableStoreType])) {
678
            if (!$this->BuyableID) {
0 ignored issues
show
Documentation introduced by
The property BuyableID does not exist on object<OrderItem>. 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...
679
                user_error('There was an error retrieving the product', E_USER_NOTICE);
680
                return Product::create();
681
            }
682
            //start hack
683
            if (!$this->BuyableClassName) {
0 ignored issues
show
Bug introduced by
The property BuyableClassName does not seem to exist. Did you mean ClassName?

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...
684
                $this->BuyableClassName = str_replace('_OrderItem', '', $this->ClassName);
0 ignored issues
show
Bug introduced by
The property BuyableClassName does not seem to exist. Did you mean ClassName?

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...
685
            }
686
            $turnTranslatableBackOn = false;
687
            $className = $this->BuyableClassName;
0 ignored issues
show
Bug introduced by
The property BuyableClassName does not seem to exist. Did you mean ClassName?

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...
688
            if ($className::has_extension($this->class, 'Translatable')) {
689
                Translatable::disable_locale_filter();
690
                $turnTranslatableBackOn = true;
691
            }
692
            //end hack!
693
            $obj = null;
694
            if ($current) {
695
                $obj = $className::get()->byID($this->BuyableID);
0 ignored issues
show
Documentation introduced by
The property BuyableID does not exist on object<OrderItem>. 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...
696
            }
697
            //run if current not available or current = false
698
            if (!$obj || !$current) {
699
                if (((!$obj) || (!$obj->exists())) && $this->Version) {
0 ignored issues
show
Documentation introduced by
The property Version does not exist on object<OrderItem>. 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...
700
                    /* @TODO: check if the version exists?? - see sample below
0 ignored issues
show
Unused Code Comprehensibility introduced by
51% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
701
                    $versionTable = $this->BuyableClassName."_versions";
702
                    $dbConnection = DB::getConn();
703
                    if($dbConnection && $dbConnection instanceOf MySQLDatabase && $dbConnection->hasTable($versionTable)) {
704
                        $result = DB::query("
705
                            SELECT COUNT(\"ID\")
706
                            FROM \"$versionTable\"
707
                            WHERE
708
                                \"RecordID\" = ".intval($this->BuyableID)."
709
                                AND \"Version\" = ".intval($this->Version)."
710
                        ");
711
                        if($result->value()) {
712
                     */
713
                    $obj = self::get_version($this->BuyableClassName, $this->BuyableID, $this->Version);
0 ignored issues
show
Bug introduced by
The property BuyableClassName does not seem to exist. Did you mean ClassName?

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 BuyableID does not exist on object<OrderItem>. 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 Version does not exist on object<OrderItem>. 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...
714
                }
715
                //our second to last resort
716
                if ((!$obj) || (!$obj->exists())) {
717
                    $obj = Versioned::get_latest_version($this->BuyableClassName, $this->BuyableID);
0 ignored issues
show
Bug introduced by
The property BuyableClassName does not seem to exist. Did you mean ClassName?

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 BuyableID does not exist on object<OrderItem>. 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...
718
                }
719
            }
720
            //our final backup
721
            if ((!$obj) || (!$obj->exists())) {
722
                $obj = $className::get()->byID($this->BuyableID);
0 ignored issues
show
Documentation introduced by
The property BuyableID does not exist on object<OrderItem>. 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...
723
            }
724
            if ($turnTranslatableBackOn) {
725
                Translatable::enable_locale_filter();
726
            }
727
            $this->tempBuyableStore[$tempBuyableStoreType] = $obj;
728
        }
729
        //check for data integrity
730
        return $this->tempBuyableStore[$tempBuyableStoreType];
731
    }
732
733
    /**
734
     * @alias for getBuyableTitle
735
     * @return string
736
     **/
737
    public function BuyableTitle()
738
    {
739
        return $this->getBuyableTitle();
740
    }
741
742
    /**
743
     * @return string
744
     **/
745
    public function getBuyableTitle()
746
    {
747
        if ($buyable = $this->Buyable()) {
748
            if ($title = $buyable->Title) {
749
                return $title;
750
            }
751
            //This should work in all cases, because ultimately, it will return #ID - see DataObject
752
            return $item->getTitle();
0 ignored issues
show
Bug introduced by
The variable $item does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
753
        }
754
        user_error('No Buyable could be found for OrderItem with ID: '.$this->ID, E_USER_WARNING);
755
    }
756
757
    /**
758
     * @alias for getBuyableLink
759
     * @return string
0 ignored issues
show
Documentation introduced by
Should the return type not be false|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...
760
     */
761
    public function BuyableLink()
762
    {
763
        return $this->getBuyableLink();
764
    }
765
766
    /**
767
     *
768
     * @return string
0 ignored issues
show
Documentation introduced by
Should the return type not be false|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...
769
     */
770
    public function getBuyableLink()
771
    {
772
        $buyable = $this->Buyable();
773
        if ($buyable && $buyable->exists()) {
774
            $order = $this->Order();
775
            if ($order && $order->IsSubmitted()) {
776
                return  Director::absoluteURL($buyable->VersionedLink());
777
            }
778
            return  Director::absoluteURL($buyable->Link());
779
        } else {
780
            return $this->getLink();
781
        }
782
    }
783
784
    /**
785
     * @alias for getBuyableExists
786
     * @return bool
787
     */
788
    public function BuyableExists()
789
    {
790
        return $this->getBuyableExists();
791
    }
792
793
    /**
794
     *
795
     * @return bool
796
     */
797
    public function getBuyableExists()
798
    {
799
        if ($buyable = $this->Buyable(true)) {
800
            $className = $buyable->ClassName;
801
            $id = $buyable->ID;
802
            return $className::get()->byID($id) ? true : false;
803
        }
804
805
        return false;
806
    }
807
808
809
    /**
810
     * @alias for getBuyableFullName
811
     * @return String
812
     */
813
    public function BuyableFullName()
814
    {
815
        return $this->getBuyableFullName();
816
    }
817
818
    /**
819
     * @return String
820
     */
821
    public function getBuyableFullName()
822
    {
823
        $buyable = $this->Buyable();
824
        if ($buyable && $buyable->exists()) {
825
            return $buyable->FullName;
826
        } else {
827
            return $this->getBuyableTitle();
828
        }
829
    }
830
831
    /**
832
     * @alias for getBuyableMoreDetails
833
     * @return String
834
     */
835
    public function BuyableMoreDetails()
836
    {
837
        return $this->getBuyableMoreDetails();
838
    }
839
840
    /**
841
     * @return String
842
     */
843
    public function getBuyableMoreDetails()
844
    {
845
        if ($subtitle = $this->TableSubTitleNOHTML) {
0 ignored issues
show
Documentation introduced by
The property TableSubTitleNOHTML does not exist on object<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...
846
            return $subtitle;
847
        }
848
        $buyable = $this->Buyable();
849
        if ($buyable && $buyable->exists()) {
850
            if ($buyable->ShortDescription) {
851
                return $buyable->ShortDescription;
852
            }
853
        }
854
855
        return _t('OrderItem.NA', 'n/a');
856
    }
857
858
    ##########################
859
    ## LINKS                ##
860
    ##########################
861
862
    /**
863
     * @return string (URLSegment)
864
     **/
865
    public function Link()
866
    {
867
        return $this->getLink();
868
    }
869
870
    /**
871
     * @return string (URLSegment)
872
     **/
873
    public function getLink()
874
    {
875
        $order = $this->Order();
876
        if ($order) {
877
            return $order->Link();
878
        } else {
879
            return  Director::absoluteURL("order-link-could-not-be-found");
880
        }
881
    }
882
883
    /**
884
     * alias
885
     * @return string
0 ignored issues
show
Documentation introduced by
Should the return type not be false|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...
886
     */
887
    public function AbsoluteLink()
888
    {
889
        return $this->getAbsoluteLink();
890
    }
891
892
    /**
893
     * @return string
0 ignored issues
show
Documentation introduced by
Should the return type not be false|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...
894
     */
895
    public function getAbsoluteLink()
896
    {
897
        return Director::absoluteURL($this->getLink());
898
    }
899
900
    /**
901
     * @return string (URLSegment)
902
     **/
903
    public function CheckoutLink()
904
    {
905
        return CheckoutPage::find_link();
906
    }
907
908
    ## Often Overloaded functions ##
909
910
    /**
911
     * @return string (URLSegment)
912
     **/
913
    public function AddLink()
914
    {
915
        return ShoppingCart_Controller::add_item_link($this->BuyableID, $this->BuyableClassName, $this->linkParameters());
0 ignored issues
show
Documentation introduced by
The property BuyableID does not exist on object<OrderItem>. 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 BuyableClassName does not seem to exist. Did you mean ClassName?

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...
916
    }
917
918
    /**
919
     * @return string (URLSegment)
920
     **/
921
    public function IncrementLink()
922
    {
923
        return ShoppingCart_Controller::add_item_link($this->BuyableID, $this->BuyableClassName, $this->linkParameters());
0 ignored issues
show
Documentation introduced by
The property BuyableID does not exist on object<OrderItem>. 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 BuyableClassName does not seem to exist. Did you mean ClassName?

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...
924
    }
925
926
    /**
927
     * @return string (URLSegment)
928
     **/
929
    public function DecrementLink()
930
    {
931
        return ShoppingCart_Controller::remove_item_link($this->BuyableID, $this->BuyableClassName, $this->linkParameters());
0 ignored issues
show
Documentation introduced by
The property BuyableID does not exist on object<OrderItem>. 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 BuyableClassName does not seem to exist. Did you mean ClassName?

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...
932
    }
933
934
    /**
935
     * @return string (URLSegment)
936
     **/
937
    public function RemoveLink()
938
    {
939
        return ShoppingCart_Controller::remove_item_link($this->BuyableID, $this->BuyableClassName, $this->linkParameters());
0 ignored issues
show
Documentation introduced by
The property BuyableID does not exist on object<OrderItem>. 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 BuyableClassName does not seem to exist. Did you mean ClassName?

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...
940
    }
941
942
    /**
943
     * @return string (URLSegment)
944
     **/
945
    public function RemoveAllLink()
946
    {
947
        return ShoppingCart_Controller::remove_all_item_link($this->BuyableID, $this->BuyableClassName, $this->linkParameters());
0 ignored issues
show
Documentation introduced by
The property BuyableID does not exist on object<OrderItem>. 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 BuyableClassName does not seem to exist. Did you mean ClassName?

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...
948
    }
949
950
    /**
951
     * @return string (URLSegment)
952
     **/
953
    public function RemoveAllAndEditLink()
954
    {
955
        return ShoppingCart_Controller::remove_all_item_and_edit_link($this->BuyableID, $this->BuyableClassName, $this->linkParameters());
0 ignored issues
show
Documentation introduced by
The property BuyableID does not exist on object<OrderItem>. 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 BuyableClassName does not seem to exist. Did you mean ClassName?

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...
956
    }
957
958
    /**
959
     * @return string (URLSegment)
960
     **/
961
    public function SetSpecificQuantityItemLink($quantity)
962
    {
963
        return ShoppingCart_Controller::set_quantity_item_link($this->BuyableID, $this->BuyableClassName, array_merge($this->linkParameters(), array('quantity' => $quantity)));
0 ignored issues
show
Documentation introduced by
The property BuyableID does not exist on object<OrderItem>. 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 BuyableClassName does not seem to exist. Did you mean ClassName?

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...
964
    }
965
966
    /**
967
     * @Todo: do we still need this?
968
     *
969
     * @return array for use as get variables in link
970
     **/
971
    protected function linkParameters()
972
    {
973
        $array = array();
974
        $updatedLinkParameters = $this->extend('updateLinkParameters', $array);
975
        if ($updatedLinkParameters !== null && is_array($updatedLinkParameters) && count($updatedLinkParameters)) {
976
            foreach ($updatedLinkParameters as $updatedLinkParametersUpdate) {
977
                $array = array_merge($array, $updatedLinkParametersUpdate);
978
            }
979
        }
980
981
        return $array;
982
    }
983
984
    public function debug()
985
    {
986
        $html = EcommerceTaskDebugCart::debug_object($this);
987
        $html .= '<ul>';
988
        $html .= '<li><b>Buyable Price:</b> '.$this->Buyable()->Price.' </li>';
989
        $html .= '<li><b>Buyable Calculated Price:</b> '.$this->Buyable()->CalculatedPrice().' </li>';
990
        $html .= '</ul>';
991
992
        return $html;
993
    }
994
}
995