CountryPrice_EcommerceCountry::get_real_country()   F
last analyzed

Complexity

Conditions 23
Paths 1521

Size

Total Lines 107

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 107
rs 0
c 0
b 0
f 0
cc 23
nc 1521
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
/**
4
 * Adds fields to individual countries.
5
 *
6
 */
7
8
class CountryPrice_EcommerceCountry extends DataExtension
9
{
10
    private static $db = array(
11
        'OnlyShowChildrenInDropdowns' => 'Boolean',
12
        'IsBackupCountry' => 'Boolean',
13
        'FAQContent' => 'HTMLText',
14
        'TopBarMessage' => 'Varchar(255)',
15
        'DeliveryCostNote' => 'Varchar(255)',
16
        'ShippingEstimation' => 'Varchar(255)',
17
        'ReturnInformation' => 'Varchar(255)',
18
        'ProductNotAvailableNote' => 'HTMLText',
19
        'LanguageAndCountryCode' => 'Varchar(20)'
20
    );
21
22
    private static $has_one = array(
23
        'Distributor' => 'Distributor',
24
        'EcommerceCurrency' => 'EcommerceCurrency',
25
        'AlwaysTheSameAs' => 'EcommerceCountry'
26
    );
27
28
    private static $has_many = array(
29
        'ParentFor' => 'EcommerceCountry'
30
    );
31
32
    private static $searchable_fields = array(
33
        "AlwaysTheSameAsID" => true,
34
        "IsBackupCountry" => "ExactMatchFilter"
35
    );
36
37
    private static $default_sort = array(
38
        'Name' => 'DESC'
39
    );
40
41
42
    private static $indexes = array(
43
        "IsBackupCountry" => true
44
    );
45
46
    private static $casting = array(
47
        "LanguageAndCountryCode" => 'Varchar'
48
    );
49
50
    public function updateCMSFields(FieldList $fields)
51
    {
52
        $fields->addFieldToTab(
53
            "Root.ParentCountry",
54
            DropdownField::create(
55
                'AlwaysTheSameAsID',
56
                'Parent Country',
57
                array('' => '--- PLEASE SELECT ---') + EcommerceCountry::get()->filter(array("AlwaysTheSameAsID" => 0))->exclude(array("ID" => $this->owner->ID))->map("ID", "Name")->toArray()
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...
58
            )
59
        );
60
        if ($this->owner->AlwaysTheSameAsID) {
0 ignored issues
show
Bug introduced by
The property AlwaysTheSameAsID 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...
61
            $removeByNameArray = array(
62
                'IsBackupCountry',
63
                'DoNotAllowSales',
64
                'FAQContent',
65
                'TopBarMessage',
66
                'DeliveryCostNote',
67
                'ShippingEstimation',
68
                'ReturnInformation',
69
                'ProductNotAvailableNote',
70
                'DistributorID',
71
                'EcommerceCurrencyID',
72
                'ParentFor',
73
                'Regions'
74
            );
75
            foreach ($removeByNameArray as $removeByNameField) {
76
                $fields->removeByName(
77
                    $removeByNameField
78
                );
79
            }
80
        } else {
81
            $fields->addFieldToTab('Root.Messages', TextField::create('TopBarMessage', 'Top Bar Message')->setRightTitle("also see the site config for default messages"));
82
            if ($this->owner->DistributorID) {
0 ignored issues
show
Bug introduced by
The property DistributorID 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...
83
                $FAQContentField = new HtmlEditorField('FAQContent', 'Content');
84
                $FAQContentField->setRows(7);
85
                $FAQContentField->setColumns(7);
86
                $fields->addFieldToTab('Root.FAQPage', $FAQContentField);
87
            } else {
88
                $fields->addFieldToTab(
89
                    'Root.FAQPage',
90
                    new LiteralField(
91
                        "FAQPageExplanation",
92
                        "<p class=\"message warning\">FAQ information can only be added to the main country for a ". _t('Distributor.SINGULAR_NAME', 'Distributor') ."</p>"
93
                    )
94
                );
95
            }
96
97
            $distributors = Distributor::get()
98
                ->filter(array("IsDefault" => 0));
99
            $distributors = $distributors->count() ? $distributors->map('ID', 'Name')->toArray() : array();
100
            $distributors = array('' => '--- PLEASE SELECT ---') + $distributors;
101
            $fields->addFieldToTab(
102
                'Root.Main',
103
                DropdownField::create('DistributorID', _t('Distributor.SINGULAR_NAME', 'Distributor'), array(0 => "-- Not Selected --") + $distributors),
104
                "DoNotAllowSales"
105
            );
106
107
            $fields->addFieldToTab(
108
                "Root.Testing",
109
                new LiteralField("LogInAsThisCountry", "<h3><a href=\"/whoami/setmycountry/".$this->owner->Code."/?countryfortestingonly=".$this->owner->Code."\">place an order as a person from ".$this->owner->Title."</a></h3>")
0 ignored issues
show
Bug introduced by
The property Code 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 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...
110
            );
111
112
            $fields->addFieldToTab(
113
                "Root.Currency",
114
                $fields->dataFieldByName("EcommerceCurrencyID")
115
            );
116
        }
117
    }
118
119
    public static function get_real_countries_list()
120
    {
121
        return EcommerceCountry::get()
122
            ->filter(array('DoNotAllowSales' => 0, 'AlwaysTheSameAsID' => 0));
123
    }
124
125
    /**
126
     *
127
     *
128
     * @param  [type] $countryCode [description]
0 ignored issues
show
Documentation introduced by
The doc-type [type] could not be parsed: Unknown type name "" at position 0. [(view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
129
     * @return DataList
130
     */
131
    public static function get_sibling_countries($countryCode = null)
132
    {
133
        $countryObject = self::get_real_country($countryCode);
134
        if ($countryObject->AlwaysTheSameAsID) {
135
            return EcommerceCountry::get()
136
                ->filterAny(
137
                    array(
138
                        'AlwaysTheSameAsID' => array($countryObject->AlwaysTheSameAsID),
139
                        "ID" => array($countryObject->AlwaysTheSameAsID, $countryObject->ID)
140
                    )
141
                );
142
        } else {
143
            return EcommerceCountry::get()
144
                ->filterAny(
145
                    array(
146
                        'AlwaysTheSameAsID' => $countryObject->ID,
147
                        'ID' => $countryObject->ID
148
                    )
149
                );
150
        }
151
    }
152
153
    /**
154
     * checks if the country has a distributor
155
     * and returns it.  If not, returns the default country.
156
     *
157
     * @return EcommerceCountry
0 ignored issues
show
Documentation introduced by
Should the return type not be EcommerceCountry|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...
158
     *
159
     */
160
    public static function get_distributor_country($countryCode = null)
161
    {
162
        $countryObject = CountryPrice_EcommerceCountry::get_real_country($countryCode);
163
        if ($countryObject && $countryObject->hasDistributor()) {
164
            //do nothing ...
165
        } else {
166
            $countryObject = self::get_backup_country();
167
        }
168
        return $countryObject;
169
    }
170
171
    /**
172
    * checks if the country has a distributor
173
    * and returns the primary country for the distributor.
174
    * If not, returns the default country.
175
     *
176
     * @return EcommerceCountry
177
     *
178
     */
179
    public static function get_distributor_primary_country($countryCode = null)
180
    {
181
        $countryObject = CountryPrice_EcommerceCountry::get_real_country($countryCode);
182
        if ($countryObject && $countryObject->hasDistributor()) {
183
            return $countryObject->Distributor()->PrimaryCountry();
184
        //do nothing ...
185
        } else {
186
            $countryObject = self::get_backup_country();
187
        }
188
        return $countryObject;
189
    }
190
191
    private static $_get_real_country_cache = array();
192
193
    /**
194
     * returns the 'always the same as' (parent) country if necessary
195
     * @param  EcommerceCountry | string | int   (optional)  $country
196
     *
197
     * @return EcommerceCountry
198
     */
199
    public static function get_real_country($country = null)
200
    {
201
        $country = EcommerceCountry::get_country_from_mixed_var($country);
202
        if ($country) {
203
            $cacheKey = $country->Code;
204
        } elseif ($country) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $country of type string|null is loosely compared to true; 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...
205
            $cacheKey = $country;
206
        } else {
207
            $cacheKey = 'notprovided';
208
        }
209
        if (isset(self::$_get_real_country_cache[$cacheKey]) && self::$_get_real_country_cache[$cacheKey]) {
210
        } else {
211
            //save original - just in case...
212
            $originalCountry = $country;
213
214
            //no country provided
215
            if (! $country) {
216
                $urlCountryCode = CountryPrice_Translation::get_country_url_provider()->CurrentCountrySegment();
0 ignored issues
show
Bug introduced by
The method CurrentCountrySegment cannot be called on \CountryPrice_Translatio..._country_url_provider() (of type string).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
217
218
                // 2. CHECK WHAT THE SYSTEM THINKS THE COUNTRY CHOULD BE
219
220
                //now we check it from order / session ....
221
                $order = ShoppingCart::current_order();
222
                if ($order && $order->exists()) {
223
                    Session::clear('temporary_country_order_store');
224
                    $countryCode = $order->getCountry();
225
                } else {
226
                    $countryCode = Session::get('temporary_country_order_store');
227
                }
228
229
                //if we still dont have a country then we use the standard e-commerce methods ...
230
                if (! $countryCode) {
231
                    $countryCode = EcommerceCountry::get_country();
232
                }
233
234
                //lets make our object!
235
                if ($countryCode) {
236
                    $country = DataObject::get_one('EcommerceCountry', ['Code' => $countryCode]);
237
                }
238
239
                $country = EcommerceCountry::get_country_from_mixed_var($country);
240
                if ($country) {
241
                    //do nothing
242
                } else {
243
                    $country = null;
244
                }
245
                //IF THE COUNTRY DOES NOT MATCH THE URL COUNTRY THEN THE URL WINS!!!!
246
                if ($urlCountryCode) {
247
                    if (
248
                            ($country && $country->Code !== $urlCountryCode)
249
                        ||
250
                            ! $country
251
252
                    ) {
253
                        $country = DataObject::get_one('EcommerceCountry', ['Code' => $urlCountryCode]);
254
                        if ($country) {
255
                            //change country Object
256
                            //reset everything ...
257
                            CountryPrices_ChangeCountryController::set_new_country($country->Code);
258
                        // return self::get_real_country($country);
259
                        } else {
260
                            return $this->redirect('404-country-not-found');
0 ignored issues
show
Bug introduced by
The variable $this does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
Bug introduced by
The method redirect() does not seem to exist on object<CountryPrice_EcommerceCountry>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
261
                        }
262
                    } else {
263
                    }
264
                }
265
            }
266
267
268
            //MAKE SURE WE HAVE AN OBJECT
269
            //get the Object
270
            $country = EcommerceCountry::get_country_from_mixed_var($country);
271
272
273
            //LOOK FOR REPLACEMENT COUNTRIES
274
            //substitute (always the same as) check ....
275
            if ($country) {
276
                if ($country->AlwaysTheSameAsID) {
277
                    $realCountry = $country->AlwaysTheSameAs();
278
                    if ($realCountry && $realCountry->exists()) {
279
                        $country = $realCountry;
280
                    }
281
                }
282
            } else {
283
                //last chance ... do this only once ...
284
                $countryCode = EcommerceCountry::get_country_default();
285
                if ($countryCode && !$originalCountry) {
286
                    $country = self::get_real_country($countryCode);
287
                }
288
            }
289
290
            //FINAL BOARDING CALL!
291
            //surely we have one now???
292
            $country = EcommerceCountry::get_country_from_mixed_var($country);
293
            if ($country) {
294
                //do nothing
295
            } else {
296
                //final backup....
297
                $country = EcommerceCountry::get()->first();
298
            }
299
300
            //set to cache ...
301
            self::$_get_real_country_cache[$cacheKey] = $country;
302
        }
303
304
        return self::$_get_real_country_cache[$cacheKey];
305
    }
