Completed
Push — master ( a22c99...7ec1b3 )
by Nicolaas
03:46
created

get_money_object_from_order_currency()   C

Complexity

Conditions 7
Paths 16

Size

Total Lines 26
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 7
eloc 16
nc 16
nop 2
dl 0
loc 26
rs 6.7272
c 0
b 0
f 0
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
    );
32
33
    /**
34
     * standard SS variable.
35
     *
36
     * @var array
37
     */
38
    private static $casting = array(
0 ignored issues
show
Unused Code introduced by
The property $casting is not used and could be removed.

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

Loading history...
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
39
        'IsDefault' => 'Boolean',
40
        'IsDefaultNice' => 'Varchar',
41
        'InUseNice' => 'Varchar',
42
        'ExchangeRate' => 'Double',
43
        'DefaultSymbol' => 'Varchar',
44
        'ShortSymbol' => 'Varchar',
45
        'LongSymbol' => 'Varchar',
46
    );
47
48
    /**
49
     * standard SS variable.
50
     *
51
     * @var array
52
     */
53
    private static $searchable_fields = array(
0 ignored issues
show
Unused Code introduced by
The property $searchable_fields is not used and could be removed.

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

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

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

Loading history...
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
64
        'Code' => 'Short Code',
65
        'Name' => 'Name',
66
        'InUse' => 'It is available for use?',
67
        'ExchangeRate' => 'Exchange Rate',
68
        'ExchangeRateExplanation' => 'Exchange Rate explanation',
69
        'IsDefaultNice' => 'Is default currency for site',
70
        'DefaultSymbol' => 'Default symbol',
71
        'ShortSymbol' => 'Short symbol',
72
        'LongSymbol' => 'Long symbol',
73
    );
74
75
    /**
76
     * standard SS variable.
77
     *
78
     * @var array
79
     */
80
    private static $summary_fields = array(
0 ignored issues
show
Unused Code introduced by
The property $summary_fields is not used and could be removed.

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

Loading history...
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
81
        'Code' => 'Code',
82
        'Name' => 'Name',
83
        'InUseNice' => 'Available',
84
        'IsDefaultNice' => 'Default Currency',
85
        'ExchangeRate' => 'Exchange Rate',
86
    ); //note no => for relational fields
87
88
    /**
89
     * standard SS variable.
90
     *
91
     * @var string
92
     */
93
    private static $singular_name = 'Currency';
0 ignored issues
show
Unused Code introduced by
The property $singular_name is not used and could be removed.

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

Loading history...
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
94
    public function i18n_singular_name()
95
    {
96
        return _t('EcommerceCurrency.CURRENCY', 'Currency');
97
    }
98
99
    /**
100
     * standard SS variable.
101
     *
102
     * @var string
103
     */
104
    private static $plural_name = 'Currencies';
0 ignored issues
show
Unused Code introduced by
The property $plural_name is not used and could be removed.

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

Loading history...
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
105
    public function i18n_plural_name()
106
    {
107
        return _t('EcommerceCurrency.CURRENCIES', 'Currencies');
108
    }
109
110
    /**
111
     * standard SS variable.
112
     *
113
     * @var string
114
     */
115
    private static $default_sort = '"InUse" DESC, "Name" ASC, "Code" ASC';
0 ignored issues
show
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...
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
116
117
    /**
118
     * standard SS variable.
119
     *
120
     * @var array
121
     */
122
    private static $defaults = array(
0 ignored issues
show
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...
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
123
        'InUse' => true,
124
    );
125
126
    /**
127
     * Standard SS Method.
128
     *
129
     * @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...
130
     *
131
     * @var bool
132
     */
133
    public function canCreate($member = null)
