Completed
Push — master ( ac5e72...cd4d3b )
by
unknown
03:25
created

get_money_object_from_order_currency()   D

Complexity

Conditions 10
Paths 32

Size

Total Lines 32
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 10
eloc 20
nc 32
nop 2
dl 0
loc 32
rs 4.8196
c 0
b 0
f 0

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/**
4
 * Object to manage currencies.
5
 *
6
 * @authors: Nicolaas [at] Sunny Side Up .co.nz
7
 * @package: ecommerce
8
 * @sub-package: money
9
 * Precondition : There should always be at least one currency usable.
10
 **/
11
class EcommerceCurrency extends DataObject implements EditableEcommerceObject
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.

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

namespace YourVendor;

class YourClass { }

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

Loading history...
12
{
13
    /**
14
     * standard SS variable.
15
     *
16
     * @var array
17
     */
18
    private static $db = array(
0 ignored issues
show
Unused Code introduced by
The property $db is not used and could be removed.

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

Loading history...
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
19
        'Code' => 'Varchar(3)',
20
        'Name' => 'Varchar(100)',
21
        'InUse' => 'Boolean',
22
    );
23
24
    /**
25
     * standard SS variable.
26
     *
27
     * @var array
28
     */
29
    private static $indexes = array(
0 ignored issues
show
Unused Code introduced by
The property $indexes is not used and could be removed.

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

Loading history...
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
30
        'Code' => true,
31
        'InUse' => true,
32
        'Name' => true
33
    );
34
35
    /**
36
     * standard SS variable.
37
     *
38
     * @var array
39
     */
40
    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...
Unused Code introduced by
The property $casting is not used and could be removed.

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

Loading history...
41
        'IsDefault' => 'Boolean',
42
        'IsDefaultNice' => 'Varchar',
43
        'InUseNice' => 'Varchar',
44
        'ExchangeRate' => 'Double',
45
        'DefaultSymbol' => 'Varchar',
46
        'ShortSymbol' => 'Varchar',
47
        'LongSymbol' => 'Varchar',
48
    );
49
50
    /**
51
     * standard SS variable.
52
     *
53
     * @var array
54
     */
55
    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...
Unused Code introduced by
The property $searchable_fields is not used and could be removed.

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

Loading history...
56
        'Code' => 'PartialMatchFilter',
57
        'Name' => 'PartialMatchFilter',
58
    );
59
60
    /**
61
     * standard SS variable.
62
     *
63
     * @var array
64
     */
65
    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...
Unused Code introduced by
The property $field_labels is not used and could be removed.

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

Loading history...
66
        'Code' => 'Short Code',
67
        'Name' => 'Name',
68
        'InUse' => 'It is available for use?',
69
        'ExchangeRate' => 'Exchange Rate',
70
        'ExchangeRateExplanation' => 'Exchange Rate explanation',
71
        'IsDefaultNice' => 'Is default currency for site',
72
        'DefaultSymbol' => 'Default symbol',
73
        'ShortSymbol' => 'Short symbol',
74
        'LongSymbol' => 'Long symbol',
75
    );
76
77
    /**
78
     * standard SS variable.
79
     *
80
     * @var array
81
     */
82
    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...
Unused Code introduced by
The property $summary_fields is not used and could be removed.

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

Loading history...
83
        'Code' => 'Code',
84
        'Name' => 'Name',
85
        'InUseNice' => 'Available',
86
        'IsDefaultNice' => 'Default Currency',
87
        'ExchangeRate' => 'Exchange Rate',
88
    ); //note no => for relational fields
89
90
    /**
91
     * standard SS variable.
92
     *
93
     * @var string
94
     */
95
    private static $singular_name = 'Currency';
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...
Unused Code introduced by
The property $singular_name is not used and could be removed.

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

Loading history...
96
    public function i18n_singular_name()
97
    {
98
        return _t('EcommerceCurrency.CURRENCY', 'Currency');
99
    }
100
101
    /**
102
     * standard SS variable.
103
     *
104
     * @var string
105
     */
106
    private static $plural_name = 'Currencies';
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...
Unused Code introduced by
The property $plural_name is not used and could be removed.

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

Loading history...
107
    public function i18n_plural_name()
