Completed
Push — master ( 181911...c15eac )
by Nicolaas
03:23
created

OrderItem::priceHasBeenFixed()   B

Complexity

Conditions 6
Paths 5

Size

Total Lines 16
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
dl 0
loc 16
rs 8.8571
c 0
b 0
f 0
eloc 9
nc 5
nop 1

1 Method

Rating   Name   Duplication   Size   Complexity  
A OrderItem::Buyable() 0 4 1
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
     * @param int $orderID
604
     * 
605
     */
606
    public static function reset_price_has_been_fixed($orderID = 0)
607
    {
608
        self::set_price_has_been_fixed($orderID, false);
609
    }
610
611
612
613
    /**
614
     * Store for buyables.
615
     * We store this here to speed up things a little
616
     * Format is like this
617
     * Array(
618
     *  0 => Buyable (versioned)
619
     *  1 => Buyable (current)
620
     * );.
621
     *
622
     * @var array
623
     */
624
    protected $tempBuyableStore = array();
625
626
    /**
627
     * @param bool $current - is this a current one, or an older VERSION ?
628
     *
629
     * @return DataObject (Any type of Data Object that is buyable)
630
     **/
631
    public function Buyable($current = false)
632
    {
633
        return $this->getBuyable($current);
634
    }
635
636
    /**
637
     * @param bool $current - is this a current one, or an older VERSION ?
638
     *
639
     * @return DataObject (Any type of Data Object that is buyable)
640
     **/
641
    public function getBuyable($current = false)
642
    {
643
        $currentOrVersion = $current ? 'current' : 'version';
644
        if (!isset($this->tempBuyableStore[$currentOrVersion])) {
645
            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...
646
                user_error('There was an error retrieving the product', E_USER_NOTICE);
647
                return Product::create();
648
            }
649
            //start hack
650
            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...
651
                $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...
652
            }
653
            $turnTranslatableBackOn = false;
654
            $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...
655
            if ($className::has_extension($this->class, 'Translatable')) {
656
                Translatable::disable_locale_filter();
657
                $turnTranslatableBackOn = true;
658
            }
659
            //end hack!
660
            $obj = null;
661
            if ($current) {
662
                $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...
663
            }
664
            //run if current not available or current = false
665
            if (!$obj || !$current) {
666
                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...
667
                    /* @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...
668
                    $versionTable = $this->BuyableClassName."_versions";
669
                    $dbConnection = DB::getConn();
670
                    if($dbConnection && $dbConnection instanceOf MySQLDatabase && $dbConnection->hasTable($versionTable)) {
671
                        $result = DB::query("
672
                            SELECT COUNT(\"ID\")
673
                            FROM \"$versionTable\"
674
                            WHERE
675
                                \"RecordID\" = ".intval($this->BuyableID)."
676
                                AND \"Version\" = ".intval($this->Version)."
677
                        ");
678
                        if($result->value()) {
679
                     */
680
                    $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...
681
                }
682
                //our second to last resort
683
                if ((!$obj) || (!$obj->exists())) {
684
                    $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...
685
                }
686
            }
687
            //our final backup
688
            if ((!$obj) || (!$obj->exists())) {
689
                $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...
690
            }
691
            if ($turnTranslatableBackOn) {
692
                Translatable::enable_locale_filter();
693
            }
694
            $this->tempBuyableStore[$currentOrVersion] = $obj;
695
        }
696
        //check for data integrity
697
        return $this->tempBuyableStore[$currentOrVersion];
698
    }
699
700
    /**
701
     * @alias for getBuyableTitle
702
     * @return string
703
     **/
704
    public function BuyableTitle()
705
    {
706
        return $this->getBuyableTitle();
707
    }
708
709
    /**
710
     * @return string
711
     **/
712
    public function getBuyableTitle()
713
    {
714
        if ($buyable = $this->Buyable()) {
715
            if ($title = $buyable->Title) {
716
                return $title;
717
            }
718
            //This should work in all cases, because ultimately, it will return #ID - see DataObject
719
            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...
720
        }
721
        user_error('No Buyable could be found for OrderItem with ID: '.$this->ID, E_USER_WARNING);
722
    }
723
724
    /**
725
     * @alias for getBuyableLink
726
     * @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...
727
     */
728
    public function BuyableLink()
729
    {
730
        return $this->getBuyableLink();
731
    }
732
733
    /**
734
     *
735
     * @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...
736
     */
737
    public function getBuyableLink()
738
    {
739
        $buyable = $this->Buyable();
740
        if ($buyable && $buyable->exists()) {
741
            $order = $this->Order();
742
            if ($order && $order->IsSubmitted()) {
743
                return  Director::absoluteURL($buyable->VersionedLink());
744
            }
745
            return  Director::absoluteURL($buyable->Link());
746
        } else {
747
            return $this->getLink();
748
        }
749
    }
750
751
    /**
752
     * @alias for getBuyableExists
753
     * @return bool
754
     */