134
    {
135
        if (! $member) {
136
            $member = Member::currentUser();
137
        }
138
        $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...
139
        if ($extended !== null) {
140
            return $extended;
141
        }
142
        if (Permission::checkMember($member, Config::inst()->get('EcommerceRole', 'admin_permission_code'))) {
143
            return true;
144
        }
145
146
        return parent::canEdit($member);
0 ignored issues
show
Bug introduced by
It seems like $member defined by \Member::currentUser() on line 136 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...
147
    }
148
149
    /**
150
     * Standard SS Method.
151
     *
152
     * @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...
153
     *
154
     * @var bool
155
     */
156
    public function canView($member = null)
157
    {
158
        if (! $member) {
159
            $member = Member::currentUser();
160
        }
161
        $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...
162
        if ($extended !== null) {
163
            return $extended;
164
        }
165
        if (Permission::checkMember($member, Config::inst()->get('EcommerceRole', 'admin_permission_code'))) {
166
            return true;
167
        }
168
169
        return parent::canEdit($member);
0 ignored issues
show
Bug introduced by
It seems like $member defined by \Member::currentUser() on line 159 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...
170
    }
171
172
    /**
173
     * Standard SS Method.
174
     *
175
     * @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...
176
     *
177
     * @var bool
178
     */
179
    public function canEdit($member = null)
180
    {
181
        if (! $member) {
182
            $member = Member::currentUser();
183
        }
184
        $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...
185
        if ($extended !== null) {
186
            return $extended;
187
        }
188
        if (Permission::checkMember($member, Config::inst()->get('EcommerceRole', 'admin_permission_code'))) {
189
            return true;
190
        }
191
192
        return parent::canEdit($member);
0 ignored issues
show
Bug introduced by
It seems like $member defined by \Member::currentUser() on line 182 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...
193
    }
194
195
    /**
196
     * Standard SS method.
197
     *
198
     * @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...
199
     *
200
     * @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...
201
     */
202
    public function canDelete($member = null)
203
    {
204
        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...
205
            if (! $member) {
206
                $member = Member::currentUser();
207
            }
208
            $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...
209
            if ($extended !== null) {
210
                return $extended;
211
            }
212
            if (Permission::checkMember($member, Config::inst()->get('EcommerceRole', 'admin_permission_code'))) {
213
                return true;
214
            }
215
216
            return parent::canEdit($member);
0 ignored issues
show
Bug introduced by
It seems like $member defined by \Member::currentUser() on line 206 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...
217
        }
218
219
        return false;
220
    }
221
222
    /**
223
     * NOTE: when there is only one currency we return an empty DataList
224
     * as one currency is meaningless.
225
     *
226
     * @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...
227
     */
228
    public static function ecommerce_currency_list()
229
    {
230
        $dos = EcommerceCurrency::get()
231
            ->Filter(array('InUse' => 1))
232
            ->Sort(
233
                array(
234
                    "IF(\"Code\" = '".strtoupper(EcommerceConfig::get('EcommerceCurrency', 'default_currency'))."', 0, 1)" => 'ASC',
235
                    'Name' => 'ASC',
236
                    'Code' => 'ASC',
237
                )
238
            );
239
        if ($dos->count() < 2) {
240
            return;
241
        }
242
243
        return $dos;
244
    }
245
246
    public static function get_list()
247
    {
248
        return EcommerceCurrency::get()
249
            ->filter(array('InUse' => 1))
250
            ->sort(
251
                array(
252
                    "IF(\"Code\" = '".EcommerceConfig::get('EcommerceCurrency', 'default_currency')."', 0, 1)" => 'ASC',
253
                    'Name' => 'ASC',
254
                    'Code' => 'ASC',
255
                )
256
            );
257
    }
258
259
    /**
260
     * @param float | Currency $price
261
     * @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...
262
     *
263
     * @return Money
264
     */
265
    public static function get_money_object_from_order_currency($price, Order $order = null)