108
    {
109
        return _t('EcommerceCurrency.CURRENCIES', 'Currencies');
110
    }
111
112
    /**
113
     * standard SS variable.
114
     *
115
     * @var string
116
     */
117
    private static $default_sort = [
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...
Unused Code introduced by
The property $default_sort is not used and could be removed.

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

Loading history...
118
        'InUse' => 'DESC',
119
        'Name' => 'ASC',
120
        'Code' => 'ASC',
121
        'ID' => 'DESC'
122
    ];
123
124
    /**
125
     * standard SS variable.
126
     *
127
     * @var array
128
     */
129
    private static $defaults = array(
0 ignored issues
show
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
Unused Code introduced by
The property $defaults is not used and could be removed.

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

Loading history...
130
        'InUse' => true
131
    );
132
133
    /**
134
     * Standard SS Method.
135
     *
136
     * @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...
137
     *
138
     * @var bool
139
     */
140
    public function canCreate($member = null)
141
    {
142
        if (! $member) {
143
            $member = Member::currentUser();
144
        }
145
        $extended = $this->extendedCan(__FUNCTION__, $member);
0 ignored issues
show
Documentation introduced by
$member is of type object<DataObject>|null, but the function expects a object<Member>|integer.

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...
146
        if ($extended !== null) {
147
            return $extended;
148
        }
149
        if (Permission::checkMember($member, Config::inst()->get('EcommerceRole', 'admin_permission_code'))) {
150
            return true;
151
        }
152
153
        return parent::canEdit($member);
0 ignored issues
show
Bug introduced by
It seems like $member defined by \Member::currentUser() on line 143 can also be of type object<DataObject>; however, DataObject::canEdit() does only seem to accept object<Member>|null, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
Comprehensibility Bug introduced by
It seems like you call parent on a different method (canEdit() instead of canCreate()). Are you sure this is correct? If so, you might want to change this to $this->canEdit().

This check looks for a call to a parent method whose name is different than the method from which it is called.

Consider the following code:

class Daddy
{
    protected function getFirstName()
    {
        return "Eidur";
    }

    protected function getSurName()
    {
        return "Gudjohnsen";
    }
}

class Son
{
    public function getFirstName()
    {
        return parent::getSurname();
    }
}

The getFirstName() method in the Son calls the wrong method in the parent class.

Loading history...
154
    }
155
156
    /**
157
     * Standard SS Method.
158
     *
159
     * @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...
160
     *
161
     * @var bool
162
     */
163
    public function canView($member = null)
164
    {
165
        if (! $member) {
166
            $member = Member::currentUser();
167
        }
168
        $extended = $this->extendedCan(__FUNCTION__, $member);
0 ignored issues
show
Documentation introduced by
$member is of type object<DataObject>|null, but the function expects a object<Member>|integer.

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...
169
        if ($extended !== null) {
170
            return $extended;
171
        }
172
        if (Permission::checkMember($member, Config::inst()->get('EcommerceRole', 'admin_permission_code'))) {
173
            return true;
174
        }
175
176
        return parent::canEdit($member);
0 ignored issues
show
Bug introduced by
It seems like $member defined by \Member::currentUser() on line 166 can also be of type object<DataObject>; however, DataObject::canEdit() does only seem to accept object<Member>|null, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
Comprehensibility Bug introduced by
It seems like you call parent on a different method (canEdit() instead of canView()). Are you sure this is correct? If so, you might want to change this to $this->canEdit().

This check looks for a call to a parent method whose name is different than the method from which it is called.

Consider the following code:

class Daddy
{
    protected function getFirstName()
    {
        return "Eidur";
    }

    protected function getSurName()
    {
        return "Gudjohnsen";
    }
}

class Son
{
    public function getFirstName()
    {
        return parent::getSurname();
    }
}

The getFirstName() method in the Son calls the wrong method in the parent class.

Loading history...
177
    }
178
179
    /**
180
     * Standard SS Method.
181
     *
182
     * @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...
183
     *
184
     * @var bool
185
     */
186
    public function canEdit($member = null)
