| 1 |
<?php |
| 2 |
|
| 3 |
namespace FluentCart\App\Services\Localization; |
| 4 |
|
| 5 |
/* |
| 6 |
* Use cases for LocalizationManager |
| 7 |
* $localization = App::getInstance('localization'); |
| 8 |
* $countries = $localization->countries(); |
| 9 |
* $localization->countriesOptions(); //format as options |
| 10 |
* $localization->states('BD'); |
| 11 |
* $localization->statesOptions('BD'); |
| 12 |
* $localization->phones(); |
| 13 |
* $localization->phonesOptions(); |
| 14 |
* $localization->timezones(); |
| 15 |
* $localization->timezonesOptions(); |
| 16 |
* $localization->continents(); |
| 17 |
* $localization->continents('EU'); |
| 18 |
* $localization->taxContinents('EU'); |
| 19 |
* $localization->continentsCountries('EU'); |
| 20 |
* $localization->continentsCountriesOptions('EU'); |
| 21 |
* $localization->continentFromCountry('BD'); |
| 22 |
* $localization->locales(); |
| 23 |
* $localization->locales('BD'); |
| 24 |
* $localization->localesOptions('BD'); |
| 25 |
* $localization->units(); |
| 26 |
* $localization->addressLocales('BD'); |
| 27 |
* $localization->postcode->isValid(‘NG51GJ', 'GB’) |
| 28 |
* $localization->postcode->formatPostcode(‘NG51GJ', 'GB’) |
| 29 |
* |
| 30 |
*/ |
| 31 |
|
| 32 |
use FluentCart\App\Helpers\CartCheckoutHelper; |
| 33 |
use FluentCart\Framework\Support\Arr; |
| 34 |
use FluentCart\Framework\Support\Collection; |
| 35 |
|
| 36 |
class LocalizationManager |
| 37 |
{ |
| 38 |
private static ?LocalizationManager $instance = null; |
| 39 |
|
| 40 |
static ?array $countries = null; |
| 41 |
static ?array $timeZones = null; |
| 42 |
static ?array $continents = null; |
| 43 |
static ?array $taxContinents = null; |
| 44 |
static ?array $locale = null; |
| 45 |
static ?array $addressLocales = null; |
| 46 |
static ?array $phones = null; |
| 47 |
static ?array $states = null; |
| 48 |
static ?array $units = null; |
| 49 |
|
| 50 |
private static ?PostcodeVerification $postcodeInstance = null; |
| 51 |
|
| 52 |
/** |
| 53 |
* Get the singleton instance |
| 54 |
*/ |
| 55 |
public static function getInstance(): LocalizationManager |
| 56 |
{ |
| 57 |
if (self::$instance === null) { |
| 58 |
self::$instance = new self(); |
| 59 |
} |
| 60 |
return self::$instance; |
| 61 |
} |
| 62 |
|
| 63 |
/** |
| 64 |
* Get all countries |
| 65 |
*/ |
| 66 |
public function countries(): array |
| 67 |
{ |
| 68 |
if (is_array(self::$countries)) { |
| 69 |
return self::$countries; |
| 70 |
} |
| 71 |
self::$countries = require 'i18n/countries.php'; |
| 72 |
return self::$countries; |
| 73 |
} |
| 74 |
|
| 75 |
public function getCountryNameByCode($countryCode) |
| 76 |
{ |
| 77 |
|
| 78 |
if (!$countryCode) { |
| 79 |
return ''; |
| 80 |
} |
| 81 |
|
| 82 |
return Arr::get($this->countries(), $countryCode, $countryCode); |
| 83 |
} |
| 84 |
|
| 85 |
/** |
| 86 |
* Get all timezones |
| 87 |
*/ |
| 88 |
public function timezones(): array |
| 89 |
{ |
| 90 |
if (is_array(self::$timeZones)) { |
| 91 |
return self::$timeZones; |
| 92 |
} |
| 93 |
self::$timeZones = require 'i18n/country_tz.php'; |
| 94 |
return self::$timeZones; |
| 95 |
} |
| 96 |
|
| 97 |
/** |
| 98 |
* Get all continents |
| 99 |
*/ |
| 100 |
public function continents($countryCode = null): array |
| 101 |
{ |
| 102 |
if (is_array(self::$continents)) { |
| 103 |
if ($countryCode) { |
| 104 |
return self::$continents[$countryCode] ?? []; |
| 105 |
} |
| 106 |
return self::$continents; |
| 107 |
} |
| 108 |
self::$continents = require 'i18n/continents.php'; |
| 109 |
if ($countryCode) { |
| 110 |
return self::$continents[$countryCode] ?? []; |
| 111 |
} |
| 112 |
return self::$continents; |
| 113 |
} |
| 114 |
|
| 115 |
/** |
| 116 |
* Get all continents |
| 117 |
*/ |
| 118 |
public function taxContinents($countryCode = null): array |
| 119 |
{ |
| 120 |
if (is_array(self::$taxContinents)) { |
| 121 |
if ($countryCode) { |
| 122 |
return self::$taxContinents[$countryCode] ?? []; |
| 123 |
} |
| 124 |
return self::$taxContinents; |
| 125 |
} |
| 126 |
self::$taxContinents = require 'i18n/eu_tax_countries.php'; |
| 127 |
if ($countryCode) { |
| 128 |
return self::$taxContinents[$countryCode] ?? []; |
| 129 |
} |
| 130 |
return self::$taxContinents; |
| 131 |
} |
| 132 |
|
| 133 |
/** |
| 134 |
* Get all phone codes |
| 135 |
*/ |
| 136 |
public function phones(): array |
| 137 |
{ |
| 138 |
if (is_array(self::$phones)) { |
| 139 |
return self::$phones; |
| 140 |
} |
| 141 |
self::$phones = require 'i18n/phone.php'; |
| 142 |
return self::$phones; |
| 143 |
} |
| 144 |
|
| 145 |
/** |
| 146 |
* Get all locale information |
| 147 |
*/ |
| 148 |
public function locales($countryCode = null): array |
| 149 |
{ |
| 150 |
if (is_array(self::$locale)) { |
| 151 |
if ($countryCode) { |
| 152 |
return self::$locale[$countryCode] ?? []; |
| 153 |
} |
| 154 |
return self::$locale; |
| 155 |
} |
| 156 |
self::$locale = require 'i18n/locale-info.php'; |
| 157 |
if ($countryCode) { |
| 158 |
return self::$locale[$countryCode] ?? []; |
| 159 |
} |
| 160 |
return self::$locale; |
| 161 |
} |
| 162 |
|
| 163 |
public function addressLocales($countryCode = null): array |
| 164 |
{ |
| 165 |
if (!is_array(self::$addressLocales)) { |
| 166 |
self::$addressLocales = require 'i18n/address-locales.php'; |
| 167 |
} |
| 168 |
|
| 169 |
if ($countryCode) { |
| 170 |
return self::$addressLocales[$countryCode] ?? []; |
| 171 |
} |
| 172 |
return self::$addressLocales; |
| 173 |
} |
| 174 |
|
| 175 |
/** |
| 176 |
* Get all states/provinces |
| 177 |
*/ |
| 178 |
public function states($countryCode = null): array |
| 179 |
{ |
| 180 |
if (is_array(self::$states)) { |
| 181 |
if ($countryCode) { |
| 182 |
return self::$states[$countryCode] ?? []; |
| 183 |
} |
| 184 |
return self::$states; |
| 185 |
} |
| 186 |
self::$states = require 'i18n/states.php'; |
| 187 |
if ($countryCode) { |
| 188 |
return self::$states[$countryCode] ?? []; |
| 189 |
} |
| 190 |
return self::$states; |
| 191 |
} |
| 192 |
|
| 193 |
public function getStateNameByCode($stateCode, $countryCode = null) |
| 194 |
{ |
| 195 |
if (empty($countryCode)) { |
| 196 |
$states = $this->states(); |
| 197 |
} else { |
| 198 |
$states = Arr::get($this->states(), $countryCode); |
| 199 |
if ($states) { |
| 200 |
$states = [ |
| 201 |
$countryCode => $states |
| 202 |
]; |
| 203 |
} else { |
| 204 |
$states = []; |
| 205 |
} |
| 206 |
} |
| 207 |
|
| 208 |
$collection = new Collection($states); |
| 209 |
$flat = $collection->flatMap(function ($items) { |
| 210 |
return $items; |
| 211 |
}); |
| 212 |
return $flat->get($stateCode, $stateCode); |
| 213 |
} |
| 214 |
|
| 215 |
/** |
| 216 |
* Get all measurement units |
| 217 |
*/ |
| 218 |
public function units(): array |
| 219 |
{ |
| 220 |
if (is_array(self::$units)) { |
| 221 |
return self::$units; |
| 222 |
} |
| 223 |
self::$units = require 'i18n/units.php'; |
| 224 |
return self::$units; |
| 225 |
} |
| 226 |
|
| 227 |
/** |
| 228 |
* Convert array to options format |
| 229 |
*/ |
| 230 |
private function toOptions(array $items, bool $includeCountries = false): array |
| 231 |
{ |
| 232 |
$options = []; |
| 233 |
foreach ($items as $code => $item) { |
| 234 |
$option = [ |
| 235 |
'value' => $code, |
| 236 |
'name' => is_array($item) ? ($item['name'] ?? $code) : $item, |
| 237 |
]; |
| 238 |
|
| 239 |
if ($includeCountries && isset($item['countries'])) { |
| 240 |
$option['options'] = $item['countries']; |
| 241 |
} |
| 242 |
|
| 243 |
$options[] = $option; |
| 244 |
} |
| 245 |
return $options; |
| 246 |
} |
| 247 |
|
| 248 |
/** |
| 249 |
* Get country ISO lists |
| 250 |
*/ |
| 251 |
public function countryIsoList(): array |
| 252 |
{ |
| 253 |
return $this->countries(); |
| 254 |
} |
| 255 |
|
| 256 |
/** |
| 257 |
* Get countries as options |
| 258 |
*/ |
| 259 |
public function countriesOptions(): array |
| 260 |
{ |
| 261 |
return $this->toOptions($this->countries()); |
| 262 |
} |
| 263 |
|
| 264 |
/** |
| 265 |
* Get phone codes as options |
| 266 |
*/ |
| 267 |
public function phonesOptions(): array |
| 268 |
{ |
| 269 |
return $this->toOptions($this->phones()); |
| 270 |
} |
| 271 |
|
| 272 |
/** |
| 273 |
* Get continents as options |
| 274 |
*/ |
| 275 |
public function continentsOptions(): array |
| 276 |
{ |
| 277 |
$continents = $this->continents(); |
| 278 |
$options = []; |
| 279 |
foreach ($continents as $code => $continent) { |
| 280 |
$options[] = [ |
| 281 |
'value' => $code, |
| 282 |
'name' => $continent, |
| 283 |
'options' => $continent['countries'] ?? [] |
| 284 |
]; |
| 285 |
} |
| 286 |
return $options; |
| 287 |
} |
| 288 |
|
| 289 |
public function continentsCountries(string $continentCode): array |
| 290 |
{ |
| 291 |
$continents = $this->continents($continentCode); |
| 292 |
$contentsCountries = $continents['countries'] ?? []; |
| 293 |
$countries = []; |
| 294 |
foreach ($contentsCountries as $continent) { |
| 295 |
$countries[$continent] = $this->countries()[$continent] ?? $continent; |
| 296 |
} |
| 297 |
return $countries; |
| 298 |
} |
| 299 |
|
| 300 |
public function continentsCountriesOptions(string $continentCode): array |
| 301 |
{ |
| 302 |
$continents = $this->continents($continentCode); |
| 303 |
$contentsCountries = []; |
| 304 |
$countries = []; |
| 305 |
if ($continentCode) { |
| 306 |
$contentsCountries = $continents['countries'] ?? []; |
| 307 |
} |
| 308 |
foreach ($contentsCountries as $continent) { |
| 309 |
$countries[] = [ |
| 310 |
'value' => $continent, |
| 311 |
'name' => $this->countries()[$continent] ?? $continent, |
| 312 |
]; |
| 313 |
} |
| 314 |
return $countries; |
| 315 |
} |
| 316 |
|
| 317 |
public function timeZonesOptions(): array |
| 318 |
{ |
| 319 |
return $this->toOptions($this->timezones(), true); |
| 320 |
} |
| 321 |
|
| 322 |
public function localesOptions(): array |
| 323 |
{ |
| 324 |
$locales = $this->locales(); |
| 325 |
$options = []; |
| 326 |
foreach ($locales as $code => $localesInfo) { |
| 327 |
$options[] = [ |
| 328 |
'value' => $localesInfo, |
| 329 |
'name' => $code, |
| 330 |
]; |
| 331 |
} |
| 332 |
return $options; |
| 333 |
} |
| 334 |
|
| 335 |
public function statesOptions($countryCode = null): array |
| 336 |
{ |
| 337 |
if ($countryCode) { |
| 338 |
return $this->countryStatesOptions($countryCode); |
| 339 |
} |
| 340 |
return array_map(function ($states) { |
| 341 |
return [ |
| 342 |
'options' => $states |
| 343 |
]; |
| 344 |
}, $this->states()); |
| 345 |
} |
| 346 |
|
| 347 |
/** |
| 348 |
* Guess country code from timezone |
| 349 |
*/ |
| 350 |
public function guessCountryTimezone(string $timezone): ?string |
| 351 |
{ |
| 352 |
$timezoneMap = $this->timezones(); |
| 353 |
|
| 354 |
// Check for exact matches first |
| 355 |
if (isset($timezoneMap[$timezone])) { |
| 356 |
return $timezoneMap[$timezone]; |
| 357 |
} |
| 358 |
|
| 359 |
// Check for partial matches |
| 360 |
foreach ($timezoneMap as $prefix => $countryCode) { |
| 361 |
if (strpos($timezone, $prefix) === 0) { |
| 362 |
return $countryCode; |
| 363 |
} |
| 364 |
} |
| 365 |
|
| 366 |
return null; |
| 367 |
} |
| 368 |
|
| 369 |
/** |
| 370 |
* Get continent code for a country |
| 371 |
*/ |
| 372 |
public function continentFromCountry(string $countryCode): string |
| 373 |
{ |
| 374 |
$countryCode = trim(strtoupper($countryCode)); |
| 375 |
$continents = $this->continents(); |
| 376 |
$continents_and_codes = wp_list_pluck($continents, 'countries'); |
| 377 |
foreach ($continents_and_codes as $continentCode => $countries) { |
| 378 |
if (false !== array_search($countryCode, $countries, true)) { |
| 379 |
return $continentCode; |
| 380 |
} |
| 381 |
} |
| 382 |
return ''; |
| 383 |
} |
| 384 |
|
| 385 |
/** |
| 386 |
* Check whether a country is part of the EU VAT country list. |
| 387 |
*/ |
| 388 |
public function isEuTaxCountry(string $countryCode): bool |
| 389 |
{ |
| 390 |
$countryCode = trim(strtoupper($countryCode)); |
| 391 |
|
| 392 |
if ($countryCode === '') { |
| 393 |
return false; |
| 394 |
} |
| 395 |
|
| 396 |
$euCountries = Arr::get($this->taxContinents('EU'), 'countries', []); |
| 397 |
|
| 398 |
return in_array($countryCode, $euCountries, true); |
| 399 |
} |
| 400 |
|
| 401 |
/** |
| 402 |
* Get calling code for a country |
| 403 |
*/ |
| 404 |
public function callingCode(string $countryCode): string |
| 405 |
{ |
| 406 |
$calling_codes = $this->phones(); |
| 407 |
return $calling_codes[$countryCode] ?? ''; |
| 408 |
} |
| 409 |
|
| 410 |
/** |
| 411 |
* Get locale for a country |
| 412 |
*/ |
| 413 |
public function localeForCountry(string $countryCode): string |
| 414 |
{ |
| 415 |
$locales = $this->locales(); |
| 416 |
return $locales[$countryCode] ?? ''; |
| 417 |
} |
| 418 |
|
| 419 |
/** |
| 420 |
* Get states for a country |
| 421 |
*/ |
| 422 |
public function countryStates(string $countryCode): array |
| 423 |
{ |
| 424 |
$states = $this->states(); |
| 425 |
return Arr::get($states, $countryCode, []); |
| 426 |
} |
| 427 |
|
| 428 |
/** |
| 429 |
* Get states for a country as options |
| 430 |
*/ |
| 431 |
public function countryStatesOptions(string $countryCode): array |
| 432 |
{ |
| 433 |
$states = $this->countryStates($countryCode); |
| 434 |
$options = []; |
| 435 |
foreach ($states as $code => $state) { |
| 436 |
$options[] = [ |
| 437 |
'value' => $code, |
| 438 |
'name' => $state, |
| 439 |
]; |
| 440 |
} |
| 441 |
return apply_filters("fluent_cart/country_state_options", $options, [ |
| 442 |
'countryCode' => $countryCode, |
| 443 |
]); |
| 444 |
} |
| 445 |
|
| 446 |
// Static proxy methods for backward compatibility |
| 447 |
public static function getCountries(): array |
| 448 |
{ |
| 449 |
return self::getInstance()->countries(); |
| 450 |
} |
| 451 |
|
| 452 |
public static function getTimeZones(): array |
| 453 |
{ |
| 454 |
return self::getInstance()->timezones(); |
| 455 |
} |
| 456 |
|
| 457 |
public static function getContinents(): array |
| 458 |
{ |
| 459 |
return self::getInstance()->continents(); |
| 460 |
} |
| 461 |
|
| 462 |
public static function getPhones(): array |
| 463 |
{ |
| 464 |
return self::getInstance()->phones(); |
| 465 |
} |
| 466 |
|
| 467 |
public static function getLocale($countryCode = null): array |
| 468 |
{ |
| 469 |
return self::getInstance()->locales($countryCode); |
| 470 |
} |
| 471 |
|
| 472 |
public static function getStates(): array |
| 473 |
{ |
| 474 |
return self::getInstance()->states(); |
| 475 |
} |
| 476 |
|
| 477 |
public static function getUnits(): array |
| 478 |
{ |
| 479 |
return self::getInstance()->units(); |
| 480 |
} |
| 481 |
|
| 482 |
public static function getCountyIsoLists(): array |
| 483 |
{ |
| 484 |
return self::getInstance()->countryIsoList(); |
| 485 |
} |
| 486 |
|
| 487 |
public static function guessCountryFromTimezone(string $timezone): ?string |
| 488 |
{ |
| 489 |
return self::getInstance()->guessCountryTimezone($timezone); |
| 490 |
} |
| 491 |
|
| 492 |
public static function getCountryCallingCode($countryCode): string |
| 493 |
{ |
| 494 |
return self::getInstance()->callingCode($countryCode); |
| 495 |
} |
| 496 |
|
| 497 |
public static function getCountryStates($countryCode): array |
| 498 |
{ |
| 499 |
return self::getInstance()->countryStates($countryCode); |
| 500 |
} |
| 501 |
|
| 502 |
public static function getAddressLocales($countryCode): array |
| 503 |
{ |
| 504 |
return self::getInstance()->addressLocales($countryCode); |
| 505 |
} |
| 506 |
|
| 507 |
public static function isValidCountryCode($code) |
| 508 |
{ |
| 509 |
$countries = self::getInstance()->countries(); |
| 510 |
// dd($countries); |
| 511 |
} |
| 512 |
|
| 513 |
public static function getCountryInfoFromRequest($timezone, $countryCode): array |
| 514 |
{ |
| 515 |
if (!$countryCode && $timezone) { |
| 516 |
$countryCode = self::guessCountryFromTimezone($timezone); |
| 517 |
} |
| 518 |
|
| 519 |
if (!$countryCode) { |
| 520 |
return [ |
| 521 |
'country_code' => '', |
| 522 |
'states' => [], |
| 523 |
'address_locale' => [] |
| 524 |
]; |
| 525 |
} |
| 526 |
|
| 527 |
$states = self::getInstance()->statesOptions($countryCode); |
| 528 |
$addressLocale = self::getInstance()->addressLocales($countryCode); |
| 529 |
|
| 530 |
return [ |
| 531 |
'country_code' => $countryCode, |
| 532 |
'states' => $states, |
| 533 |
'address_locale' => $addressLocale |
| 534 |
]; |
| 535 |
} |
| 536 |
|
| 537 |
/** |
| 538 |
* Magic method to access properties |
| 539 |
*/ |
| 540 |
public function __get($name) |
| 541 |
{ |
| 542 |
if ($name === 'postcode') { |
| 543 |
return $this->getPostcodeInstance(); |
| 544 |
} |
| 545 |
|
| 546 |
return null; |
| 547 |
} |
| 548 |
|
| 549 |
/** |
| 550 |
* Get postcode verification instance |
| 551 |
*/ |
| 552 |
private function getPostcodeInstance(): PostcodeVerification |
| 553 |
{ |
| 554 |
if (self::$postcodeInstance === null) { |
| 555 |
self::$postcodeInstance = new PostcodeVerification(); |
| 556 |
} |
| 557 |
return self::$postcodeInstance; |
| 558 |
} |
| 559 |
|
| 560 |
/** |
| 561 |
* Static method to get postcode verification instance |
| 562 |
*/ |
| 563 |
public static function postcode() |
| 564 |
{ |
| 565 |
return self::getInstance()->getPostcodeInstance(); |
| 566 |
} |
| 567 |
|
| 568 |
public function getZipCodeValidationRule($countryCode): array |
| 569 |
{ |
| 570 |
|
| 571 |
if (!$countryCode) { |
| 572 |
return ['string', 'maxLength:192']; |
| 573 |
} |
| 574 |
$locale = $this->addressLocales($countryCode); |
| 575 |
|
| 576 |
$isZipcodeRequired = Arr::get($locale, 'postcode.required', true) !== false; |
| 577 |
if (!$isZipcodeRequired) { |
| 578 |
return ['string', 'maxLength:192']; |
| 579 |
} |
| 580 |
return ['required', 'string', 'maxLength:192']; |
| 581 |
} |
| 582 |
|
| 583 |
public function getValidationRule($data, $prefix = '', $defaultRoles = []): array |
| 584 |
{ |
| 585 |
$prefix = $prefix ? $prefix . '_' : ''; |
| 586 |
$countries = $this->countries(); |
| 587 |
$country = Arr::get($data, $prefix . 'country'); |
| 588 |
$addressLocale = $this->addressLocales($country); |
| 589 |
$stateRequired = (string)(Arr::get($addressLocale, 'state.hidden', '')) !== '1'; |
| 590 |
|
| 591 |
if (Arr::get($addressLocale, 'state.required', true) === false) { |
| 592 |
$stateRequired = false; |
| 593 |
} |
| 594 |
|
| 595 |
$states = empty($country) ? [] : $this->countryStates($country); |
| 596 |
|
| 597 |
$defaultCountryRoles = Arr::wrap(Arr::get($defaultRoles, 'country', [])); |
| 598 |
$defaultStateRoles = Arr::wrap(Arr::get($defaultRoles, 'state', [])); |
| 599 |
$defaultPostcodeRoles = Arr::wrap(Arr::get($defaultRoles, 'postcode', [])); |
| 600 |
|
| 601 |
// Get current field structure based on prefix (billing/shipping) |
| 602 |
$checkoutHelper = CartCheckoutHelper::make(); |
| 603 |
$fields = $prefix === 'billing_' |
| 604 |
? $checkoutHelper->getBillingAddressFields() |
| 605 |
: $checkoutHelper->getShippingAddressFields(); |
| 606 |
|
| 607 |
$addressSchema = Arr::get($fields, 'address_section.schema', []); |
| 608 |
|
| 609 |
$rules = []; |
| 610 |
|
| 611 |
if (isset($addressSchema['country'])) { |
| 612 |
$rules[$prefix . 'country'] = array_merge($defaultCountryRoles, [ |
| 613 |
static function ($attribute, $value) use ($countries) { |
| 614 |
$isValid = Arr::has($countries, $value); |
| 615 |
if (!$isValid) { |
| 616 |
return __('Invalid country code.', 'fluent-cart'); |
| 617 |
} |
| 618 |
} |
| 619 |
]); |
| 620 |
} |
| 621 |
|
| 622 |
if (isset($addressSchema['state'])) { |
| 623 |
$rules[$prefix . 'state'] = array_merge($defaultStateRoles, [ |
| 624 |
'required' => static function ($attribute, $value) use ($stateRequired) { |
| 625 |
|
| 626 |
if ($stateRequired && !$value) { |
| 627 |
return __('State is required.', 'fluent-cart'); |
| 628 |
} |
| 629 |
return null; |
| 630 |
}, |
| 631 |
'invalid' => static function ($attribute, $value) use ($data, $country, $states) { |
| 632 |
|
| 633 |
if (!is_array($states)) { |
| 634 |
return null; |
| 635 |
} |
| 636 |
|
| 637 |
if (empty($states)) { |
| 638 |
return null; |
| 639 |
} |
| 640 |
if ($country && $value) { |
| 641 |
$isValid = Arr::has($states, $value); |
| 642 |
if (!$isValid) { |
| 643 |
return __('Invalid state code.', 'fluent-cart'); |
| 644 |
} |
| 645 |
} |
| 646 |
|
| 647 |
return null; |
| 648 |
} |
| 649 |
]); |
| 650 |
} |
| 651 |
|
| 652 |
if (isset($cityZipSchema['postcode'])) { |
| 653 |
$rules[$prefix . 'postcode'] = array_merge( |
| 654 |
$defaultPostcodeRoles, |
| 655 |
$this->getZipCodeValidationRule($country) |
| 656 |
); |
| 657 |
} |
| 658 |
|
| 659 |
return $rules; |
| 660 |
|
| 661 |
// return [ |
| 662 |
// $prefix . 'country' => array_merge($defaultCountryRoles, |
| 663 |
// [ |
| 664 |
// static function ($attribute, $value) use ($countries) { |
| 665 |
// $isValid = Arr::has($countries, $value); |
| 666 |
// if (!$isValid) { |
| 667 |
// return __('Invalid country code.', 'fluent-cart'); |
| 668 |
// } |
| 669 |
// } |
| 670 |
// ] |
| 671 |
// ), |
| 672 |
// $prefix . 'state' => array_merge($defaultStateRoles, |
| 673 |
// [ |
| 674 |
// static function ($attribute, $value) use ($stateRequired) { |
| 675 |
// if ($stateRequired && !$value) { |
| 676 |
// return __('State is required.', 'fluent-cart'); |
| 677 |
// } |
| 678 |
// }, |
| 679 |
// static function ($attribute, $value) use ($data, $country, $states) { |
| 680 |
// if ($country && $value) { |
| 681 |
// $isValid = Arr::has($states, $value); |
| 682 |
// if (!$isValid) { |
| 683 |
// return __('Invalid state code 2.', 'fluent-cart'); |
| 684 |
// } |
| 685 |
// } |
| 686 |
// } |
| 687 |
// ] |
| 688 |
// ), |
| 689 |
// $prefix . 'postcode' => array_merge( |
| 690 |
// $defaultPostcodeRoles, |
| 691 |
// $this->getZipCodeValidationRule($country) |
| 692 |
// ), |
| 693 |
// ]; |
| 694 |
} |
| 695 |
|
| 696 |
} |
| 697 |
|