266
    {
267
        if ($price instanceof Currency) {
268
            $price = $price->getValue();
269
        }
270
        if (!$order) {
271
            $order = ShoppingCart::current_order();
272
        }
273
        $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...
274
        if ($order) {
275
            if ($order->HasAlternativeCurrency()) {
276
                $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...
277
                if ($exchangeRate && $exchangeRate != 1) {
278
                    $price = $exchangeRate * $price;
279
                }
280
            }
281
        }
282
283
        return DBField::create_field(
284
            'Money',
285
            array(
286
                'Amount' => $price,
287
                'Currency' => $currency->Code
288
            )
289
        );
290
    }
291
292
    /**
293
     * returns the default currency.
294
     */
295
    public static function default_currency()
296
    {
297
        return DataObject::get_one(
298
            'EcommerceCurrency',
299
            array(
300
                'Code' => trim(strtolower(EcommerceConfig::get('EcommerceCurrency', 'default_currency'))),
301
                'InUse' => 1,
302
            )
303
        );
304
    }
305
306
    /**
307
     * returns the default currency as Code.
308
     *
309
     * @return string - e.g. NZD
310
     */
311
    public static function default_currency_code()
312
    {
313
        $obj = self::default_currency();
314
        if ($obj) {
315
            $code = $obj->Code;
316
        }
317
        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...
318
            $code = EcommerceConfig::get('EcommerceCurrency', 'default_currency');
319
        }
320
        if (!$code) {
321
            $code = 'NZD';
322
        }
323
324
        return strtoupper($code);
325
    }
326
327
    /**
328
     * @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...
329
     */
330
    public static function default_currency_id()
331
    {
332
        $currency = self::default_currency();
333
334
        return $currency ? $currency->ID : 0;
335
    }
336
337
    /**
338
     * Only returns a currency when it is a valid currency.
339
     *
340
     * @param string $currencyCode - the code of the currency, e.g. nzd
341
     *
342
     * @return EcommerceCurrency | Null
343
     */
344
    public static function get_one_from_code($currencyCode)
345
    {
346
        return DataObject::get_one(
347
            'EcommerceCurrency',
348
            array(
349
                'Code' => trim(strtoupper($currencyCode)),
350
                'InUse' => 1,
351
            )
352
        );
353
    }
354
355
    /**
356
     * STANDARD SILVERSTRIPE STUFF.
357
     **/
358
    public function getCMSFields()
359
    {
360
        $fields = parent::getCMSFields();
361
        $fieldLabels = $this->fieldLabels();
362
        $codeField = $fields->dataFieldByName('Code');
363
        $codeField->setRightTitle('e.g. NZD, use uppercase codes');
364
        $titleField = $fields->dataFieldByName('Name');
365
        $titleField->setRightTitle('e.g. New Zealand Dollar');
366
        $fields->addFieldToTab('Root.Main', new ReadonlyField('IsDefaulNice', $fieldLabels['IsDefaultNice'], $this->getIsDefaultNice()));
367
        if (!$this->isDefault()) {
368
            $fields->addFieldToTab('Root.Main', new ReadonlyField('ExchangeRate', $fieldLabels['ExchangeRate'], $this->ExchangeRate()));
369
            $fields->addFieldToTab('Root.Main', new ReadonlyField('ExchangeRateExplanation', $fieldLabels['ExchangeRateExplanation'], $this->ExchangeRateExplanation()));
370
        }
371
        $fields->addFieldsToTab('Root.Main', array(
372
            new HeaderField('Symbols'),
373
            new ReadonlyField('DefaultSymbol', 'Default'),
374
            new ReadonlyField('ShortSymbol', 'Short'),
375
            new ReadonlyField('LongSymbol', 'Long'),
376
        ));
377
378
        return $fields;
379
    }
380
381
    /**
382
     * link to edit the record.
383
     *
384
     * @param string | Null $action - e.g. edit
385
     *
386
     * @return string
387
     */
388
    public function CMSEditLink($action = null)
