Completed
Push — master ( c7d7ec...00b45d )
by Nicolaas
02:46
created

updateBeforeCalculatedPrice()   F

Complexity

Conditions 37
Paths 2204

Size

Total Lines 132
Code Lines 86

Duplication

Lines 30
Ratio 22.73 %

Importance

Changes 0
Metric Value
dl 30
loc 132
rs 2
c 0
b 0
f 0
cc 37
eloc 86
nc 2204
nop 1

How to fix   Long Method    Complexity   

Long Method

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

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

Commonly applied refactorings include:

1
<?php
2
/**
3
 * Adds pricing to Buyables
4
 *
5
 *
6
 */
7
8
class CountryPrice_BuyableExtension extends DataExtension
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...
9
{
10
    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...
11
        "AllCountries" => "Boolean"
12
    );
13
14
    private static $many_many = array(
0 ignored issues
show
Unused Code introduced by
The property $many_many 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...
15
        "IncludedCountries" => "EcommerceCountry",
16
        "ExcludedCountries" => "EcommerceCountry"
17
    );
18
19
    private static $allow_usage_of_distributor_backup_country_pricing = false;
0 ignored issues
show
Unused Code introduced by
The property $allow_usage_of_distributor_backup_country_pricing 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...
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) {
34
            $tabs = new TabSet('Countries',
35
                new Tab(
36
                    'Include',
37
                    new CheckboxField("AllCountries", "All Countries")
38
                )
39
            );
40
        } else {
41
            $tabs = new TabSet('Countries',
42
                $includeTab = new Tab(
43
                    'Include',
44
                    new CheckboxField("AllCountries", "All Countries")
45
                ),
46
                $excludeTab = new Tab(
47
                    'Exclude'
48
                )
49
            );
50
            if (count($excludedCountries)) {
51
                $includeTab->push(
52
                    new LiteralField(
53
                        "ExplanationInclude",
54
                        "<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>"
55
                    )
56
                );
57
                $includeTab->push(
58
                    new CheckboxSetField('IncludedCountries', '', $excludedCountries)
59
                );
60
            }
61
            if (count($includedCountries)) {
62
                $excludeTab->push(
63
                    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>")
64
                );
65
                $excludeTab->push(
66
                    new CheckboxSetField('ExcludedCountries', '', $includedCountries)
67
                );
68
            }
69
        }
70
71
72
        if ($this->owner->ID) {
73
            //start cms_object hack
74
            CountryPrice::set_cms_object($this->owner);
75
            //end cms_object hack
76
            $source = $this->owner->AllCountryPricesForBuyable();
77
            $table = new GridField(
78
                'CountryPrices',
79
                'Country Prices',
80
                $source,
81
                GridFieldConfig_RecordEditor::create()
82
            );
83
            $tab = 'Root.Countries.Pricing';
84
            $fields->addFieldsToTab(
85
                $tab,
86
                array(
87
                    NumericField::create('Price', 'Main Price', '', 12),
88
                    HeaderField::create('OtherCountryPricing', "Prices for other countries"),
89
                    $table
90
                )
91
            );
92
        }
93
94
        $fields->addFieldToTab('Root.Countries', $tabs);
95
    }
96
97
    private $debug = false;
98
99
    /**
100
     * This is called from /ecommerce/code/Product
101
     * returning NULL is like returning TRUE, i.e. ignore this.
102
     * @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...
103
     * @param bool (optional)     $checkPrice
104
     * @return false | null
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...
105
     */
106
    public function canPurchaseByCountry(Member $member = null, $checkPrice = true, $countryCode = '')