187
    {
188
        if (! $member) {
189
            $member = Member::currentUser();
190
        }
191
        $extended = $this->extendedCan(__FUNCTION__, $member);
0 ignored issues
show
Documentation introduced by
$member is of type object<DataObject>|null, but the function expects a object<Member>|integer.

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...
192
        if ($extended !== null) {
193
            return $extended;
194
        }
195
        if (Permission::checkMember($member, Config::inst()->get('EcommerceRole', 'admin_permission_code'))) {
196
            return true;
197
        }
198
199
        return parent::canEdit($member);
0 ignored issues
show
Bug introduced by
It seems like $member defined by \Member::currentUser() on line 189 can also be of type object<DataObject>; however, DataObject::canEdit() does only seem to accept object<Member>|null, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
200
    }
201
202
    /**
203
     * Standard SS method.
204
     *
205
     * @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...
206
     *
207
     * @return bool
0 ignored issues
show
Documentation introduced by
Should the return type not be boolean|string|null?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
208
     */
209
    public function canDelete($member = null)
210
    {
211
        if (!$this->InUse && EcommerceCurrency::get()->Count() > 1) {
0 ignored issues
show
Documentation introduced by
The property InUse does not exist on object<EcommerceCurrency>. 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
            if (! $member) {
213
                $member = Member::currentUser();
214
            }
215
            $extended = $this->extendedCan(__FUNCTION__, $member);
0 ignored issues
show
Documentation introduced by
$member is of type object<DataObject>|null, but the function expects a object<Member>|integer.

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...
216
            if ($extended !== null) {
217
                return $extended;
218
            }
219
            if (Permission::checkMember($member, Config::inst()->get('EcommerceRole', 'admin_permission_code'))) {
220
                return true;
221
            }
222
223
            return parent::canEdit($member);
0 ignored issues
show
Bug introduced by
It seems like $member defined by \Member::currentUser() on line 213 can also be of type object<DataObject>; however, DataObject::canEdit() does only seem to accept object<Member>|null, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
Comprehensibility Bug introduced by
It seems like you call parent on a different method (canEdit() instead of canDelete()). Are you sure this is correct? If so, you might want to change this to $this->canEdit().

This check looks for a call to a parent method whose name is different than the method from which it is called.

Consider the following code:

class Daddy
{
    protected function getFirstName()
    {
        return "Eidur";
    }

    protected function getSurName()
    {
        return "Gudjohnsen";
    }
}

class Son
{
    public function getFirstName()
    {
        return parent::getSurname();
    }
}

The getFirstName() method in the Son calls the wrong method in the parent class.

Loading history...
224
        }
225
226
        return false;
227
    }
228
229
    /**
230
     * NOTE: when there is only one currency we return an empty DataList
231
     * as one currency is meaningless.
232
     *
233
     * @return DataList | null
0 ignored issues
show
Documentation introduced by
Should the return type not be DataList|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...
234
     */
235
    public static function ecommerce_currency_list()
236
    {
237
        $dos = EcommerceCurrency::get()
238
            ->Filter(array('InUse' => 1))
239
            ->Sort(
240
                array(
241
                    "IF(\"Code\" = '".strtoupper(EcommerceConfig::get('EcommerceCurrency', 'default_currency'))."', 0, 1)" => 'ASC',
242
                    'Name' => 'ASC',
243
                    'Code' => 'ASC',
244
                )
245
            );
246
        if ($dos->count() < 2) {
247
            return;
248
        }
249
250
        return $dos;
251
    }
252
253
    public static function get_list()
254
    {
255
        return EcommerceCurrency::get()
256
            ->filter(array('InUse' => 1))
257
            ->sort(
258
                array(
259
                    "IF(\"Code\" = '".EcommerceConfig::get('EcommerceCurrency', 'default_currency')."', 0, 1)" => 'ASC',
260
                    'Name' => 'ASC',
261
                    'Code' => 'ASC',
262
                )
263
            );
264
    }
265
266
    /**
267
     * @param float | Currency $price
268
     * @param Order $order
0 ignored issues
show
Documentation introduced by
Should the type for parameter $order not be null|Order?

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...
269
     *
270
     * @return Money
271
     */
272
    public static function get_money_object_from_order_currency($price, Order $order = null)
