OrderItem::AddLink()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
dl 0
loc 4
rs 10
c 0
b 0
f 0
nc 1
nop 0
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
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
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
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
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
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
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",
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
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
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
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
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
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);
512
        //if ($updatedUnitPrice !== null && is_array($updatedUnitPrice) && count($updatedUnitPrice)) {
513
        //    $unitPrice = $updatedUnitPrice[0];
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)
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);
0 ignored issues
show
Documentation introduced by
$current is of type boolean, but the function expects a string.

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

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

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

function acceptsInteger($int) { }

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

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
634
    }
635
636
    /**
637
     * @param string $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 = '')
642
    {
643
        $currentOrVersion = $current ? 'current' : 'version';
644
        if (!is_null($this->Order()) && !$current) {
645
            if (! $this->Order()->IsSubmitted()) {
646
                $currentOrVersion = 'current';
647
            }
648
        } elseif ($current === 'version') {
649
            $currentOrVersion = 'version';
650
        }
651
        if (!isset($this->tempBuyableStore[$currentOrVersion])) {
652
            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...
653
                user_error('There was an error retrieving the product', E_USER_NOTICE);
654
                return Product::create();
655
            }
656
            //start hack
657
            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...
658
                $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...
659
            }
660
            $turnTranslatableBackOn = false;
661
            $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...
662
            if ($className::has_extension($this->class, 'Translatable')) {
663
                Translatable::disable_locale_filter();
664
                $turnTranslatableBackOn = true;
665
            }
666
            //end hack!
667
            $obj = null;
668
            if ($currentOrVersion === 'current') {
669
                $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...
670
            }
671
            //run if current not available or current = false
672
            if (!$obj || !$current) {
673
                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...
674
                    /* @TODO: check if the version exists?? - see sample below
675
                    $versionTable = $this->BuyableClassName."_versions";
676
                    $dbConnection = DB::getConn();
677
                    if($dbConnection && $dbConnection instanceOf MySQLDatabase && $dbConnection->hasTable($versionTable)) {
678
                        $result = DB::query("
679
                            SELECT COUNT(\"ID\")
680
                            FROM \"$versionTable\"
681
                            WHERE
682
                                \"RecordID\" = ".intval($this->BuyableID)."
683
                                AND \"Version\" = ".intval($this->Version)."
684
                        ");
685
                        if($result->value()) {
686
                     */
687
                    $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...
688
                }
689
                //our second to last resort
690
                if ((!$obj) || (!$obj->exists())) {
691
                    $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...
692
                }
693
            }
694
            //our final backup
695
            if ((!$obj) || (!$obj->exists())) {
696
                $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...
697
            }
698
            if ($turnTranslatableBackOn) {
699
                Translatable::enable_locale_filter();
700
            }
701
            $this->tempBuyableStore[$currentOrVersion] = $obj;
702
        }
703
        //check for data integrity
704
        return $this->tempBuyableStore[$currentOrVersion];
705
    }
706
707
    /**
708
     * @alias for getBuyableTitle
709
     * @return string
710
     **/
711
    public function BuyableTitle()
712
    {
713
        return $this->getBuyableTitle();
714
    }
715
716
    /**
717
     * @return string
718
     **/
719
    public function getBuyableTitle()