389
    {
390
        return CMSEditLinkAPI::find_edit_link_for_object($this, $action);
391
    }
392
393
    public function DefaultSymbol()
394
    {
395
        return $this->getDefaultSymbol();
396
    }
397
    public function getDefaultSymbol()
398
    {
399
        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...
400
    }
401
402
    public function ShortSymbol()
403
    {
404
        return $this->getShortSymbol();
405
    }
406
    public function getShortSymbol()
407
    {
408
        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...
409
    }
410
411
    public function LongSymbol()
412
    {
413
        return $this->getLongSymbol();
414
    }
415
    public function getLongSymbol()
416
    {
417
        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...
418
    }
419
420
    /**
421
     * casted variable method.
422
     *
423
     * @return bool
424
     */
425
    public function IsDefault()
426
    {
427
        return $this->getIsDefault();
428
    }
429
    public function getIsDefault()
430
    {
431
        $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...
432
        if ($this->exists()) {
433
            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...
434
                user_error('This currency (ID = '.$this->ID.') does not have a code ');
435
            }
436
        }
437
438
        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...
439
    }
440
441
    /**
442
     * casted variable method.
443
     *
444
     * @return string
445
     */
446
    public function IsDefaultNice()
447
    {
448
        return $this->getIsDefaultNice();
449
    }
450
    public function getIsDefaultNice()
451
    {
452
        if ($this->getIsDefault()) {
453
            return _t('EcommerceCurrency.YES', 'Yes');
454
        } else {
455
            return _t('EcommerceCurrency.NO', 'No');
456
        }
457
    }
458
459
    /**
460
     * casted variable method.
461
     *
462
     * @return string
463
     */
464
    public function InUseNice()
465
    {
466
        return $this->getInUseNice();
467
    }
468
    public function getInUseNice()
469
    {
470
        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...
471
            return _t('EcommerceCurrency.YES', 'Yes');
472
        } else {
473
            return _t('EcommerceCurrency.NO', 'No');
474
        }
475
    }
476
477
    /**
478
     * casted variable.
479
     * @alias for getExchangeRate
480
     *
481
     * @return float
482
     */
483
    public function ExchangeRate()
484
    {
485
        return $this->getExchangeRate();
486
    }
487
488
    /**
489
     *
490
     * @return float
491
     */
492
    public function getExchangeRate()
493
    {
494
        $exchangeRateProviderClassName = EcommerceConfig::get('EcommerceCurrency', 'exchange_provider_class');
495
        $exchangeRateProvider = new $exchangeRateProviderClassName();
496
497
        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...
498
    }
499
500
    /**
501
     * casted variable.
502
     *
503
     * @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...
504
     */
505
    public function ExchangeRateExplanation()
506
    {
507
        return $this->getExchangeRateExplanation();
508
    }
509
510
    /**
511
     *
512
     *
513
     * @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...
514
     */
515
    public function getExchangeRateExplanation()
516
    {
517
        $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...
518
        $exchangeRate = $this->getExchangeRate();
519
        $exchangeRateError = '';
520
        if (!$exchangeRate) {
521
            $exchangeRate = 1;
522
            $exchangeRateError = _t('EcommerceCurrency.EXCHANGE_RATE_ERROR', 'Error in exchange rate. ');
523
        }
524
        $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...
525
    }
526
527
    /**
528
     * @return bool
529
     */
530
    public function IsCurrent()
531
    {
532
        $order = ShoppingCart::current_order();
533
534
        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...
535
    }
536
537
    /**
538
     * Returns the link that can be used in the shopping cart to
539
     * set the preferred currency to this one.
540
     * For example: /shoppingcart/setcurrency/nzd/
541
     * Dont be fooled by the set_ part in the set_currency_link....
542
     *
543
     * @return string
544
     */
545
    public function Link()
546
    {
547
        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...
548
    }
549
550
    /**
551
     * returns the link type.
552
     *
553
     * @return string (link | default | current)
554
     */