273
    {
274
        if ($price instanceof Currency) {
275
            $price = $price->getValue();
276
        }
277
        if (!$order) {
278
            $order = ShoppingCart::current_order();
279
        }
280
        $currency = $order->CurrencyUsed();
0 ignored issues
show
Documentation Bug introduced by
The method CurrencyUsed does not exist on object<Order>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
281
        $currencyCode = $currency->Code;
282
        if ($order) {
283
            if ($order->HasAlternativeCurrency()) {
284
                $exchangeRate = $order->ExchangeRate;
0 ignored issues
show
Documentation introduced by
The property ExchangeRate does not exist on object<Order>. Since you implemented __set, maybe consider adding a @property annotation.

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

<?php

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

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

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

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

}

Since the property has write access only, you can use the @property-write annotation instead.

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

See also the PhpDoc documentation for @property.

Loading history...
285
                if ($exchangeRate && $exchangeRate != 1) {
286
                    $price = $exchangeRate * $price;
287
                }
288
            }
289
        }
290
291
        $updatedCurrencyCode = Injector::inst()->get('EcommerceCurrency')->extend('updateCurrencyCodeForMoneyObect', $currencyCode);
292
        if ($updatedCurrencyCode !== null && is_array($updatedCurrencyCode) && count($updatedCurrencyCode)) {
293
            $currencyCode = $updatedCurrencyCode[0];
294
        }
295
296
        return DBField::create_field(
297
            'Money',
298
            array(
299
                'Amount' => $price,
300
                'Currency' => $currencyCode
301
            )
302
        );
303
    }
304
305
    /**
306
     * returns the default currency.
307
     */
308
    public static function default_currency()
309
    {
310
        return DataObject::get_one(
311
            'EcommerceCurrency',
312
            array(
313
                'Code' => trim(strtolower(EcommerceConfig::get('EcommerceCurrency', 'default_currency'))),
314
                'InUse' => 1,
315
            )
316
        );
317
    }
318
319
    /**
320
     * returns the default currency as Code.
321
     *
322
     * @return string - e.g. NZD
323
     */
324
    public static function default_currency_code()
325
    {
326
        $obj = self::default_currency();
327
        if ($obj) {
328
            $code = $obj->Code;
329
        }
330
        if (!$code) {
0 ignored issues
show
Bug introduced by
The variable $code does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
331
            $code = EcommerceConfig::get('EcommerceCurrency', 'default_currency');
332
        }
333
        if (!$code) {
334
            $code = 'NZD';
335
        }
336
337
        return strtoupper($code);
338
    }
339
340
    /**
341
     * @return int
0 ignored issues
show
Documentation introduced by
Should the return type not be integer|double?

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...
342
     */
343
    public static function default_currency_id()
344
    {
345
        $currency = self::default_currency();
346
347
        return $currency ? $currency->ID : 0;
348
    }
349
350
    /**
351
     * Only returns a currency when it is a valid currency.
352
     *
353
     * @param string $currencyCode - the code of the currency, e.g. nzd
354
     *
355
     * @return EcommerceCurrency | Null
356
     */
357
    public static function get_one_from_code($currencyCode)
358
    {
359
        return DataObject::get_one(
360
            'EcommerceCurrency',
361
            array(
362
                'Code' => trim(strtoupper($currencyCode)),
363
                'InUse' => 1,
364
            )
365
        );
366
    }
367
368
    /**
369
     * STANDARD SILVERSTRIPE STUFF.
370
     **/
371
    public function getCMSFields()
372
    {
373
        $fields = parent::getCMSFields();
374
        $fieldLabels = $this->fieldLabels();
375
        $codeField = $fields->dataFieldByName('Code');
376
        $codeField->setRightTitle('e.g. NZD, use uppercase codes');
377
        $titleField = $fields->dataFieldByName('Name');
378
        $titleField->setRightTitle('e.g. New Zealand Dollar');
379
        $fields->addFieldToTab('Root.Main', new ReadonlyField('IsDefaulNice', $fieldLabels['IsDefaultNice'], $this->getIsDefaultNice()));
380
        if (!$this->isDefault()) {
381
            $fields->addFieldToTab('Root.Main', new ReadonlyField('ExchangeRate', $fieldLabels['ExchangeRate'], $this->ExchangeRate()));
382
            $fields->addFieldToTab('Root.Main', new ReadonlyField('ExchangeRateExplanation', $fieldLabels['ExchangeRateExplanation'], $this->ExchangeRateExplanation()));
383
        }
384
        $fields->addFieldsToTab('Root.Main', array(
385
            new HeaderField('Symbols'),
386
            new ReadonlyField('DefaultSymbol', 'Default'),
387
            new ReadonlyField('ShortSymbol', 'Short'),
388
            new ReadonlyField('LongSymbol', 'Long'),
389
        ));
390
391
        return $fields;
392
    }