306
307
    public static function countries_belong_to_same_group($countryOrCountryCodeA, $countryOrCountryCodeB)
308
    {
309
        $countryA = EcommerceCountry::get_country_from_mixed_var($countryOrCountryCodeA);
310
        $countryB = EcommerceCountry::get_country_from_mixed_var($countryOrCountryCodeB);
311
        if ($countryA && $countryB) {
312
            if ($countryA->ID === $countryB->ID) {
313
                return true;
314
            }
315
            if ($countryA->AlwaysTheSameAsID === $countryB->ID) {
316
                return true;
317
            }
318
            if ($countryA->ID === $countryB->AlwaysTheSameAsID) {
319
                return true;
320
            }
321
            if ($countryA->AlwaysTheSameAsID && $countryA->AlwaysTheSameAsID === $countryB->AlwaysTheSameAsID) {
322
                return true;
323
            }
324
        }
325
326
        return false;
327
    }
328
329
330
    /**
331
     *
332
     * @return EcommerceCountry
0 ignored issues
show
Documentation introduced by
Should the return type not be EcommerceCountry|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...
333
     */
334
    public static function get_backup_country()
335
    {
336
        $obj = EcommerceCountry::get()->filter(array("IsBackupCountry" => true))->first();
337
        if (! $obj) {
338
            $obj = EcommerceCountry::get()->filter(array("Code" => EcommerceConfig::get('EcommerceCountry', 'default_country_code')))->first();
339
            if (! $obj) {
340
                $obj = EcommerceCountry::get()->first();
341
            }
342
        }
343
        return $obj;
344
    }