555
    public function LinkingMode()
556
    {
557
        $linkingMode = '';
558
        if ($this->IsDefault()) {
559
            $linkingMode .= ' default';
560
        }
561
        if ($this->IsCurrent()) {
562
            $linkingMode .= ' current';
563
        } else {
564
            $linkingMode .= ' link';
565
        }
566
567
        return $linkingMode;
568
    }
569
570
    public function validate()
571
    {
572
        $result = parent::validate();
573
        $errors = array();
574
        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...
575
            $errors[] = 'The code must be 3 characters long.';
576
        }
577
        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...
578
            $errors[] = 'The name is required.';
579
        }
580
        if (!count($errors)) {
581
            $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...
582
            // Check that there are no 2 same code currencies in use
583
            if ($this->isChanged('Code')) {
584
                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...
585
                    $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...
586
                }
587
            }
588
        }
589
        foreach ($errors as $error) {
590
            $result->error($error);
591
        }
592
593
        return $result;
594
    }
595
596
    /**
597
     * Standard SS Method
598
     * Adds the default currency.
599
     */
600
    public function populateDefaults()
601
    {
602
        parent::populateDefaults();
603
        $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...
604
    }
605
606
    public function onBeforeWrite()
607
    {
608
        parent::onBeforeWrite();
609
        // Check that there is always at least one currency in use
610
        $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...
611
        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...
612
            $list = self::get_list();
613
            if ($list->count() == 0 || ($list->Count() == 1 && $list->First()->ID == $this->ID)) {
614
                $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...
615
            }
616
        }
617
    }
618
619
    /**
620
     * Standard SS Method
621
     * Adds the default currency.
622
     */
623
    public function requireDefaultRecords()
624
    {
625
        parent::requireDefaultRecords();
626
        $currency = self::default_currency();
627
        if (!$currency) {
628
            self::create_new(EcommerceConfig::get('EcommerceCurrency', 'default_currency'));
629
        }
630
    }
631
632
    /**
633
     * checks if a currency exists, creates it and returns it.
634
     *
635
     * @param string $code
636
     * @param string $name OPTIONAL
637
     */
638
    public static function create_new($code, $name = '')
639
    {
640
        $code = trim(strtoupper($code));
641
        if (!$name) {
642
            $currencies = Config::inst()->get('EcommerceCurrency', 'currencies');
643
            if (isset($currencies[$code])) {
644
                $name = $currencies[$code];
645
            } else {
646
                $name = $code;
647
            }
648
        }
649
        $name = ucwords($name);
650
        $currency = DataObject::get_one(
651
            'EcommerceCurrency',
652
            array('Code' => $code),
653
            $cacheDataObjectGetOne = false
654
        );
655
        if ($currency) {
656
            $currency->Name = $name;
657
            $currency->InUse = true;
658
        } else {
659
            $currency = EcommerceCurrency::create(
660
                array(
661
                'Code' => $code,
662
                'Name' => $name,
663
                'InUse' => true,
664
                )
665
            );
666
        }
667
        $valid = $currency->write();
668
        if ($valid) {
669
            return $currency;
670
        }
671
    }
672
673
    /**
674
     * Debug helper method.
675
     * Can be called from /shoppingcart/debug/.
676
     *
677
     * @return string
678
     */
679
    public function debug()
680
    {
681
        return EcommerceTaskDebugCart::debug_object($this);
682
    }
683
684
    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...
685
        'AFA' => 'afghanistan afghanis',
686
        'ALL' => 'albania leke',
687
        'DZD' => 'algeria dinars',
688
        'ARS' => 'argentina pesos',
689
        'AUD' => 'australia dollars',
690
        'ATS' => 'austria schillings*',
691
        'BSD' => 'bahamas dollars',
692
        'BHD' => 'bahrain dinars',
693
        'BDT' => 'bangladesh taka',