755
    public function BuyableExists()
756
    {
757
        return $this->getBuyableExists();
758
    }
759
760
    /**
761
     *
762
     * @return bool
763
     */
764
    public function getBuyableExists()
765
    {
766
        if ($buyable = $this->Buyable(true)) {
767
            $className = $buyable->ClassName;
768
            $id = $buyable->ID;
769
            return $className::get()->byID($id) ? true : false;
770
        }
771
772
        return false;
773
    }
774
775
776
    /**
777
     * @alias for getBuyableFullName
778
     * @return String
779
     */
780
    public function BuyableFullName()
781
    {
782
        return $this->getBuyableFullName();
783
    }
784
785
    /**
786
     * @return String
787
     */
788
    public function getBuyableFullName()
789
    {
790
        $buyable = $this->Buyable();
791
        if ($buyable && $buyable->exists()) {
792
            return $buyable->FullName;
793
        } else {
794
            return $this->getBuyableTitle();
795
        }
796
    }
797
798
    /**
799
     * @alias for getBuyableMoreDetails
800
     * @return String
801
     */
802
    public function BuyableMoreDetails()
803
    {
804
        return $this->getBuyableMoreDetails();
805
    }
806
807
    /**
808
     * @return String
809
     */
810
    public function getBuyableMoreDetails()
811
    {
812
        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...
813
            return $subtitle;
814
        }
815
        $buyable = $this->Buyable();
816
        if ($buyable && $buyable->exists()) {
817
            if ($buyable->ShortDescription) {
818
                return $buyable->ShortDescription;
819
            }
820
        }
821
822
        return _t('OrderItem.NA', 'n/a');
823
    }
824
825
    ##########################
826
    ## LINKS                ##
827
    ##########################
828
829
    /**
830
     * @return string (URLSegment)
831
     **/
832
    public function Link()
833
    {
834
        return $this->getLink();
835
    }
836
837
    /**
838
     * @return string (URLSegment)
839
     **/
840
    public function getLink()
841
    {
842
        $order = $this->Order();
843
        if ($order) {
844
            return $order->Link();
845
        } else {
846
            return  Director::absoluteURL("order-link-could-not-be-found");
847
        }
848
    }
849
850
    /**
851
     * alias
852
     * @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...
853
     */
854
    public function AbsoluteLink()
855
    {
856
        return $this->getAbsoluteLink();
857
    }
858
859
    /**
860
     * @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...
861
     */
862
    public function getAbsoluteLink()
863
    {
864
        return Director::absoluteURL($this->getLink());
865
    }
866
867
    /**
868
     * @return string (URLSegment)
869
     **/
870
    public function CheckoutLink()
871
    {
872
        return CheckoutPage::find_link();
873
    }
874
875
    ## Often Overloaded functions ##
876
877
    /**
878
     * @return string (URLSegment)
879
     **/
880
    public function AddLink()
881
    {
882
        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...
883
    }
884
885
    /**
886
     * @return string (URLSegment)
887
     **/
888
    public function IncrementLink()
889
    {
890
        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...
891
    }
892
893
    /**
894
     * @return string (URLSegment)
895
     **/
896
    public function DecrementLink()
897
    {
898
        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...
899
    }
900
901
    /**
902
     * @return string (URLSegment)
903
     **/
904
    public function RemoveLink()
905
    {
906
        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...
907
    }
908
909
    /**
910
     * @return string (URLSegment)
911
     **/
912
    public function RemoveAllLink()
913
    {
914
        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...
915
    }
916
917
    /**
918
     * @return string (URLSegment)
919
     **/
920
    public function RemoveAllAndEditLink()
921
    {
922
        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...
923
    }
924
925
    /**
926
     * @return string (URLSegment)
927
     **/
928
    public function SetSpecificQuantityItemLink($quantity)
929
    {
930
        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...
931
    }
932
933
    /**
934
     * @Todo: do we still need this?
935
     *
936
     * @return array for use as get variables in link
937
     **/
938
    protected function linkParameters()
939
    {
940
        $array = array();
941
        $updatedLinkParameters = $this->extend('updateLinkParameters', $array);
942
        if ($updatedLinkParameters !== null && is_array($updatedLinkParameters) && count($updatedLinkParameters)) {
943
            foreach ($updatedLinkParameters as $updatedLinkParametersUpdate) {
944
                $array = array_merge($array, $updatedLinkParametersUpdate);
945
            }
946
        }
947
948
        return $array;
949
    }
950
951
    public function debug()
952
    {
953
        $html = EcommerceTaskDebugCart::debug_object($this);
954
        $html .= '<ul>';
955
        $html .= '<li><b>Buyable Price:</b> '.$this->Buyable()->Price.' </li>';
956
        $html .= '<li><b>Buyable Calculated Price:</b> '.$this->Buyable()->CalculatedPrice().' </li>';
957
        $html .= '</ul>';
958
959
        return $html;
960
    }
961
}
962