107
    {
108
        $countryObject = CountryPrice_EcommerceCountry::get_real_country($countryCode);
109
        if ($countryObject) {
110
            if ($this->debug) {
111
                debug::log('found country object: '.$countryObject->Code);
112
            }
113
            $countryCode = $countryObject->Code;
114
        }
115
        if ($countryCode == '') {
116
            if ($this->debug) {
117
                debug::log('There is no country Code! ');
118
            }
119
            return null;
120
        }
121 View Code Duplication
        if ($countryCode == EcommerceConfig::get('EcommerceCountry', 'default_country_code')) {
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...
122
            if ($this->debug) {
123
                debug::log('we are in the default country! exiting now ... ');
124
            }
125
            return null;
126
        }
127 View Code Duplication
        if ($this->owner->AllCountries) {
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...
128
            //is there a valid price ???
129
            if ($this->debug) {
130
                debug::log('All countries applies - updated  ... new price = '.floatval($this->owner->updateCalculatedPrice()));
131
            }
132
            //null basically means - ignore ...
133
            return floatval($this->owner->getCalculatedPrice()) > 0 ? null : false;
134
        }
135
        if ($countryCode) {
136
            $included = $this->owner->getManyManyComponents('IncludedCountries', "\"Code\" = '$countryCode'")->Count();
137 View Code Duplication
            if ($included) {
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...
138
                if ($this->debug) {
139
                    debug::log('included countries  ... new price = '.floatval($this->owner->updateCalculatedPrice()));
140
                }
141
                //null basically means - ignore ...
142
                return floatval($this->owner->getCalculatedPrice()) > 0 ? null : false;
143
            }
144
            $excluded = $this->owner->getManyManyComponents('ExcludedCountries', "\"Code\" = '$countryCode'")->Count();
145
            if ($excluded) {
146
                if ($this->debug) {
147
                    debug::log('excluded country');
148
                }
149
                return false;
150
            }
151
        }
152
        if ($this->owner instanceof Product && $this->owner->hasMethod('hasVariations') && $this->owner->hasVariations()) {
153
            if ($this->debug) {
154
                debug::log('check variations ... ');
155
            }
156
157
            //check variations ...
158
            return $this->owner->Variations()->First()->canPurchaseByCountry($member, $checkPrice);
159
        }
160
161
        //is there a valid price ???
162
        $countryPrice = $this->owner->getCalculatedPrice();
163
        if ($this->debug) {
164
            debug::log('nothing applies, but we have a country price... '.$countryPrice);
165
        }
166
        return floatval($countryPrice) > 0 ? null : false;
167
    }
168
169
    /**
170
     *
171
     * @return DataList
172
     */
173
    public function AllCountryPricesForBuyable()
174
    {
175
        $filterArray = array("ObjectClass" => ClassInfo::subclassesFor($this->ownerBaseClass), "ObjectID" => $this->owner->ID);
176
        return CountryPrice::get()
177
            ->filter($filterArray);
178
    }
179
180
    /**
181
     * returns all the prices for a particular country and/or currency
182
     * for the object
183
     * @param string (optional) $country
184
     * @param string (optional) $currency
185
     * @return DataList
186
     */
187
    public function CountryPricesForCountryAndCurrency($countryCode = null, $currency = null)
188
    {
189
        $countryObject = CountryPrice_EcommerceCountry::get_real_country($countryCode);
190
        $allCountryPricesForBuyable = $this->AllCountryPricesForBuyable();
191
        if ($countryObject) {
192
            $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...
193
        }
194
        if ($currency) {
195
            $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...
196
        }
197
        $allCountryPricesForBuyable = $allCountryPricesForBuyable->filter($filterArray);
198
        return $allCountryPricesForBuyable;
199
    }
200
201
    private static $_buyable_price = array();
202
203
    /***
204
     *
205
     * updates the calculated price to the local price...
206
     * if there is no price then we return 0
207
     * if the default price can be used then we use NULL (i.e. ignore it!)
208
     * @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...
209
     * @return Float | null (ignore this value and use original value)
210
     */
211
    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...