694
        'BBD' => 'barbados dollars',
695
        'BEF' => 'belgium francs*',
696
        'BMD' => 'bermuda dollars',
697
        'BRL' => 'brazil reais',
698
        'BGN' => 'bulgaria leva',
699
        'CAD' => 'canada dollars',
700
        'XOF' => 'cfa bceao francs',
701
        'XAF' => 'cfa beac francs',
702
        'CLP' => 'chile pesos',
703
        'CNY' => 'china yuan renminbi',
704
        'COP' => 'colombia pesos',
705
        'CRC' => 'costa rica colones',
706
        'HRK' => 'croatia kuna',
707
        'CYP' => 'cyprus pounds',
708
        'CZK' => 'czech republic koruny',
709
        'DKK' => 'denmark kroner',
710
        'DOP' => 'dominican republic pesos',
711
        'XCD' => 'eastern caribbean dollars',
712
        'EGP' => 'egypt pounds',
713
        'EEK' => 'estonia krooni',
714
        'EUR' => 'euro',
715
        'FJD' => 'fiji dollars',
716
        'DEM' => 'germany deutsche marks*',
717
        'XAU' => 'gold ounces',
718
        'NLG' => 'holland (netherlands) guilders*',
719
        'HKD' => 'hong kong dollars',
720
        'HUF' => 'hungary forint',
721
        'ISK' => 'iceland kronur',
722
        'XDR' => 'imf special drawing right',
723
        'INR' => 'india rupees',
724
        'IDR' => 'indonesia rupiahs',
725
        'IRR' => 'iran rials',
726
        'IQD' => 'iraq dinars',
727
        'ILS' => 'israel new shekels',
728
        'JMD' => 'jamaica dollars',
729
        'JPY' => 'japan yen',
730
        'JOD' => 'jordan dinars',
731
        'KES' => 'kenya shillings',
732
        'KRW' => 'korea (south) won',
733
        'KWD' => 'kuwait dinars',
734
        'LBP' => 'lebanon pounds',
735
        'MYR' => 'malaysia ringgits',
736
        'MTL' => 'malta liri',
737
        'MUR' => 'mauritius rupees',
738
        'MXN' => 'mexico pesos',
739
        'MAD' => 'morocco dirhams',
740
        'NZD' => 'new zealand dollars',
741
        'NOK' => 'norway kroner',
742
        'OMR' => 'oman rials',
743
        'PKR' => 'pakistan rupees',
744
        'XPD' => 'palladium ounces',
745
        'PEN' => 'peru nuevos soles',
746
        'PHP' => 'philippines pesos',
747
        'PLN' => 'poland zlotych',
748
        'QAR' => 'qatar riyals',
749
        'ROL' => 'romania lei',
750
        'RUB' => 'russia rubles',
751
        'SAR' => 'saudi arabia riyals',
752
        'XAG' => 'silver ounces',
753
        'SGD' => 'singapore dollars',
754
        'SKK' => 'slovakia koruny',
755
        'SIT' => 'slovenia tolars',
756
        'ZAR' => 'south africa rand',
757
        'KRW' => 'south korea won',
758
        'LKR' => 'sri lanka rupees',
759
        'SDD' => 'sudan dinars',
760
        'SEK' => 'sweden kronor',
761
        'CHF' => 'switzerland francs',
762
        'TWD' => 'taiwan new dollars',
763
        'THB' => 'thailand baht',
764
        'TTD' => 'trinidad and tobago dollars',
765
        'TND' => 'tunisia dinars',
766
        'TRY' => 'turkey new lira',
767
        'AED' => 'united arab emirates dirhams',
768
        'gbp' => 'united kingdom pounds',
769
        'USD' => 'united states dollars',
770
        'VEB' => 'venezuela bolivares',
771
        'VND' => 'vietnam dong',
772
        'ZMK' => 'zambia kwacha',
773
    );
774
}
775