CountryPrice_BuyableExtension::canEdit()   A
last analyzed

Complexity

Conditions 4
Paths 6

Size

Total Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 13
rs 9.8333
c 0
b 0
f 0
cc 4
nc 6
nop 1
1
<?php
2
/**
3
 * Adds pricing to Buyables
4
 *
5
 *
6
 */
7
8
class CountryPrice_BuyableExtension extends DataExtension
9
{
10
    private static $db = array(
11
        "AllCountries" => "Boolean"
12
    );
13
14
    private static $many_many = array(
15
        "IncludedCountries" => "EcommerceCountry",
16
        "ExcludedCountries" => "EcommerceCountry"
17
    );
18
19
    private static $allow_usage_of_distributor_backup_country_pricing = false;
20
21
    public function updateCMSFields(FieldList $fields)
22
    {
23
        $excludedCountries = EcommerceCountry::get()
24
            ->filter(array("DoNotAllowSales" => 1, "AlwaysTheSameAsID" => 0));
25
        if ($excludedCountries->count()) {
26
            $excludedCountries = $excludedCountries->map('ID', 'Name')->toArray();
27
        }
28
        $includedCountries = EcommerceCountry::get()
29
            ->filter(array("DoNotAllowSales" => 0, "AlwaysTheSameAsID" => 0));
30
        if ($includedCountries->count()) {
31
            $includedCountries = $includedCountries->map('ID', 'Name')->toArray();
32
        }
33
        if ($this->owner->AllCountries) {
0 ignored issues
show
Bug introduced by
The property AllCountries does not seem to exist in SS_Object.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
34
            $tabs = new TabSet(
35
                'Countries',
36
                new Tab(
37
                    'Include',
38
                    new CheckboxField("AllCountries", "All Countries")
39
                )
40
            );
41
        } else {
42
            $tabs = new TabSet(
43
                'Countries',
44
                $includeTab = new Tab(
45
                    'Include',
46
                    new CheckboxField("AllCountries", "All Countries")
47
                ),
48
                $excludeTab = new Tab(
49
                    'Exclude'
50
                )
51
            );
52 View Code Duplication
            if (count($excludedCountries)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
53
                $includeTab->push(
54
                    new LiteralField(
55
                        "ExplanationInclude",
56
                        "<p>Products are not available in the countries listed below.  You can include sales of <i>".$this->owner->Title."</i> to new countries by ticking the box(es) next to any country.</p>"
0 ignored issues
show
Bug introduced by
The property Title does not seem to exist in SS_Object.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
57
                    )
58
                );
59
                $includeTab->push(
60
                    new CheckboxSetField('IncludedCountries', '', $excludedCountries)
61
                );
62
            }
63 View Code Duplication
            if (count($includedCountries)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
64
                $excludeTab->push(
65
                    new LiteralField("ExplanationExclude", "<p>Products are available in all countries listed below.  You can exclude sales of <i>".$this->owner->Title."</i> from these countries by ticking the box next to any of them.</p>")
66
                );
67
                $excludeTab->push(
68
                    new CheckboxSetField('ExcludedCountries', '', $includedCountries)
69
                );
70
            }
71
        }
72
73
74
        if ($this->owner->ID) {
0 ignored issues
show
Bug introduced by
The property ID does not seem to exist in SS_Object.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
75
            //start cms_object hack
76
            CountryPrice::set_cms_object($this->owner);
77
            //end cms_object hack
78
            $source = $this->owner->AllCountryPricesForBuyable();
79
            $table = new GridField(
80
                'CountryPrices',
81
                'Country Prices',
82
                $source,
83
                GridFieldConfig_RecordEditor::create()
84
            );
85
            $tab = 'Root.Countries.Pricing';
86
            $fields->addFieldsToTab(
87
                $tab,
88
                array(
89
                    NumericField::create('Price', 'Main Price', '', 12),
90
                    HeaderField::create('OtherCountryPricing', "Prices for other countries"),
91
                    $table
92
                )
93
            );
94
        }
95
96
        $fields->addFieldToTab('Root.Countries', $tabs);
97
    }
98
99
    private $debug = false;
100
101
    /**
102
     * This is called from /ecommerce/code/Product
103
     * returning NULL is like returning TRUE OR FALSE, i.e. ignore this.
104
     * @param Member (optional)   $member
0 ignored issues
show
Documentation introduced by
Should the type for parameter $member not be null|Member?

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...
105
     * @param bool (optional)     $checkPrice
106
     * @return false | null
0 ignored issues
show
Documentation introduced by
Should the return type not be null|false?

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...
107
     */
108
    public function canPurchaseByCountry(Member $member = null, $checkPrice = true, $countryCode = '')
0 ignored issues
show
Unused Code introduced by
The parameter $member is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $checkPrice is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
109
    {
110
        $countryObject = CountryPrice_EcommerceCountry::get_real_country($countryCode);
111
        if ($countryObject) {
112
            if ($this->debug) {
113
                debug::log('found country object: '.$countryObject->Code);
114
            }
115
            $countryCode = $countryObject->Code;
116
        }
117
        if ($countryCode == '') {
118
            if ($this->debug) {
119
                debug::log('There is no country Code! ');
120
            }
121
122
            //we can not decide
123
            return null;
124
        } else {
125
            $canSell = false;
126
127
            //easy  ... overrules all ...
128
            if ($this->owner->AllCountries) {
0 ignored issues
show
Bug introduced by
The property AllCountries does not seem to exist in SS_Object.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
129
                //is there a valid price ???
130
                if ($this->debug) {
131
                    debug::log('All countries applies - updated  ... new price = '.floatval($this->owner->updateCalculatedPrice()));
132
                }
133
                $canSell = true;
134
            } else {
135
136
137
                //excluded first...
138
                $excluded = $this->owner->getManyManyComponents('ExcludedCountries', "\"Code\" = '$countryCode'")->Count();
139
                if ($excluded) {
140
                    if ($this->debug) {
141
                        debug::log('excluded country');
142
                    }
143
144
                    //no!
145
                    return false;
146
                }
147
148
                //default country is included by default ...
149
                if ($countryCode == EcommerceConfig::get('EcommerceCountry', 'default_country_code')) {
150
                    if ($this->debug) {
151
                        debug::log('we are in the default country! exiting now ... ');
152
                    }
153
                    $canSell = true;
154
                } elseif ($this->owner->IncludedCountries()->count()) {
155
                    $included = $this->owner->getManyManyComponents('IncludedCountries', "\"Code\" = '$countryCode'")->Count();
156
                    if ($included) {
157
                        if ($this->debug) {
158
                            debug::log('In included countries');
159
                        }
160
                        //null basically means - ignore ...
161
                        $canSell = true;
162
                    } else {
163
                        //if countries are included and the current country is not included ...
164
                        return false;
165
                    }
166
                }
167
            }
168
            if ($this->debug) {
169
                debug::log('the product is '.($canSell ? '' : 'NOT ').' for sale - lets check price ... ');
170
            }
171
172
            //is there a valid price ???
173
            $countryPrice = $this->owner->getCalculatedPrice(true);
174
            if ($this->debug) {
175
                debug::log('nothing applies, but we have a country price... '.$countryPrice);
176
            }
177
178
            return floatval($countryPrice) > 0 ? null : false;
179
        }
180
    }
181
182
    /**
183
     *
184
     * @return DataList
185
     */
186
    public function AllCountryPricesForBuyable()
187
    {
188
        $filterArray = array("ObjectClass" => ClassInfo::subclassesFor($this->ownerBaseClass), "ObjectID" => $this->owner->ID);
0 ignored issues
show
Bug introduced by
The property ID does not seem to exist in SS_Object.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
189
        return CountryPrice::get()
190
            ->filter($filterArray);
191
    }
192
193
    /**
194
     * returns all the prices for a particular country and/or currency
195
     * for the object
196
     * @param string (optional) $country
197
     * @param string (optional) $currency
198
     * @return DataList
199
     */
200
    public function CountryPricesForCountryAndCurrency($countryCode = null, $currency = null)
201
    {
202
        $countryObject = CountryPrice_EcommerceCountry::get_real_country($countryCode);
203
        $allCountryPricesForBuyable = $this->AllCountryPricesForBuyable();
204
        if ($countryObject) {
205
            $filterArray["Country"] = $countryObject->Code;
0 ignored issues
show
Coding Style Comprehensibility introduced by
$filterArray was never initialized. Although not strictly required by PHP, it is generally a good practice to add $filterArray = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
206
        }
207
        if ($currency) {
208
            $filterArray["Currency"] = $currency;
0 ignored issues
show
Bug introduced by
The variable $filterArray 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...
209
        }
210
        $allCountryPricesForBuyable = $allCountryPricesForBuyable->filter($filterArray);
211
        return $allCountryPricesForBuyable;
212
    }
213
214
    private static $_buyable_price = array();
215
216
    /***
217
     *
218
     * updates the calculated price to the local price...
219
     * if there is no price then we return 0
220
     * if the default price can be used then we use NULL (i.e. ignore it!)
221
     * @param float $price (optional)
0 ignored issues
show
Documentation introduced by
Should the type for parameter $price not be double|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...
222
     * @return Float | null (ignore this value and use original value)
223
     */
224
    public function updateBeforeCalculatedPrice($price = null)
0 ignored issues
show
Unused Code introduced by
The parameter $price is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
225
    {
226
        $countryCode = '';
227
        $countryObject = CountryPrice_EcommerceCountry::get_real_country();
228
        if ($countryObject) {
229
            $countryCode = $countryObject->Code;
230
        }
231
        if ($countryCode === '' || $countryCode === EcommerceConfig::get('EcommerceCountry', 'default_country_code')) {
232
            if ($this->debug) {
233
                debug::log('No country code or default country code: '.$countryCode);
234
            }
235
236
            return null;
237
        }
238
        $key = $this->owner->ClassName."___".$this->owner->ID.'____'.$countryCode;
0 ignored issues
show
Bug introduced by
The property ClassName does not seem to exist in SS_Object.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
Bug introduced by
The property ID does not seem to exist in SS_Object.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
239
        if (! isset(self::$_buyable_price[$key])) {
240
            //basics
241
            $currency = null;
242
            $currencyCode = null;
243
244
            if ($countryCode) {
245
                $order = ShoppingCart::current_order();
246
                //if the order has never been localised, then we do this now!!!!
247
                if (count(self::$_buyable_price) === 0) {
248
                    CountryPrice_OrderDOD::localise_order($countryCode, $force = false, $runAgain = true);
249
250
                    // CRUCIAL!!!!
251
                    // reload order with new values!
252
                    $order = ShoppingCart::current_order();
253
                }
254
                if ($order && $order->exists()) {
255
                    $currency = $order->CurrencyUsed();
256
                }
257
                if ($currency && $currency->exists()) {
258
                    //do nothing
259
                } else {
260
                    $currency = CountryPrice_EcommerceCurrency::get_currency_for_country($countryCode);
261
                }
262
                if ($currency) {
263
                    $currencyCode = strtoupper($currency->Code);
264
                    //1. exact price for country
265 View Code Duplication
                    if ($currencyCode) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
266
                        $prices = $this->owner->CountryPricesForCountryAndCurrency(
267
                            $countryCode,
268
                            $currencyCode
269
                        );
270
                        if ($prices && $prices->count() == 1) {
271
                            self::$_buyable_price[$key] = $prices->First()->Price;
272
                            return self::$_buyable_price[$key];
273
                        } elseif ($prices) {
274
                            if ($this->debug) {
275
                                debug::log('MAIN COUNTRY: There is an error number of prices: '.$prices->count().' based on a search for '.$countryCode.' - '.$currencyCode);
276
                            }
277
                        } else {
278
                            if ($this->debug) {
279
                                debug::log('MAIN COUNTRY: There is no country price: ');
280
                            }
281
                        }
282
                    } else {
283
                        if ($this->debug) {
284
                            debug::log('MAIN COUNTRY: There is no currency code '.$currencyCode.'');
285
                        }
286
                    }
287
                } else {
288
                    if ($this->debug) {
289
                        debug::log('MAIN COUNTRY: there is no currency');
290
                    }
291
                }
292
                if (Config::inst()->get('CountryPrice_BuyableExtension', 'allow_usage_of_distributor_backup_country_pricing')) {
293
                    //there is a specific country price ...
294
                    //check for distributor primary country price
295
                    // if it is the same currency, then use that one ...
296
                    $distributorCountry = CountryPrice_EcommerceCountry::get_distributor_primary_country($countryCode);
297
                    if ($distributorCurrency = $distributorCountry->EcommerceCurrency()) {
298
                        if ($distributorCurrency->ID == $currency->ID) {
299
                            $distributorCurrencyCode = strtoupper($distributorCurrency->Code);
300
                            $distributorCountryCode = $distributorCountry->Code;
301 View Code Duplication
                            if ($distributorCurrencyCode && $distributorCountryCode) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
302
                                $prices = $this->owner->CountryPricesForCountryAndCurrency(
303
                                    $distributorCountryCode,
304
                                    $distributorCurrencyCode
305
                                );
306
                                if ($prices && $prices->count() == 1) {
307
                                    self::$_buyable_price[$key] = $prices->First()->Price;
308
309
                                    return self::$_buyable_price[$key];
310
                                } elseif ($prices) {
311
                                    if ($this->debug) {
312
                                        debug::log('BACKUP COUNTRY: There is an error number of prices: '.$prices->count());
313
                                    }
314
                                } else {
315
                                    if ($this->debug) {
316
                                        debug::log('BACKUP COUNTRY: There is no country price: ');
317
                                    }
318
                                }
319
                            } else {
320
                                if ($this->debug) {
321
                                    debug::log('BACKUP COUNTRY: We are missing the distributor currency code ('.$distributorCurrencyCode.') or the distributor country code ('.$distributorCountryCode.')');
322
                                }
323
                            }
324
                        } else {
325
                            if ($this->debug) {
326
                                debug::log('BACKUP COUNTRY: The distributor currency ID ('.$distributorCurrency->ID.') is not the same as the order currency ID ('.$currency->ID.').');
327
                            }
328
                        }
329
                    }
330
                } else {
331
                    if ($this->debug) {
332
                        debug::log('We do not allow backup country pricing');
333
                    }
334
                }
335
            } else {
336
                if ($this->debug) {
337
                    debug::log('There is not Country Code ');
338
                }
339
            }
340
            //order must have a country and a currency
341
            if (! $currencyCode ||  ! $countryCode) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $currencyCode of type string|null is loosely compared to false; this is ambiguous if the string can be empty. You might want to explicitly use === null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
342
                if ($this->debug) {
343
                    debug::log('No currency ('.$currencyCode.') or no country code ('.$countryCode.') for order: ');
344
                }
345
            }