393
394
    /**
395
     * link to edit the record.
396
     *
397
     * @param string | Null $action - e.g. edit
398
     *
399
     * @return string
0 ignored issues
show
Documentation introduced by
Should the return type not be null|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...
400
     */
401
    public function CMSEditLink($action = null)
402
    {
403
        return CMSEditLinkAPI::find_edit_link_for_object($this, $action);
404
    }
405
406
    public function DefaultSymbol()
407
    {
408
        return $this->getDefaultSymbol();
409
    }
410
    public function getDefaultSymbol()
411
    {
412
        return EcommerceMoney::get_default_symbol($this->Code);
0 ignored issues
show
Documentation introduced by
The property Code does not exist on object<EcommerceCurrency>. 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...
413
    }
414
415
    public function ShortSymbol()
416
    {
417
        return $this->getShortSymbol();
418
    }
419
    public function getShortSymbol()
420
    {
421
        return EcommerceMoney::get_short_symbol($this->Code);
0 ignored issues
show
Documentation introduced by
The property Code does not exist on object<EcommerceCurrency>. 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...
422
    }
423
424
    public function LongSymbol()
425
    {
426
        return $this->getLongSymbol();
427
    }
428
    public function getLongSymbol()
429
    {
430
        return EcommerceMoney::get_long_symbol($this->Code);
0 ignored issues
show
Documentation introduced by
The property Code does not exist on object<EcommerceCurrency>. 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...
431
    }
432
433
    /**
434
     * casted variable method.
435
     *
436
     * @return bool
437
     */
438
    public function IsDefault()
439
    {
440
        return $this->getIsDefault();
441
    }
442
    public function getIsDefault()
443
    {
444
        $outcome = false;
0 ignored issues
show
Unused Code introduced by
$outcome is not used, you could remove the assignment.

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

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

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

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

Loading history...
445
        if ($this->exists()) {
446
            if (!$this->Code) {
0 ignored issues
show
Documentation introduced by
The property Code does not exist on object<EcommerceCurrency>. 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...
447
                user_error('This currency (ID = '.$this->ID.') does not have a code ');
448
            }
449
        }
450
451
        return strtoupper($this->Code) ==  strtoupper(EcommerceConfig::get('EcommerceCurrency', 'default_currency'));
0 ignored issues
show
Documentation introduced by
The property Code does not exist on object<EcommerceCurrency>. 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...
452
    }
453
454
    /**
455
     * casted variable method.
456
     *
457
     * @return string
458
     */
459
    public function IsDefaultNice()
460
    {
461
        return $this->getIsDefaultNice();
462
    }
463
    public function getIsDefaultNice()
464
    {
465
        if ($this->getIsDefault()) {
466
            return _t('EcommerceCurrency.YES', 'Yes');
467
        } else {
468
            return _t('EcommerceCurrency.NO', 'No');
469
        }
470
    }
471
472
    /**
473
     * casted variable method.
474
     *
475
     * @return string
476
     */
477
    public function InUseNice()
478
    {
479
        return $this->getInUseNice();
480
    }
481
    public function getInUseNice()
482
    {
483
        if ($this->InUse) {
0 ignored issues
show
Documentation introduced by
The property InUse does not exist on object<EcommerceCurrency>. 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...
484
            return _t('EcommerceCurrency.YES', 'Yes');
485
        } else {
486
            return _t('EcommerceCurrency.NO', 'No');
487
        }
488
    }
489
490
    /**
491
     * casted variable.
492
     * @alias for getExchangeRate
493
     *
494
     * @return float
495
     */