212
    {
213
        $countryCode = '';
214
        $countryObject = CountryPrice_EcommerceCountry::get_real_country();
215
        if ($countryObject) {
216
            $countryCode = $countryObject->Code;
217
        }
218 View Code Duplication
        if ($countryCode == '' || $countryCode == EcommerceConfig::get('EcommerceCountry', 'default_country_code')) {
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...
219
            if ($this->debug) {
220
                debug::log('No country code or default country code: '.$countryCode);
221
            }
222
223
            return null;
224
        }
225
        $key = $this->owner->ClassName."___".$this->owner->ID.'____'.$countryCode;
226
        if ($this->debug) {
227
            debug::log('TESTING '.$key.'');
228
        }
229
        if (! isset(self::$_buyable_price[$key])) {
230
            //basics
231
            $currency = null;
0 ignored issues
show
Unused Code introduced by
$currency 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...
232
            $currencyCode = null;
233
234
            if ($countryCode) {
235
                $order = ShoppingCart::current_order();
236
                CountryPrice_OrderDOD::localise_order();
237
                $currency = $order->CurrencyUsed();
238
                if ($currency) {
239
                    $currencyCode = strtoupper($currency->Code);
240
                    //1. exact price for country
241
                    if ($currencyCode) {
242
                        $prices = $this->owner->CountryPricesForCountryAndCurrency(
243
                            $countryCode,
244
                            $currencyCode
245
                        );
246 View Code Duplication
                        if ($prices && $prices->count() == 1) {
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...
247
                            self::$_buyable_price[$key] = $prices->First()->Price;
248
                            return self::$_buyable_price[$key];
249
                        } elseif ($prices) {
250
                            if ($this->debug) {
251
                                debug::log('MAIN COUNTRY: There is an error number of prices: '.$prices->count());
252
                            }
253
                        } else {
254
                            if ($this->debug) {
255
                                debug::log('MAIN COUNTRY: There is no country price: ');
256
                            }
257
                        }
258
                    } else {
259
                        if ($this->debug) {
260
                            debug::log('MAIN COUNTRY: There is no currency code '.$currencyCode.'');
261
                        }
262
                    }
263
                } else {
264
                    if ($this->debug) {
265
                        debug::log('MAIN COUNTRY: there is no currency');
266
                    }
267
                }
268
                if (Config::inst()->get('CountryPrice_BuyableExtension', 'allow_usage_of_distributor_backup_country_pricing')) {
269
                    //there is a specific country price ...
270
                    //check for distributor primary country price
271
                    // if it is the same currency, then use that one ...
272
                    $distributorCountry = CountryPrice_EcommerceCountry::get_distributor_primary_country($countryCode);
273
                    if ($distributorCurrency = $distributorCountry->EcommerceCurrency()) {
274
                        if ($distributorCurrency->ID == $currency->ID) {
275
                            $distributorCurrencyCode = strtoupper($distributorCurrency->Code);
276
                            $distributorCountryCode = $distributorCountry->Code;
277
                            if ($distributorCurrencyCode && $distributorCountryCode) {
278
                                $prices = $this->owner->CountryPricesForCountryAndCurrency(
279
                                    $distributorCountryCode,
280
                                    $distributorCurrencyCode
281
                                );
282 View Code Duplication
                                if ($prices && $prices->count() == 1) {
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...
283
                                    self::$_buyable_price[$key] = $prices->First()->Price;
284
                                    return self::$_buyable_price[$key];
285
                                } elseif ($prices) {
286
                                    if ($this->debug) {
287
                                        debug::log('BACKUP COUNTRY: There is an error number of prices: '.$prices->count());
288
                                    }
289
                                } else {
290
                                    if ($this->debug) {
291
                                        debug::log('BACKUP COUNTRY: There is no country price: ');
292
                                    }
293
                                }
294
                            } else {
295
                                if ($this->debug) {
296
                                    debug::log('BACKUP COUNTRY: We are missing the distributor currency code ('.$distributorCurrencyCode.') or the distributor country code ('.$distributorCountryCode.')');
297
                                }
298
                            }
299
                        } else {
300
                            if ($this->debug) {
301
                                debug::log('BACKUP COUNTRY: The distributor currency ID ('.$distributorCurrency->ID.') is not the same as the order currency ID ('.$currency->ID.').');
302
                            }
303
                        }
304
                    }
305
                } else {
306
                    if ($this->debug) {
307
                        debug::log('We do not allow backup country pricing');
308
                    }
309
                }
310
            } else {
311
                if ($this->debug) {
312
                    debug::log('There is not Country Code ');
313
                }
314
            }
315
            //order must have a country and a currency
316
            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...
317
                if ($this->debug) {
318
                    debug::log('No currency ('.$currencyCode.') or no country code ('.$countryCode.') for order: ');
319
                }
320
                self::$_buyable_price[$key] = 0;
321
                return self::$_buyable_price[$key];
322
            }
323
            //catch error 2: no country price BUT currency is not default currency ...
324
            if (EcommercePayment::site_currency() != $currencyCode) {
325
                if ($this->debug) {
326
                    debug::log('site currency  ('.EcommercePayment::site_currency().') is not the same order currency ('.$currencyCode.')');
327
                }
328
                self::$_buyable_price[$key] = 0;
329
                return self::$_buyable_price[$key];
330
            }
331
            //you can revert back to default country price ...
332
            //returning NULL is basically good ...
333
            if ($this->debug) {
334
                debug::log('SETTING '.$key.' to NULL');
335
            }
336
            self::$_buyable_price[$key] = null;
337
338
            return self::$_buyable_price[$key];
339
        }