346
            //catch error 2: no country price BUT currency is not default currency ...
347
            if (EcommercePayment::site_currency() != $currencyCode) {
348
                if ($this->debug) {
349
                    debug::log('site currency  ('.EcommercePayment::site_currency().') is not the same order currency ('.$currencyCode.')');
350
                }
351
            } else {
352
                if ($this->debug) {
353
                    debug::log('SETTING '.$key.' to ZERO - NOT FOR SALE');
354
                }
355
            }
356
            self::$_buyable_price[$key] = 0;
357
        }
358
359
        return self::$_buyable_price[$key];
360
    }
361
362
    /**
363
     * delete the related prices
364
     */
365
    public function onBeforeDelete()
366
    {
367
        $prices = $this->AllCountryPricesForBuyable();
368
        if ($prices && $prices->count()) {
369
            foreach ($prices as $price) {
370
                $price->delete();
371
            }
372
        }
373
    }
374
375
    // VARIATION CODE ONLY
376
377
    // We us isNew to presave if we should add some country price for the newy created variation based on the "possibly" pre-existing ones of the product
378
    protected $isNew = false;
379
380
    public function onBeforeWrite()
381
    {
382
        $this->isNew = $this->owner->ID == 0;
0 ignored issues
show
Bug introduced by
The property ID does not seem to exist in SS_Object.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
383
    }