496
    public function ExchangeRate()
497
    {
498
        return $this->getExchangeRate();
499
    }
500
501
    /**
502
     *
503
     * @return float
504
     */
505
    public function getExchangeRate()
506
    {
507
        $exchangeRateProviderClassName = EcommerceConfig::get('EcommerceCurrency', 'exchange_provider_class');
508
        $exchangeRateProvider = new $exchangeRateProviderClassName();
509
510
        return $exchangeRateProvider->ExchangeRate(EcommerceConfig::get('EcommerceCurrency', 'default_currency'), $this->Code);
0 ignored issues
show
Documentation introduced by
The property Code does not exist on object<EcommerceCurrency>. 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...
511
    }
512
513
    /**
514
     * casted variable.
515
     *
516
     * @return string
0 ignored issues
show
Documentation introduced by
Should the return type not be string|null?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
517
     */
518
    public function ExchangeRateExplanation()
519
    {
520
        return $this->getExchangeRateExplanation();
521
    }
522
523
    /**
524
     *
525
     *
526
     * @return string
0 ignored issues
show
Documentation introduced by
Should the return type not be string|null?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
527
     */
528
    public function getExchangeRateExplanation()
529
    {
530
        $string = '1 '.EcommerceConfig::get('EcommerceCurrency', 'default_currency').' = '.round($this->getExchangeRate(), 3).' '.$this->Code;
0 ignored issues
show
Documentation introduced by
The property Code does not exist on object<EcommerceCurrency>. 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...
531
        $exchangeRate = $this->getExchangeRate();
532
        $exchangeRateError = '';
533
        if (!$exchangeRate) {
534
            $exchangeRate = 1;
535
            $exchangeRateError = _t('EcommerceCurrency.EXCHANGE_RATE_ERROR', 'Error in exchange rate. ');
536
        }
537
        $string .= ', 1 '.$this->Code.' = '.round(1 / $exchangeRate, 3).' '.EcommerceConfig::get('EcommerceCurrency', 'default_currency').'. '.$exchangeRateError;
0 ignored issues
show
Documentation introduced by
The property Code does not exist on object<EcommerceCurrency>. 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...
538
    }
539
540
    /**
541
     * @return bool
542
     */
543
    public function IsCurrent()
544
    {
545
        $order = ShoppingCart::current_order();
546
547
        return $order ? $order->CurrencyUsedID == $this->ID : false;
0 ignored issues
show
Documentation introduced by
The property CurrencyUsedID 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...
548
    }
549
550
    /**
551
     * Returns the link that can be used in the shopping cart to
552
     * set the preferred currency to this one.
553
     * For example: /shoppingcart/setcurrency/nzd/
554
     * Dont be fooled by the set_ part in the set_currency_link....
555
     *
556
     * @return string
557
     */
558
    public function Link()
559
    {
560
        return ShoppingCart_Controller::set_currency_link($this->Code);
0 ignored issues
show
Documentation introduced by
The property Code does not exist on object<EcommerceCurrency>. 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...
561
    }
562
563
    /**
564
     * returns the link type.
565
     *
566
     * @return string (link | default | current)
567
     */
568
    public function LinkingMode()
569
    {
570
        $linkingMode = '';
571
        if ($this->IsDefault()) {
572
            $linkingMode .= ' default';
573
        }
574
        if ($this->IsCurrent()) {
575
            $linkingMode .= ' current';
576
        } else {
577
            $linkingMode .= ' link';
578
        }
579
580
        return $linkingMode;
581
    }
582
583
    public function validate()
