Country.php 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Customer\Model\Address\Validator;
  7. use Magento\Customer\Model\Address\AbstractAddress;
  8. use Magento\Customer\Model\Address\ValidatorInterface;
  9. use Magento\Directory\Helper\Data;
  10. use Magento\Directory\Model\AllowedCountries;
  11. use Magento\Store\Model\ScopeInterface;
  12. /**
  13. * Address country and region validator.
  14. */
  15. class Country implements ValidatorInterface
  16. {
  17. /**
  18. * @var Data
  19. */
  20. private $directoryData;
  21. /**
  22. * @var AllowedCountries
  23. */
  24. private $allowedCountriesReader;
  25. /**
  26. * @param Data $directoryData
  27. * @param AllowedCountries $allowedCountriesReader
  28. */
  29. public function __construct(
  30. Data $directoryData,
  31. AllowedCountries $allowedCountriesReader
  32. ) {
  33. $this->directoryData = $directoryData;
  34. $this->allowedCountriesReader = $allowedCountriesReader;
  35. }
  36. /**
  37. * @inheritdoc
  38. */
  39. public function validate(AbstractAddress $address)
  40. {
  41. $errors = $this->validateCountry($address);
  42. if (empty($errors)) {
  43. $errors = $this->validateRegion($address);
  44. }
  45. return $errors;
  46. }
  47. /**
  48. * Validate country existence.
  49. *
  50. * @param AbstractAddress $address
  51. * @return array
  52. */
  53. private function validateCountry(AbstractAddress $address)
  54. {
  55. $countryId = $address->getCountryId();
  56. $errors = [];
  57. if (!\Zend_Validate::is($countryId, 'NotEmpty')) {
  58. $errors[] = __('"%fieldName" is required. Enter and try again.', ['fieldName' => 'countryId']);
  59. } elseif (!in_array($countryId, $this->getWebsiteAllowedCountries($address), true)) {
  60. //Checking if such country exists.
  61. $errors[] = __(
  62. 'Invalid value of "%value" provided for the %fieldName field.',
  63. ['fieldName' => 'countryId', 'value' => htmlspecialchars($countryId)]
  64. );
  65. }
  66. return $errors;
  67. }
  68. /**
  69. * Validate region existence.
  70. *
  71. * @param AbstractAddress $address
  72. * @return array
  73. * @throws \Zend_Validate_Exception
  74. * @SuppressWarnings(PHPMD.CyclomaticComplexity)
  75. */
  76. private function validateRegion(AbstractAddress $address)
  77. {
  78. $errors = [];
  79. $countryId = $address->getCountryId();
  80. $countryModel = $address->getCountryModel();
  81. $regionCollection = $countryModel->getRegionCollection();
  82. $region = $address->getRegion();
  83. $regionId = (string)$address->getRegionId();
  84. $allowedRegions = $regionCollection->getAllIds();
  85. $isRegionRequired = $this->directoryData->isRegionRequired($countryId);
  86. if ($isRegionRequired && empty($allowedRegions) && !\Zend_Validate::is($region, 'NotEmpty')) {
  87. //If region is required for country and country doesn't provide regions list
  88. //region must be provided.
  89. $errors[] = __('"%fieldName" is required. Enter and try again.', ['fieldName' => 'region']);
  90. } elseif ($allowedRegions && !\Zend_Validate::is($regionId, 'NotEmpty') && $isRegionRequired) {
  91. //If country actually has regions and requires you to
  92. //select one then it must be selected.
  93. $errors[] = __('"%fieldName" is required. Enter and try again.', ['fieldName' => 'regionId']);
  94. } elseif ($allowedRegions && $regionId && !in_array($regionId, $allowedRegions, true)) {
  95. //If a region is selected then checking if it exists.
  96. $errors[] = __(
  97. 'Invalid value of "%value" provided for the %fieldName field.',
  98. ['fieldName' => 'regionId', 'value' => htmlspecialchars($regionId)]
  99. );
  100. }
  101. return $errors;
  102. }
  103. /**
  104. * Return allowed counties per website.
  105. *
  106. * @param AbstractAddress $address
  107. * @return array
  108. */
  109. private function getWebsiteAllowedCountries(AbstractAddress $address): array
  110. {
  111. $storeId = $address->getData('store_id');
  112. return $this->allowedCountriesReader->getAllowedCountries(ScopeInterface::SCOPE_STORE, $storeId);
  113. }
  114. }