720
    {
721
        if ($buyable = $this->Buyable()) {
722
            if ($title = $buyable->Title) {
723
                return $title;
724
            }
725
            //This should work in all cases, because ultimately, it will return #ID - see DataObject
726
            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...
727
        }
728
        return 'ERROR: product not found';
729
        user_error('No Buyable could be found for OrderItem with ID: '.$this->ID, E_USER_NOTICE);
0 ignored issues
show
Unused Code introduced by
user_error('No Buyable c...is->ID, E_USER_NOTICE); does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
730
    }
731
732
    /**
733
     * @alias for getBuyableLink
734
     * @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...
735
     */
736
    public function BuyableLink()
737
    {
738
        return $this->getBuyableLink();
739
    }
740
741
    /**
742
     *
743
     * @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...
744
     */
745
    public function getBuyableLink()
746
    {
747
        $buyable = $this->Buyable();
748
        if ($buyable && $buyable->exists()) {
749
            $order = $this->Order();
750
            if ($order && $order->IsSubmitted()) {
751
                return  Director::absoluteURL($buyable->VersionedLink());
752
            }
753
            return  Director::absoluteURL($buyable->Link());
754
        } else {
755
            return $this->getLink();
756
        }
757
    }
758
759
    /**
760
     * @alias for getBuyableExists
761
     * @return bool
762
     */
763
    public function BuyableExists()
764
    {
765
        return $this->getBuyableExists();
766
    }
767
768
    /**
769
     *
770
     * @return bool
771
     */
772
    public function getBuyableExists()
773
    {
774
        if ($buyable = $this->Buyable(true)) {
775
            $className = $buyable->ClassName;
776
            $id = $buyable->ID;
777
            return $className::get()->byID($id) ? true : false;
778
        }
779
780
        return false;
781
    }
782
783
784
    /**
785
     * @alias for getBuyableFullName
786
     * @return String
787
     */
788
    public function BuyableFullName()
789
    {
790
        return $this->getBuyableFullName();
791
    }
792
793
    /**
794
     * @return String
795
     */
796
    public function getBuyableFullName()
797
    {
798
        $buyable = $this->Buyable();
799
        if ($buyable && $buyable->exists()) {
800
            return $buyable->FullName;
801
        } else {
802
            return $this->getBuyableTitle();
803
        }
804
    }
805
806
    /**
807
     * @alias for getBuyableMoreDetails
808
     * @return String
809
     */
810
    public function BuyableMoreDetails()
811
    {
812
        return $this->getBuyableMoreDetails();
813
    }
814
815
    /**
816
     * @return String
817
     */
818
    public function getBuyableMoreDetails()
819
    {
820
        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...
821
            return $subtitle;
822
        }
823
        $buyable = $this->Buyable();
824
        if ($buyable && $buyable->exists()) {
825
            if ($buyable->ShortDescription) {
826
                return $buyable->ShortDescription;
827
            }
828
        }
829
830
        return _t('OrderItem.NA', 'n/a');
831
    }
832
833
    ##########################
834
    ## LINKS                ##
835
    ##########################
836
837
    /**
838
     * @return string (URLSegment)
839
     **/
840
    public function Link()
841
    {
842
        return $this->getLink();
843
    }
844
845
    /**
846
     * @return string (URLSegment)
847
     **/
848
    public function getLink()
849
    {
850
        $order = $this->Order();
851
        if ($order) {
852
            return $order->Link();
853
        } else {
854
            return  Director::absoluteURL("order-link-could-not-be-found");
855
        }
856
    }
857
858
    /**
859
     * alias
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 AbsoluteLink()
863
    {
864
        return $this->getAbsoluteLink();
865
    }
866
867
    /**
868
     * @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...
869
     */
870
    public function getAbsoluteLink()
871
    {
872
        return Director::absoluteURL($this->getLink());
873
    }
874
875
    /**
876
     * @return string (URLSegment)
877
     **/
878
    public function CheckoutLink()
879
    {
880
        return CheckoutPage::find_link();
881
    }
882
883
    ## Often Overloaded functions ##
884
885
    /**
886
     * @return string (URLSegment)
887
     **/
888
    public function AddLink()
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 IncrementLink()
897
    {
898
        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...
899
    }
900
901
    /**
902
     * @return string (URLSegment)
903
     **/
904
    public function DecrementLink()
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 RemoveLink()
913
    {
914
        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...
915
    }
916
917
    /**
918
     * @return string (URLSegment)
919
     **/
920
    public function RemoveAllLink()
921
    {
922
        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...
923
    }
924
925
    /**
926
     * @return string (URLSegment)
927
     **/
928
    public function RemoveAllAndEditLink()
929
    {
930
        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...
931
    }
932
933
    /**
934
     * @return string (URLSegment)
935
     **/
936
    public function SetSpecificQuantityItemLink($quantity)
937
    {
938
        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...
939
    }
940
941
    /**
942
     * @Todo: do we still need this?
943
     *
944
     * @return array for use as get variables in link
945
     **/
946
    protected function linkParameters()
947
    {
948
        $array = array();
949
        $updatedLinkParameters = $this->extend('updateLinkParameters', $array);
950
        if ($updatedLinkParameters !== null && is_array($updatedLinkParameters) && count($updatedLinkParameters)) {
951
            foreach ($updatedLinkParameters as $updatedLinkParametersUpdate) {
952
                $array = array_merge($array, $updatedLinkParametersUpdate);
953
            }
954
        }
955
956
        return $array;
957
    }
958
959
    public function debug()
960
    {
961
        $html = EcommerceTaskDebugCart::debug_object($this);
962
        $html .= '<ul>';
963
        $html .= '<li><b>Buyable Price:</b> '.$this->Buyable()->Price.' </li>';
964
        $html .= '<li><b>Buyable Calculated Price:</b> '.$this->Buyable()->CalculatedPrice().' </li>';
965
        $html .= '</ul>';
966
967
        return $html;
968
    }
969
}
970