584
    {
585
        $result = parent::validate();
586
        $errors = array();
587
        if (!$this->Code || mb_strlen($this->Code) != 3) {
0 ignored issues
show
Documentation introduced by
The property Code does not exist on object<EcommerceCurrency>. 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...
588
            $errors[] = 'The code must be 3 characters long.';
589
        }
590
        if (!$this->Name) {
0 ignored issues
show
Documentation introduced by
The property Name does not exist on object<EcommerceCurrency>. 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...
591
            $errors[] = 'The name is required.';
592
        }
593
        if (!count($errors)) {
594
            $this->Code = strtoupper($this->Code);
0 ignored issues
show
Documentation introduced by
The property Code does not exist on object<EcommerceCurrency>. 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...
Documentation introduced by
The property Code does not exist on object<EcommerceCurrency>. 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...
595
            // Check that there are no 2 same code currencies in use
596
            if ($this->isChanged('Code')) {
597
                if (EcommerceCurrency::get()->where("UPPER(\"Code\") = '".$this->Code."'")->exclude('ID', intval($this->ID) - 0)->count()) {
0 ignored issues
show
Documentation introduced by
The property Code does not exist on object<EcommerceCurrency>. 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...
598
                    $errors[] = "There is alreay another currency in use which code is '$this->Code'.";
0 ignored issues
show
Documentation introduced by
The property Code does not exist on object<EcommerceCurrency>. 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...
599
                }
600
            }
601
        }
602
        foreach ($errors as $error) {
603
            $result->error($error);
604
        }
605
606
        return $result;
607
    }
608
609
    /**
610
     * Standard SS Method
611
     * Adds the default currency.
612
     */
613
    public function populateDefaults()
614
    {
615
        parent::populateDefaults();
616
        $this->InUse = true;
0 ignored issues
show
Documentation introduced by
The property InUse does not exist on object<EcommerceCurrency>. 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...
617
    }
618
619
    public function onBeforeWrite()
620
    {
621
        parent::onBeforeWrite();
622
        // Check that there is always at least one currency in use
623
        $this->Code = strtoupper($this->Code);
0 ignored issues
show
Documentation introduced by
The property Code does not exist on object<EcommerceCurrency>. 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...
Documentation introduced by
The property Code does not exist on object<EcommerceCurrency>. 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...
624
        if (!$this->InUse) {
0 ignored issues
show
Documentation introduced by
The property InUse does not exist on object<EcommerceCurrency>. 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...
625
            $list = self::get_list();
626
            if ($list->count() == 0 || ($list->Count() == 1 && $list->First()->ID == $this->ID)) {
627
                $this->InUse = true;
0 ignored issues
show
Documentation introduced by
The property InUse does not exist on object<EcommerceCurrency>. 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...
628
            }
629
        }
630
    }
631
632
    /**
633
     * Standard SS Method
634
     * Adds the default currency.
635
     */
636
    public function requireDefaultRecords()
637
    {
638
        parent::requireDefaultRecords();
639
        if (! self::default_currency()) {
640
            self::create_new(EcommerceConfig::get('EcommerceCurrency', 'default_currency'));
641
        }
642
    }
643
644
    /**
645
     * checks if a currency exists, creates it and returns it.
646
     *
647
     * @param string $code
648
     * @param string $name OPTIONAL
649
     */
650
    public static function create_new($code, $name = '')
651
    {
652
        $code = trim(strtoupper($code));
653
        if (!$name) {
654
            $currencies = Config::inst()->get('EcommerceCurrency', 'currencies');
655
            if (isset($currencies[$code])) {
656
                $name = $currencies[$code];
657
            } else {
658
                $name = $code;
659
            }
660
        }
661
        $name = ucwords($name);
662
        $currency = DataObject::get_one(
663
            'EcommerceCurrency',
664
            array('Code' => $code),
665
            $cacheDataObjectGetOne = false
666
        );
667
        if ($currency) {
668
            $currency->Name = $name;
669
            $currency->InUse = true;
670
        } else {
671
            $currency = EcommerceCurrency::create(
672
                array(
673
                'Code' => $code,
674
                'Name' => $name,
675
                'InUse' => true,
676
                )
677
            );
678
        }
679
        $valid = $currency->write();
680
        if ($valid) {
681
            return $currency;
682
        }
683
    }
684
685
    /**
686
     * Debug helper method.
687
     * Can be called from /shoppingcart/debug/.
688
     *
689
     * @return string
690
     */
691
    public function debug()
692
    {
693
        return EcommerceTaskDebugCart::debug_object($this);
694
    }