384
385
386
    public function onAfterWrite()
387
    {
388
        //only run if these are variations
389
        if ($this->isNew && $this->owner instanceof ProductVariation) {
0 ignored issues
show
Bug introduced by
The class ProductVariation does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
390
            $product = $this->owner->Product();
391
            if ($product) {
392
                $productPrices = $product->AllCountryPricesForBuyable();
393
                foreach ($productPrices as $productPrice) {
394
                    if ($productPrice->Country) {
395
                        if (
396
                            $countryVariationPrice = CountryPrice::get()
0 ignored issues
show
Unused Code introduced by
$countryVariationPrice 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...
397
                            ->filter(
398
                                array(
399
                                    "Country" => $productPrice->Country,
400
                                    "ObjectClass" => $this->owner->ClassName,
401
                                    "ObjectID" => $this->owner->ID
402
                                )
403
                            )
404
                            ->First()
405
                        ) {
406
                            //do nothing
407
                        } else {
408
                            $countryVariationPrice = new CountryPrice(
409
                                array(
410
                                    'Price' => $productPrice->Price,
411
                                    'Country' => $productPrice->Country,
412
                                    'Currency' => $productPrice->Currency,
413
                                    'ObjectClass' => $this->owner->ClassName,
414
                                    'ObjectID' => $this->owner->ID
415
                                )
416
                            );
417
                            $countryVariationPrice->write();
418
                        }
419
                    }
420
                }
421
            }
422
        }
423
    }
424
425
    /**
426
     * as long as we do not give distributors access to the Products
427
     * this is fairly safe.
428
     * @param member (optiona) $member
0 ignored issues
show
Documentation introduced by
Should the type for parameter $member not be optiona|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...
429
     * @return null / bool
0 ignored issues
show
Documentation introduced by
Should the return type not be boolean?

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...
430
     */
431
    public function canEdit($member = null)
432
    {
433
        if (! $member) {
434
            $member = Member::currentUser();
435
        }
436
        if ($member) {
437
            $distributor = $member->Distributor();
438
            if ($distributor->exists()) {
439
                return true;
440
            }
441
        }
442
        return false;
443
    }
444
}
445