DirectoryDataProcessor.php 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Checkout\Block\Checkout;
  7. use Magento\Directory\Helper\Data as DirectoryHelper;
  8. use Magento\Store\Model\StoreManagerInterface;
  9. use Magento\Store\Api\StoreResolverInterface;
  10. use Magento\Framework\App\ObjectManager;
  11. /**
  12. * Directory data processor.
  13. *
  14. * This class adds various country and region dictionaries to checkout page.
  15. * This data can be used by other UI components during checkout flow.
  16. */
  17. class DirectoryDataProcessor implements \Magento\Checkout\Block\Checkout\LayoutProcessorInterface
  18. {
  19. /**
  20. * @var array
  21. */
  22. private $countryOptions;
  23. /**
  24. * @var array
  25. */
  26. private $regionOptions;
  27. /**
  28. * @var \Magento\Directory\Model\ResourceModel\Region\CollectionFactory
  29. */
  30. private $regionCollectionFactory;
  31. /**
  32. * @var \Magento\Directory\Model\ResourceModel\Region\CollectionFactory
  33. */
  34. private $countryCollectionFactory;
  35. /**
  36. * @var StoreManagerInterface
  37. */
  38. private $storeManager;
  39. /**
  40. * @var DirectoryHelper
  41. */
  42. private $directoryHelper;
  43. /**
  44. * @param \Magento\Directory\Model\ResourceModel\Country\CollectionFactory $countryCollection
  45. * @param \Magento\Directory\Model\ResourceModel\Region\CollectionFactory $regionCollection
  46. * @param StoreResolverInterface $storeResolver @deprecated
  47. * @param DirectoryHelper $directoryHelper
  48. * @param StoreManagerInterface $storeManager
  49. * @SuppressWarnings(PHPMD.UnusedFormalParameter)
  50. */
  51. public function __construct(
  52. \Magento\Directory\Model\ResourceModel\Country\CollectionFactory $countryCollection,
  53. \Magento\Directory\Model\ResourceModel\Region\CollectionFactory $regionCollection,
  54. StoreResolverInterface $storeResolver,
  55. DirectoryHelper $directoryHelper,
  56. StoreManagerInterface $storeManager = null
  57. ) {
  58. $this->countryCollectionFactory = $countryCollection;
  59. $this->regionCollectionFactory = $regionCollection;
  60. $this->directoryHelper = $directoryHelper;
  61. $this->storeManager = $storeManager ?: ObjectManager::getInstance()->get(StoreManagerInterface::class);
  62. }
  63. /**
  64. * Process js Layout of block
  65. *
  66. * @param array $jsLayout
  67. * @return array
  68. */
  69. public function process($jsLayout)
  70. {
  71. if (!isset($jsLayout['components']['checkoutProvider']['dictionaries'])) {
  72. $jsLayout['components']['checkoutProvider']['dictionaries'] = [
  73. 'country_id' => $this->getCountryOptions(),
  74. 'region_id' => $this->getRegionOptions(),
  75. ];
  76. }
  77. return $jsLayout;
  78. }
  79. /**
  80. * Get country options list.
  81. *
  82. * @return array
  83. */
  84. private function getCountryOptions()
  85. {
  86. if (!isset($this->countryOptions)) {
  87. $this->countryOptions = $this->countryCollectionFactory->create()->loadByStore(
  88. $this->storeManager->getStore()->getId()
  89. )->toOptionArray();
  90. $this->countryOptions = $this->orderCountryOptions($this->countryOptions);
  91. }
  92. return $this->countryOptions;
  93. }
  94. /**
  95. * Get region options list.
  96. *
  97. * @return array
  98. */
  99. private function getRegionOptions()
  100. {
  101. if (!isset($this->regionOptions)) {
  102. $this->regionOptions = $this->regionCollectionFactory->create()->addAllowedCountriesFilter(
  103. $this->storeManager->getStore()->getId()
  104. )->toOptionArray();
  105. }
  106. return $this->regionOptions;
  107. }
  108. /**
  109. * Sort country options by top country codes.
  110. *
  111. * @param array $countryOptions
  112. * @return array
  113. */
  114. private function orderCountryOptions(array $countryOptions)
  115. {
  116. $topCountryCodes = $this->directoryHelper->getTopCountryCodes();
  117. if (empty($topCountryCodes)) {
  118. return $countryOptions;
  119. }
  120. $headOptions = [];
  121. $tailOptions = [[
  122. 'value' => 'delimiter',
  123. 'label' => '──────────',
  124. 'disabled' => true,
  125. ]];
  126. foreach ($countryOptions as $countryOption) {
  127. if (empty($countryOption['value']) || in_array($countryOption['value'], $topCountryCodes)) {
  128. $headOptions[] = $countryOption;
  129. } else {
  130. $tailOptions[] = $countryOption;
  131. }
  132. }
  133. return array_merge($headOptions, $tailOptions);
  134. }
  135. }