695
696
    private static $currencies = array(
0 ignored issues
show
Unused Code introduced by
The property $currencies is not used and could be removed.

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

Loading history...
697
        'AFA' => 'afghanistan afghanis',
698
        'ALL' => 'albania leke',
699
        'DZD' => 'algeria dinars',
700
        'ARS' => 'argentina pesos',
701
        'AUD' => 'australia dollars',
702
        'ATS' => 'austria schillings*',
703
        'BSD' => 'bahamas dollars',
704
        'BHD' => 'bahrain dinars',
705
        'BDT' => 'bangladesh taka',
706
        'BBD' => 'barbados dollars',
707
        'BEF' => 'belgium francs*',
708
        'BMD' => 'bermuda dollars',
709
        'BRL' => 'brazil reais',
710
        'BGN' => 'bulgaria leva',
711
        'CAD' => 'canada dollars',
712
        'XOF' => 'cfa bceao francs',
713
        'XAF' => 'cfa beac francs',
714
        'CLP' => 'chile pesos',
715
        'CNY' => 'china yuan renminbi',
716
        'COP' => 'colombia pesos',
717
        'CRC' => 'costa rica colones',
718
        'HRK' => 'croatia kuna',
719
        'CYP' => 'cyprus pounds',
720
        'CZK' => 'czech republic koruny',
721
        'DKK' => 'denmark kroner',
722
        'DOP' => 'dominican republic pesos',
723
        'XCD' => 'eastern caribbean dollars',
724
        'EGP' => 'egypt pounds',
725
        'EEK' => 'estonia krooni',
726
        'EUR' => 'euro',
727
        'FJD' => 'fiji dollars',
728
        'DEM' => 'germany deutsche marks*',
729
        'XAU' => 'gold ounces',
730
        'NLG' => 'holland (netherlands) guilders*',
731
        'HKD' => 'hong kong dollars',
732
        'HUF' => 'hungary forint',
733
        'ISK' => 'iceland kronur',
734
        'XDR' => 'imf special drawing right',
735
        'INR' => 'india rupees',
736
        'IDR' => 'indonesia rupiahs',
737
        'IRR' => 'iran rials',
738
        'IQD' => 'iraq dinars',
739
        'ILS' => 'israel new shekels',
740
        'JMD' => 'jamaica dollars',
741
        'JPY' => 'japan yen',
742
        'JOD' => 'jordan dinars',
743
        'KES' => 'kenya shillings',
744
        'KRW' => 'korea (south) won',
745
        'KWD' => 'kuwait dinars',
746
        'LBP' => 'lebanon pounds',
747
        'MYR' => 'malaysia ringgits',
748
        'MTL' => 'malta liri',
749
        'MUR' => 'mauritius rupees',
750
        'MXN' => 'mexico pesos',
751
        'MAD' => 'morocco dirhams',
752
        'NZD' => 'new zealand dollars',
753
        'NOK' => 'norway kroner',
754
        'OMR' => 'oman rials',
755
        'PKR' => 'pakistan rupees',
756
        'XPD' => 'palladium ounces',
757
        'PEN' => 'peru nuevos soles',
758
        'PHP' => 'philippines pesos',
759
        'PLN' => 'poland zlotych',
760
        'QAR' => 'qatar riyals',
761
        'ROL' => 'romania lei',
762
        'RUB' => 'russia rubles',
763
        'SAR' => 'saudi arabia riyals',
764
        'XAG' => 'silver ounces',
765
        'SGD' => 'singapore dollars',
766
        'SKK' => 'slovakia koruny',
767
        'SIT' => 'slovenia tolars',
768
        'ZAR' => 'south africa rand',
769
        'KRW' => 'south korea won',
770
        'LKR' => 'sri lanka rupees',
771
        'SDD' => 'sudan dinars',
772
        'SEK' => 'sweden kronor',
773
        'CHF' => 'switzerland francs',
774
        'TWD' => 'taiwan new dollars',
775
        'THB' => 'thailand baht',
776
        'TTD' => 'trinidad and tobago dollars',
777
        'TND' => 'tunisia dinars',
778
        'TRY' => 'turkey new lira',
779
        'AED' => 'united arab emirates dirhams',
780
        'gbp' => 'united kingdom pounds',
781
        'USD' => 'united states dollars',
782
        'VEB' => 'venezuela bolivares',
783
        'VND' => 'vietnam dong',
784
        'ZMK' => 'zambia kwacha',
785
    );
786
}
787