340
        
341
        return self::$_buyable_price[$key];
342
    }
343
344
    /**
345
     * delete the related prices
346
     */
347
    public function onBeforeDelete()
348
    {
349
        $prices = $this->AllCountryPricesForBuyable();
350
        if ($prices && $prices->count()) {
351
            foreach ($prices as $price) {
352
                $price->delete();
353
            }
354
        }
355
    }
356
357
    // VARIATION CODE ONLY
358
359
    // 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
360
    protected $isNew = false;
361
362
    public function onBeforeWrite()
363
    {
364
        $this->isNew = $this->owner->ID == 0;
365
    }
366
367
368
    public function onAfterWrite()
369
    {
370
        //only run if these are variations
371
        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...
372
            $product = $this->owner->Product();
373
            if ($product) {
374
                $productPrices = $product->AllCountryPricesForBuyable();
375
                foreach ($productPrices as $productPrice) {
376
                    if ($productPrice->Country) {
377
                        if (
0 ignored issues
show
Unused Code introduced by
This if statement is empty and can be removed.

This check looks for the bodies of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These if bodies can be removed. If you have an empty if but statements in the else branch, consider inverting the condition.

if (rand(1, 6) > 3) {
//print "Check failed";
} else {
    print "Check succeeded";
}

could be turned into

if (rand(1, 6) <= 3) {
    print "Check succeeded";
}

This is much more concise to read.

Loading history...
378
                            $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...
379
                            ->filter(
380
                                array(
381
                                    "Country" => $productPrice->Country,
382
                                    "ObjectClass" => $this->owner->ClassName,
383
                                    "ObjectID" => $this->owner->ID
384
                                )
385
                            )
386
                            ->First()
387
                        ) {
388
                            //do nothing
389
                        } else {
390
                            $countryVariationPrice = new CountryPrice(
391
                                array(
392
                                    'Price' => $productPrice->Price,
393
                                    'Country' => $productPrice->Country,
394
                                    'Currency' => $productPrice->Currency,
395
                                    'ObjectClass' => $this->owner->ClassName,
396
                                    'ObjectID' => $this->owner->ID
397
                                )
398
                            );
399
                            $countryVariationPrice->write();
400
                        }
401
                    }
402
                }
403
            }
404
        }
405
    }
406
407
    /**
408
     * as long as we do not give distributors access to the Products
409
     * this is fairly safe.
410
     * @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...
411
     * @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...
412
     */
413
    public function canEdit($member = null)
414
    {
415
        if (! $member) {
416
            $member = Member::currentUser();
417
        }
418
        if ($member) {
419
            $distributor = $member->Distributor();
420
            if ($distributor->exists()) {
421
                return true;
422
            }
423
        }
424
        return false;
425
    }
426
}
427