345
346
347
    /**
348
     *
349
     *
350
     * @return boolean
351
     */
352
    public function hasDistributor()
353
    {
354
        $countryObject = CountryPrice_EcommerceCountry::get_real_country($this->owner);
355
356
        return
357
            $countryObject->DistributorID &&
358
            $countryObject->Distributor() &&
359
            $countryObject->Distributor()->exists();
360
    }
361
362
363
    /**
364
     * make sure there is always a backup country ...
365
     */
366
    public function requireDefaultRecords()
367
    {
368
        $backupCountry = EcommerceCountry::get()->filter(array("IsBackupCountry" => 1))->first();
369
        if (!$backupCountry) {
370
            $backupCountry = self::get_backup_country();
371
            if ($backupCountry) {
372
                $backupCountry->IsBackupCountry = true;
373
                $backupCountry->write();
374
            }
375
        }
376
        if ($backupCountry) {
377
            DB::query("UPDATE EcommerceCountry SET IsBackupCountry = 0 WHERE EcommerceCountry.ID <> ".$backupCountry->ID);
378
            DB::alteration_message("Creating back-up country");
379
        } else {
380
            DB::alteration_message("Back-up country has not been set", "deleted");
381
        }
382
    }
383
384
    /**
385
     * @return string
386
     */
387
    public function ComputedLanguageAndCountryCode()
388
    {
389
        if ($this->owner->LanguageAndCountryCode) {
390
            return $this->owner->LanguageAndCountryCode;
0 ignored issues
show
Bug introduced by
The property LanguageAndCountryCode 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...
391
        }
392
        return strtolower('en-'.$this->owner->Code);
0 ignored issues
show
Bug introduced by
The property Code 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...
393
    }
394
}
395