These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | /** |
||
4 | * @description: This class helps you to manage countries within the context of e-commerce. |
||
5 | * For example: To what countries can be sold. |
||
6 | * /dev/build/?resetecommercecountries=1 will reset the list of countries... |
||
7 | * |
||
8 | * |
||
9 | * @authors: Nicolaas [at] Sunny Side Up .co.nz |
||
10 | * @package: ecommerce |
||
11 | * @sub-package: address |
||
12 | * @inspiration: Silverstripe Ltd, Jeremy |
||
13 | **/ |
||
14 | class EcommerceCountry extends DataObject implements EditableEcommerceObject |
||
15 | { |
||
16 | /** |
||
17 | * what variables are accessible through http://mysite.com/api/ecommerce/v1/EcommerceCountry/. |
||
18 | * |
||
19 | * @var array |
||
20 | */ |
||
21 | private static $api_access = array( |
||
0 ignored issues
–
show
Comprehensibility
introduced
by
Loading history...
|
|||
22 | 'view' => array( |
||
23 | 'Code', |
||
24 | 'Name', |
||
25 | ) |
||
26 | ); |
||
27 | |||
28 | /** |
||
29 | * Standard SS Variable. |
||
30 | * |
||
31 | * @var array |
||
32 | **/ |
||
33 | private static $db = array( |
||
0 ignored issues
–
show
|
|||
34 | 'Code' => 'Varchar(20)', |
||
35 | 'Name' => 'Varchar(200)', |
||
36 | 'DoNotAllowSales' => 'Boolean', |
||
37 | ); |
||
38 | |||
39 | /** |
||
40 | * Standard SS Variable. |
||
41 | * |
||
42 | * @var array |
||
43 | **/ |
||
44 | private static $has_many = array( |
||
0 ignored issues
–
show
|
|||
45 | 'Regions' => 'EcommerceRegion', |
||
46 | ); |
||
47 | |||
48 | /** |
||
49 | * Standard SS Variable. |
||
50 | * |
||
51 | * @var array |
||
52 | **/ |
||
53 | private static $indexes = array( |
||
0 ignored issues
–
show
|
|||
54 | 'Code' => true, |
||
55 | 'DoNotAllowSales' => true, |
||
56 | ); |
||
57 | |||
58 | /** |
||
59 | * standard SS variable. |
||
60 | * |
||
61 | * @var array |
||
62 | */ |
||
63 | private static $summary_fields = array( |
||
0 ignored issues
–
show
|
|||
64 | 'Code' => 'Code', |
||
65 | 'Name' => 'Name', |
||
66 | 'AllowSalesNice' => 'Allow Sales', |
||
67 | ); |
||
68 | |||
69 | /** |
||
70 | * standard SS variable. |
||
71 | * |
||
72 | * @var array |
||
73 | */ |
||
74 | private static $casting = array( |
||
0 ignored issues
–
show
|
|||
75 | 'AllowSales' => 'Boolean', |
||
76 | 'AllowSalesNice' => 'Varchar', |
||
77 | ); |
||
78 | |||
79 | /** |
||
80 | * STANDARD SILVERSTRIPE STUFF. |
||
81 | * |
||
82 | * @todo: how to translate this? |
||
83 | **/ |
||
84 | private static $searchable_fields = array( |
||
0 ignored issues
–
show
|
|||
85 | 'Code' => 'PartialMatchFilter', |
||
86 | 'Name' => 'PartialMatchFilter', |
||
87 | 'DoNotAllowSales' => array( |
||
88 | 'title' => 'Sales are prohibited', |
||
89 | ), |
||
90 | ); |
||
91 | |||
92 | /** |
||
93 | * Standard SS Variable. |
||
94 | * |
||
95 | * @var string |
||
96 | **/ |
||
97 | private static $default_sort = '"DoNotAllowSales" ASC, "Name" ASC'; |
||
0 ignored issues
–
show
|
|||
98 | |||
99 | /** |
||
100 | * Standard SS Variable. |
||
101 | * |
||
102 | * @var string |
||
103 | **/ |
||
104 | private static $singular_name = 'Country'; |
||
0 ignored issues
–
show
|
|||
105 | public function i18n_singular_name() |
||
106 | { |
||
107 | return _t('EcommerceCountry.COUNTRY', 'Country'); |
||
108 | } |
||
109 | |||
110 | /** |
||
111 | * Standard SS Variable. |
||
112 | * |
||
113 | * @var string |
||
114 | **/ |
||
115 | private static $plural_name = 'Countries'; |
||
0 ignored issues
–
show
|
|||
116 | public function i18n_plural_name() |
||
117 | { |
||
118 | return _t('EcommerceCountry.COUNTRIES', 'Countries'); |
||
119 | } |
||
120 | |||
121 | /** |
||
122 | * Standard SS variable. |
||
123 | * |
||
124 | * @var string |
||
125 | */ |
||
126 | private static $description = 'A country.'; |
||
127 | |||
128 | /** |
||
129 | * Standard SS Method. |
||
130 | * |
||
131 | * @param Member $member |
||
0 ignored issues
–
show
Should the type for parameter
$member not be Member|null ?
This check looks for 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...
|
|||
132 | * |
||
133 | * @var bool |
||
134 | */ |
||
135 | public function canCreate($member = null) |
||
136 | { |
||
137 | if (! $member) { |
||
138 | $member = Member::currentUser(); |
||
139 | } |
||
140 | $extended = $this->extendedCan(__FUNCTION__, $member); |
||
0 ignored issues
–
show
$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...
|
|||
141 | if ($extended !== null) { |
||
142 | return $extended; |
||
143 | } |
||
144 | |||
145 | return false; |
||
146 | } |
||
147 | |||
148 | /** |
||
149 | * Standard SS Method. |
||
150 | * |
||
151 | * @param Member $member |
||
0 ignored issues
–
show
Should the type for parameter
$member not be Member|null ?
This check looks for 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...
|
|||
152 | * |
||
153 | * @var bool |
||
154 | */ |
||
155 | public function canView($member = null) |
||
156 | { |
||
157 | if (! $member) { |
||
158 | $member = Member::currentUser(); |
||
159 | } |
||
160 | $extended = $this->extendedCan(__FUNCTION__, $member); |
||
0 ignored issues
–
show
$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...
|
|||
161 | if ($extended !== null) { |
||
162 | return $extended; |
||
163 | } |
||
164 | if (Permission::checkMember($member, Config::inst()->get('EcommerceRole', 'admin_permission_code'))) { |
||
165 | return true; |
||
166 | } |
||
167 | |||
168 | return parent::canEdit($member); |
||
0 ignored issues
–
show
It seems like
$member defined by \Member::currentUser() on line 158 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...
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
Loading history...
|
|||
169 | } |
||
170 | |||
171 | /** |
||
172 | * Standard SS Method. |
||
173 | * |
||
174 | * @param Member $member |
||
0 ignored issues
–
show
Should the type for parameter
$member not be Member|null ?
This check looks for 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...
|
|||
175 | * |
||
176 | * @var bool |
||
177 | */ |
||
178 | public function canEdit($member = null) |
||
179 | { |
||
180 | if (! $member) { |
||
181 | $member = Member::currentUser(); |
||
182 | } |
||
183 | $extended = $this->extendedCan(__FUNCTION__, $member); |
||
184 | if ($extended !== null) { |
||
185 | return $extended; |
||
186 | } |
||
187 | if (Permission::checkMember($member, Config::inst()->get('EcommerceRole', 'admin_permission_code'))) { |
||
188 | return true; |
||
189 | } |
||
190 | |||
191 | return parent::canEdit($member); |
||
0 ignored issues
–
show
It seems like
$member defined by \Member::currentUser() on line 181 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...
|
|||
192 | } |
||
193 | |||
194 | /** |
||
195 | * Standard SS method. |
||
196 | * |
||
197 | * @param Member $member |
||
0 ignored issues
–
show
Should the type for parameter
$member not be Member|null ?
This check looks for 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...
|
|||
198 | * |
||
199 | * @return bool |
||
200 | */ |
||
201 | public function canDelete($member = null) |
||
202 | { |
||
203 | if (! $member) { |
||
204 | $member = Member::currentUser(); |
||
205 | } |
||
206 | $extended = $this->extendedCan(__FUNCTION__, $member); |
||
0 ignored issues
–
show
$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...
|
|||
207 | if ($extended !== null) { |
||
208 | return $extended; |
||
209 | } |
||
210 | return false; |
||
211 | if (ShippingAddress::get()->filter(array('ShippingCountry' => $this->Code))->count()) { |
||
0 ignored issues
–
show
if (\ShippingAddress::ge...) { return false; } does not seem to be reachable.
This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed. Unreachable code is most often the result of function fx() {
try {
doSomething();
return true;
}
catch (\Exception $e) {
return false;
}
return false;
}
In the above example, the last
Loading history...
The property
Code does not exist on object<EcommerceCountry> . Since you implemented __get , maybe consider adding a @property annotation.
Since your code implements the magic getter <?php
/**
* @property int $x
* @property int $y
* @property string $text
*/
class MyLabel
{
private $properties;
private $allowedProperties = array('x', 'y', 'text');
public function __get($name)
{
if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
return $properties[$name];
} else {
return null;
}
}
public function __set($name, $value)
{
if (in_array($name, $this->allowedProperties)) {
$properties[$name] = $value;
} else {
throw new \LogicException("Property $name is not defined.");
}
}
}
If the property has read access only, you can use the @property-read annotation instead. Of course, you may also just have mistyped another name, in which case you should fix the error. See also the PhpDoc documentation for @property.
Loading history...
|
|||
212 | return false; |
||
213 | } |
||
214 | if (BillingAddress::get()->filter(array('Country' => $this->Code))->count()) { |
||
0 ignored issues
–
show
The property
Code does not exist on object<EcommerceCountry> . Since you implemented __get , maybe consider adding a @property annotation.
Since your code implements the magic getter <?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...
|
|||
215 | return false; |
||
216 | } |
||
217 | if (Permission::checkMember($member, Config::inst()->get('EcommerceRole', 'admin_permission_code'))) { |
||
218 | return true; |
||
219 | } |
||
220 | |||
221 | return parent::canEdit($member); |
||
0 ignored issues
–
show
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
Loading history...
|
|||
222 | } |
||
223 | |||
224 | /** |
||
225 | * returns the country based on the Visitor Country Provider. |
||
226 | * this is some sort of IP recogniser system (e.g. Geoip Class). |
||
227 | * |
||
228 | * @return string (country code) |
||
229 | **/ |
||
230 | public static function get_country_from_ip() |
||
231 | { |
||
232 | $visitorCountryProviderClassName = EcommerceConfig::get('EcommerceCountry', 'visitor_country_provider'); |
||
233 | if (!$visitorCountryProviderClassName) { |
||
234 | $visitorCountryProviderClassName = 'EcommerceCountry_VisitorCountryProvider'; |
||
235 | } |
||
236 | $visitorCountryProvider = new $visitorCountryProviderClassName(); |
||
237 | |||
238 | return $visitorCountryProvider->getCountry(); |
||
239 | } |
||
240 | |||
241 | /** |
||
242 | * returns the country based on the Visitor Country Provider. |
||
243 | * this is some sort of IP recogniser system (e.g. Geoip Class). |
||
244 | * |
||
245 | * @return string (country code) |
||
246 | **/ |
||
247 | public static function get_ip() |
||
248 | { |
||
249 | $visitorCountryProviderClassName = EcommerceConfig::get('EcommerceCountry', 'visitor_country_provider'); |
||
250 | if (!$visitorCountryProviderClassName) { |
||
251 | $visitorCountryProviderClassName = 'EcommerceCountry_VisitorCountryProvider'; |
||
252 | } |
||
253 | $visitorCountryProvider = new $visitorCountryProviderClassName(); |
||
254 | |||
255 | return $visitorCountryProvider->getIP(); |
||
256 | } |
||
257 | |||
258 | private static $_countries_from_db_cache = array(); |
||
259 | |||
260 | /** |
||
261 | * e.g. |
||
262 | * "NZ" => "New Zealand" |
||
263 | * @return array |
||
264 | */ |
||
265 | public static function get_country_dropdown($showAllCountries = true, $addEmptyString = false, $useIDNotCode = false) |
||
266 | { |
||
267 | $key = ($showAllCountries ? "all" : "notall"); |
||
268 | if (isset(self::$_countries_from_db_cache[$key])) { |
||
269 | $array = self::$_countries_from_db_cache[$key]; |
||
270 | } else { |
||
271 | $array = array(); |
||
272 | $objects = null; |
||
273 | if (class_exists('Geoip') && $showAllCountries && ! $useIDNotCode) { |
||
274 | $array = Geoip::getCountryDropDown(); |
||
275 | } elseif ($showAllCountries) { |
||
276 | $objects = EcommerceCountry::get(); |
||
277 | } else { |
||
278 | $objects = EcommerceCountry::get()->filter(array('DoNotAllowSales' => 0)); |
||
279 | } |
||
280 | if ($objects && $objects->count()) { |
||
281 | if ($useIDNotCode) { |
||
282 | $idField = 'ID'; |
||
283 | } else { |
||
284 | $idField = 'Code'; |
||
285 | } |
||
286 | $array = $objects->map($idField, 'Name')->toArray(); |
||
287 | } |
||
288 | self::$_countries_from_db_cache[$key] = $array; |
||
289 | } |
||
290 | if (count($array)) { |
||
291 | if ($addEmptyString) { |
||
292 | $array = array("", " -- please select -- ") + $array; |
||
293 | } |
||
294 | } |
||
295 | return $array; |
||
296 | } |
||
297 | |||
298 | /** |
||
299 | * This function exists as a shortcut. |
||
300 | * If there is only ONE allowed country code |
||
301 | * then a lot of checking of countries can be avoided. |
||
302 | * |
||
303 | * @return string | null - countrycode |
||
304 | **/ |
||
305 | public static function get_fixed_country_code() |
||
306 | { |
||
307 | $a = EcommerceConfig::get('EcommerceCountry', 'allowed_country_codes'); |
||
308 | if (is_array($a) && count($a) == 1) { |
||
309 | return array_shift($a); |
||
310 | } |
||
311 | |||
312 | return null; |
||
313 | } |
||
314 | |||
315 | /** |
||
316 | * @alias for EcommerceCountry::find_title |
||
317 | * |
||
318 | * @param string $code |
||
319 | * We have this as this is the same as Geoip |
||
320 | * |
||
321 | * @return string |
||
322 | */ |
||
323 | public static function countryCode2name($code) |
||
324 | { |
||
325 | return self::find_title($code); |
||
326 | } |
||
327 | |||
328 | /** |
||
329 | * returns the country name from a code. |
||
330 | * |
||
331 | * @return string |
||
332 | **/ |
||
333 | public static function find_title($code) |
||
334 | { |
||
335 | $code = strtoupper($code); |
||
336 | $options = self::get_country_dropdown($showAllCountries = true); |
||
337 | // check if code was provided, and is found in the country array |
||
338 | if (isset($options[$code])) { |
||
339 | return $options[$code]; |
||
340 | } elseif ($code) { |
||
341 | $obj = EcommerceCountry::get()->filter(array('Code' => $code))->first(); |
||
342 | if ($obj) { |
||
343 | return $obj->Name; |
||
344 | } |
||
345 | return $code; |
||
346 | } else { |
||
347 | return _t('Ecommerce.COUNTRY_NOT_FOUND', '[COUNTRY NOT FOUND]'); |
||
348 | } |
||
349 | } |
||
350 | |||
351 | /** |
||
352 | * Memory for the order's country. |
||
353 | * |
||
354 | * @var array |
||
355 | */ |
||
356 | private static $_country_cache = array(); |
||
357 | |||
358 | /** |
||
359 | * @param int (optional) $orderID |
||
360 | */ |
||
361 | public static function reset_get_country_cache($orderID = 0) |
||
362 | { |
||
363 | $orderID = ShoppingCart::current_order_id($orderID); |
||
364 | unset(self::$_country_cache[$orderID]); |
||
365 | } |
||
366 | |||
367 | /** |
||
368 | * @param int (optional) $orderID |
||
369 | */ |
||
370 | public static function get_country_cache($orderID = 0) |
||
0 ignored issues
–
show
The return type could not be reliably inferred; please add a
@return annotation.
Our type inference engine in quite powerful, but sometimes the code does not
provide enough clues to go by. In these cases we request you to add a
Loading history...
|
|||
371 | { |
||
372 | $orderID = ShoppingCart::current_order_id($orderID); |
||
373 | |||
374 | return isset(self::$_country_cache[$orderID]) ? self::$_country_cache[$orderID] : null; |
||
375 | } |
||
376 | |||
377 | /** |
||
378 | * @param string $countryCode |
||
379 | * @param int (optional) $orderID |
||
380 | */ |
||
381 | public static function set_country_cache($countryCode, $orderID = 0) |
||
382 | { |
||
383 | $orderID = ShoppingCart::current_order_id($orderID); |
||
384 | self::$_country_cache[$orderID] = $countryCode; |
||
385 | } |
||
386 | |||
387 | /** |
||
388 | * This function works out the most likely country for the current order. |
||
389 | * |
||
390 | * @param bool (optional) $recalculate |
||
391 | * @param int (optional) $orderID |
||
392 | * |
||
393 | * @return string - Country Code - e.g. NZ |
||
394 | **/ |
||
395 | public static function get_country($recalculate = false, $orderID = 0) |
||
396 | { |
||
397 | $orderID = ShoppingCart::current_order_id($orderID); |
||
398 | $countryCode = self::get_country_cache($orderID); |
||
399 | if ($countryCode === null || $recalculate) { |
||
400 | $countryCode = ''; |
||
0 ignored issues
–
show
$countryCode 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
Loading history...
|
|||
401 | //1. fixed country is first |
||
402 | $countryCode = self::get_fixed_country_code(); |
||
403 | if (!$countryCode) { |
||
404 | //2. check order / shipping address / ip address |
||
405 | //include $countryCode = self::get_country_from_ip(); |
||
406 | if ($o = ShoppingCart::current_order()) { |
||
407 | $countryCode = $o->getCountry(); |
||
408 | //3 ... if there is no shopping cart, then we still want it from IP |
||
409 | } else { |
||
410 | $countryCode = self::get_country_from_ip(); |
||
411 | } |
||
412 | //4 check default country set in GEO IP.... |
||
413 | if (!$countryCode) { |
||
414 | $countryCode = self::get_country_default(); |
||
415 | } |
||
416 | } |
||
417 | self::set_country_cache($countryCode, $orderID); |
||
418 | } |
||
419 | |||
420 | return $countryCode; |
||
421 | } |
||
422 | |||
423 | /** |
||
424 | * A bling guess at the best country! |
||
425 | * |
||
426 | * @return string |
||
0 ignored issues
–
show
|
|||
427 | */ |
||
428 | public static function get_country_default() |
||
429 | { |
||
430 | $countryCode = EcommerceConfig::get('EcommerceCountry', 'default_country_code'); |
||
431 | //5. take the FIRST country from the get_allowed_country_codes |
||
432 | if (!$countryCode) { |
||
433 | $countryArray = self::list_of_allowed_entries_for_dropdown(); |
||
434 | if (is_array($countryArray) && count($countryArray)) { |
||
435 | foreach ($countryArray as $countryCode => $countryName) { |
||
436 | //we stop at the first one... as we have no idea which one is the best. |
||
437 | break; |
||
438 | } |
||
439 | } |
||
440 | } |
||
441 | |||
442 | return $countryCode; |
||
443 | } |
||
444 | |||
445 | /** |
||
446 | * This function works out the most likely country for the current order |
||
447 | * and returns the Country Object, if any. |
||
448 | * |
||
449 | * @param bool (optional) $recalculate |
||
450 | * @param string (optional) $countryCode |
||
451 | * |
||
452 | * @return EcommerceCountry | Null |
||
0 ignored issues
–
show
|
|||
453 | **/ |
||
454 | public static function get_country_object($recalculate = false, $countryCode = null) |
||
455 | { |
||
456 | if (! $countryCode) { |
||
457 | $countryCode = self::get_country($recalculate); |
||
458 | } |
||
459 | |||
460 | return EcommerceCountry::get()->filter(array('Code' => $countryCode))->First(); |
||
461 | } |
||
462 | |||
463 | /** |
||
464 | * maps like this |
||
465 | * NZ => 1 |
||
466 | * AU => 2 |
||
467 | * etc... |
||
468 | * @var array |
||
469 | */ |
||
470 | private static $_code_to_id_map = array(); |
||
471 | /** |
||
472 | * returns the ID of the country or 0. |
||
473 | * |
||
474 | * @param string (optional) $countryCode |
||
475 | * @param bool (optional) $recalculate |
||
476 | * |
||
477 | * @return int |
||
478 | **/ |
||
479 | public static function get_country_id($countryCode = null, $recalculate = false) |
||
480 | { |
||
481 | if (!$countryCode) { |
||
482 | $countryCode = self::get_country($recalculate); |
||
483 | } |
||
484 | if (isset(self::$_code_to_id_map[$countryCode])) { |
||
485 | return self::$_code_to_id_map[$countryCode]; |
||
486 | } |
||
487 | self::$_code_to_id_map[$countryCode] = 0; |
||
488 | $country = EcommerceCountry::get() |
||
489 | ->filter(array('Code' => $countryCode)) |
||
490 | ->first(); |
||
491 | if ($country) { |
||
492 | self::$_code_to_id_map[$countryCode] = $country->ID; |
||
493 | return $country->ID; |
||
494 | } |
||
495 | |||
496 | return 0; |
||
497 | } |
||
498 | |||
499 | /** |
||
500 | * Memory for allow country to check. |
||
501 | * |
||
502 | * @var null | Boolean |
||
503 | */ |
||
504 | private static $_allow_sales_cache = array(); |
||
505 | |||
506 | public static function reset_allow_sales_cache() |
||
507 | { |
||
508 | self::$_allow_sales_cache = null; |
||
509 | } |
||
510 | |||
511 | /** |
||
512 | * Checks if we are allowed to sell to the current country. |
||
513 | * |
||
514 | * @param int (optional) $orderID |
||
515 | * |
||
516 | * @return bool |
||
517 | */ |
||
518 | public static function allow_sales($orderID = 0) |
||
519 | { |
||
520 | $orderID = ShoppingCart::current_order_id($orderID); |
||
521 | if (!isset(self::$_allow_sales_cache[$orderID])) { |
||
522 | self::$_allow_sales_cache[$orderID] = true; |
||
523 | $countryCode = self::get_country(false, $orderID); |
||
524 | if ($countryCode) { |
||
525 | $countries = EcommerceCountry::get() |
||
526 | ->filter(array( |
||
527 | 'DoNotAllowSales' => 1, |
||
528 | 'Code' => $countryCode, |
||
529 | )); |
||
530 | if ($countries->count()) { |
||
531 | self::$_allow_sales_cache[$orderID] = false; |
||
532 | } |
||
533 | } |
||
534 | } |
||
535 | |||
536 | return self::$_allow_sales_cache[$orderID]; |
||
537 | } |
||
538 | |||
539 | /** |
||
540 | * returns an array of Codes => Names of all countries that can be used. |
||
541 | * Use "list_of_allowed_entries_for_dropdown" to get the list. |
||
542 | * |
||
543 | * @todo add caching |
||
544 | * |
||
545 | * @return array |
||
546 | **/ |
||
547 | protected static function get_default_array() |
||
548 | { |
||
549 | $defaultArray = array(); |
||
550 | $countries = null; |
||
0 ignored issues
–
show
$countries 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
Loading history...
|
|||
551 | if ($code = self::get_fixed_country_code()) { |
||
552 | $defaultArray[$code] = self::find_title($code); |
||
553 | |||
554 | return $defaultArray; |
||
555 | } |
||
556 | $countries = EcommerceCountry::get()->exclude(array('DoNotAllowSales' => 1)); |
||
557 | if ($countries && $countries->count()) { |
||
558 | foreach ($countries as $country) { |
||
559 | $defaultArray[$country->Code] = $country->Name; |
||
560 | } |
||
561 | } |
||
562 | |||
563 | return $defaultArray; |
||
564 | } |
||
565 | |||
566 | public function getCMSFields() |
||
567 | { |
||
568 | $fields = parent::getCMSFields(); |
||
569 | $fields->addFieldToTab('Root.Main', new LiteralField( |
||
570 | 'Add Add Countries', |
||
571 | ' |
||
572 | <h3>Short-Cuts</h3> |
||
573 | <h6> |
||
574 | <a href="/dev/tasks/EcommerceTaskCountryAndRegion_DisallowAllCountries" target="_blank">'._t('EcommerceCountry.DISALLOW_ALL', 'disallow sales to all countries').'</a> ||| |
||
575 | <a href="/dev/tasks/EcommerceTaskCountryAndRegion_AllowAllCountries" target="_blank">'._t('EcommerceCountry.ALLOW_ALL', 'allow sales to all countries').'</a> |
||
576 | </h6> |
||
577 | ') |
||
578 | ); |
||
579 | |||
580 | return $fields; |
||
581 | } |
||
582 | |||
583 | |||
584 | |||
585 | /** |
||
586 | * link to edit the record. |
||
587 | * |
||
588 | * @param string | Null $action - e.g. edit |
||
589 | * |
||
590 | * @return string |
||
591 | */ |
||
592 | public function CMSEditLink($action = null) |
||
593 | { |
||
594 | return CMSEditLinkAPI::find_edit_link_for_object($this, $action); |
||
595 | } |
||
596 | |||
597 | /** |
||
598 | * standard SS method. |
||
599 | */ |
||
600 | public function requireDefaultRecords() |
||
601 | { |
||
602 | parent::requireDefaultRecords(); |
||
603 | if ((! EcommerceCountry::get()->count()) || isset($_REQUEST['resetecommercecountries'])) { |
||
604 | $task = new EcommerceTaskCountryAndRegion(); |
||
605 | $task->run(null); |
||
606 | } |
||
607 | } |
||
608 | |||
609 | /** |
||
610 | * standard SS method |
||
611 | * cleans up codes. |
||
612 | */ |
||
613 | public function onBeforeWrite() |
||
614 | { |
||
615 | parent::onBeforeWrite(); |
||
616 | $filter = EcommerceCodeFilter::create(); |
||
617 | $filter->checkCode($this); |
||
618 | } |
||
619 | |||
620 | //DYNAMIC LIMITATIONS |
||
621 | |||
622 | /** |
||
623 | * these variables and methods allow to "dynamically limit the countries available, |
||
624 | * based on, for example: ordermodifiers, item selection, etc.... |
||
625 | * for example, if a person chooses delivery within Australasia (with modifier) - |
||
626 | * then you can limit the countries available to "Australasian" countries. |
||
627 | */ |
||
628 | |||
629 | /** |
||
630 | * List of countries that should be shown. |
||
631 | * |
||
632 | * @param array $a: should be country codes e.g. array("NZ", "NP", "AU"); |
||
633 | * |
||
634 | * @var array |
||
635 | */ |
||
636 | private static $for_current_order_only_show_countries = array(); |
||
637 | public static function get_for_current_order_only_show_countries() |
||
638 | { |
||
639 | return self::$for_current_order_only_show_countries; |
||
640 | } |
||
641 | public static function set_for_current_order_only_show_countries(array $a) |
||
642 | { |
||
643 | if (count(self::$for_current_order_only_show_countries)) { |
||
644 | //we INTERSECT here so that only countries allowed by all forces (modifiers) are added. |
||
645 | self::$for_current_order_only_show_countries = array_intersect($a, self::$for_current_order_only_show_countries); |
||
646 | } else { |
||
647 | self::$for_current_order_only_show_countries = $a; |
||
648 | } |
||
649 | } |
||
650 | |||
651 | /** |
||
652 | * List of countries that should NOT be shown. |
||
653 | * |
||
654 | * @param array $a: should be country codes e.g. array("NZ", "NP", "AU"); |
||
655 | * |
||
656 | * @var array |
||
657 | */ |
||
658 | private static $for_current_order_do_not_show_countries = array(); |
||
659 | public static function get_for_current_order_do_not_show_countries() |
||
660 | { |
||
661 | return self::$for_current_order_do_not_show_countries; |
||
662 | } |
||
663 | public static function set_for_current_order_do_not_show_countries(array $a) |
||
664 | { |
||
665 | //We MERGE here because several modifiers may limit the countries |
||
666 | self::$for_current_order_do_not_show_countries = array_merge($a, self::$for_current_order_do_not_show_countries); |
||
667 | } |
||
668 | |||
669 | /** |
||
670 | * @var array |
||
671 | */ |
||
672 | private static $list_of_allowed_entries_for_dropdown_array = array(); |
||
673 | |||
674 | /** |
||
675 | * takes the defaultArray and limits it with "only show" and "do not show" value, relevant for the current order. |
||
676 | * |
||
677 | * @return array (Code, Title) |
||
678 | **/ |
||
679 | public static function list_of_allowed_entries_for_dropdown() |
||
680 | { |
||
681 | if (!self::$list_of_allowed_entries_for_dropdown_array) { |
||
0 ignored issues
–
show
The expression
self::$list_of_allowed_entries_for_dropdown_array of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent. Consider making the comparison explicit by using
Loading history...
|
|||
682 | $defaultArray = self::get_default_array(); |
||
683 | $onlyShow = self::$for_current_order_only_show_countries; |
||
684 | $doNotShow = self::$for_current_order_do_not_show_countries; |
||
685 | if (is_array($onlyShow) && count($onlyShow)) { |
||
686 | foreach ($defaultArray as $key => $value) { |
||
687 | if (!in_array($key, $onlyShow)) { |
||
688 | unset($defaultArray[$key]); |
||
689 | } |
||
690 | } |
||
691 | } |
||
692 | if (is_array($doNotShow) && count($doNotShow)) { |
||
693 | foreach ($doNotShow as $code) { |
||
694 | if (isset($defaultArray[$code])) { |
||
695 | unset($defaultArray[$code]); |
||
696 | } |
||
697 | } |
||
698 | } |
||
699 | self::$list_of_allowed_entries_for_dropdown_array = $defaultArray; |
||
700 | } |
||
701 | |||
702 | return self::$list_of_allowed_entries_for_dropdown_array; |
||
703 | } |
||
704 | |||
705 | /** |
||
706 | * checks if a code is allowed. |
||
707 | * |
||
708 | * @param string $code - e.g. NZ, NSW, or CO |
||
709 | * |
||
710 | * @return bool |
||
711 | **/ |
||
712 | public static function code_allowed($code) |
||
713 | { |
||
714 | return array_key_exists($code, self::list_of_allowed_entries_for_dropdown()); |
||
715 | } |
||
716 | |||
717 | /** |
||
718 | * Casted variable to show if sales are allowed to this country. |
||
719 | * |
||
720 | * @return bool |
||
721 | */ |
||
722 | public function AllowSales() |
||
723 | { |
||
724 | return $this->getAllowSales(); |
||
725 | } |
||
726 | public function getAllowSales() |
||
727 | { |
||
728 | if ($this->DoNotAllowSales) { |
||
0 ignored issues
–
show
The property
DoNotAllowSales does not exist on object<EcommerceCountry> . Since you implemented __get , maybe consider adding a @property annotation.
Since your code implements the magic getter <?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...
|
|||
729 | return false; |
||
730 | } else { |
||
731 | return true; |
||
732 | } |
||
733 | } |
||
734 | |||
735 | /** |
||
736 | * Casted variable to show if sales are allowed to this country. |
||
737 | * |
||
738 | * @return string |
||
739 | */ |
||
740 | public function AllowSalesNice() |
||
741 | { |
||
742 | return $this->getAllowSalesNice(); |
||
743 | } |
||
744 | public function getAllowSalesNice() |
||
745 | { |
||
746 | if ($this->AllowSales()) { |
||
747 | return _t('EcommerceCountry.YES', 'Yes'); |
||
748 | } else { |
||
749 | return _t('EcommerceCountry.NO', 'No'); |
||
750 | } |
||
751 | } |
||
752 | } |
||
753 |