Region.php 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Customer\Model\Renderer;
  7. use Magento\Framework\Data\Form\Element\AbstractElement;
  8. /**
  9. * Region field renderer
  10. *
  11. * @author Magento Core Team <core@magentocommerce.com>
  12. */
  13. class Region implements \Magento\Framework\Data\Form\Element\Renderer\RendererInterface
  14. {
  15. /**
  16. * Country region collections
  17. *
  18. * Structure:
  19. * array(
  20. * [$countryId] => \Magento\Framework\Data\Collection\AbstractDb
  21. * )
  22. *
  23. * @var array
  24. */
  25. protected static $_regionCollections;
  26. /**
  27. * Adminhtml data
  28. *
  29. * @var \Magento\Framework\Escaper
  30. */
  31. protected $_escaper = null;
  32. /**
  33. * @var \Magento\Directory\Model\CountryFactory
  34. */
  35. protected $_countryFactory;
  36. /**
  37. * @param \Magento\Directory\Model\CountryFactory $countryFactory
  38. * @param \Magento\Directory\Helper\Data $directoryHelper
  39. * @param \Magento\Framework\Escaper $escaper
  40. */
  41. public function __construct(
  42. \Magento\Directory\Model\CountryFactory $countryFactory,
  43. \Magento\Directory\Helper\Data $directoryHelper,
  44. \Magento\Framework\Escaper $escaper
  45. ) {
  46. $this->_countryFactory = $countryFactory;
  47. $this->_directoryHelper = $directoryHelper;
  48. $this->_escaper = $escaper;
  49. }
  50. /**
  51. * Render element
  52. *
  53. * @param AbstractElement $element
  54. * @return string
  55. * @SuppressWarnings(PHPMD.CyclomaticComplexity)
  56. * @SuppressWarnings(PHPMD.NPathComplexity)
  57. */
  58. public function render(AbstractElement $element)
  59. {
  60. $countryId = false;
  61. $isRegionRequired = false;
  62. if ($country = $element->getForm()->getElement('country_id')) {
  63. $countryId = $country->getValue();
  64. $isRegionRequired = $this->_directoryHelper->isRegionRequired($countryId);
  65. }
  66. $html = '<div class="field field-region ' . ($isRegionRequired ? 'required' : '') . '">' . "\n";
  67. $regionCollection = false;
  68. if ($countryId) {
  69. if (!isset(self::$_regionCollections[$countryId])) {
  70. self::$_regionCollections[$countryId] = $this->_countryFactory->create()->setId(
  71. $countryId
  72. )->getLoadedRegionCollection()->toOptionArray();
  73. }
  74. $regionCollection = self::$_regionCollections[$countryId];
  75. }
  76. $regionId = (int)$element->getForm()->getElement('region_id')->getValue();
  77. $htmlAttributes = $element->getHtmlAttributes();
  78. foreach ($htmlAttributes as $key => $attribute) {
  79. if ('type' === $attribute) {
  80. unset($htmlAttributes[$key]);
  81. break;
  82. }
  83. }
  84. // Output two elements - for 'region' and for 'region_id'.
  85. // Two elements are needed later upon form post - to properly set data to address model,
  86. // otherwise old value can be left in region_id attribute and saved to DB.
  87. // Depending on country selected either 'region' (input text) or 'region_id' (selectbox) is visible to user
  88. $regionHtmlName = $element->getName();
  89. $regionIdHtmlName = str_replace('region', 'region_id', $regionHtmlName);
  90. $regionHtmlId = $element->getHtmlId();
  91. $regionIdHtmlId = str_replace('region', 'region_id', $regionHtmlId);
  92. if ($isRegionRequired) {
  93. $element->addClass('required-entry');
  94. }
  95. if ($regionCollection && count($regionCollection) > 0) {
  96. $elementClass = $element->getClass();
  97. $html .= '<label class="label" for="' .
  98. $regionIdHtmlId .
  99. '"><span>' .
  100. $element->getLabel() .
  101. '</span>' .
  102. '</label>';
  103. $html .= '<div class="control">';
  104. $html .= '<select id="' . $regionIdHtmlId . '" name="' . $regionIdHtmlName . '" ' . $element->serialize(
  105. $htmlAttributes
  106. ) . '>' . "\n";
  107. foreach ($regionCollection as $region) {
  108. $selected = $regionId == $region['value'] ? ' selected="selected"' : '';
  109. $regionVal = 0 == $region['value'] ? '' : (int)$region['value'];
  110. $html .= '<option value="' . $regionVal . '"' . $selected . '>' . $this->_escaper->escapeHtml(
  111. __($region['label'])
  112. ) . '</option>';
  113. }
  114. $html .= '</select>' . "\n";
  115. $html .= '<input type="hidden" name="' . $regionHtmlName . '" id="' . $regionHtmlId . '" value=""/>';
  116. $html .= '</div>';
  117. $element->setClass($elementClass);
  118. } else {
  119. $html .= '<label class="label" for="' .
  120. $regionHtmlId .
  121. '"><span>' .
  122. $element->getLabel() .
  123. '</span></label>';
  124. $html .= '<div class="control">';
  125. $html .= '<input id="' .
  126. $regionHtmlId .
  127. '" name="' .
  128. $regionHtmlName .
  129. '" value="' .
  130. $element->getEscapedValue() .
  131. '" ' .
  132. $element->serialize(
  133. $htmlAttributes
  134. ) . "/>" . "\n";
  135. $html .= '<input type="hidden" name="' . $regionIdHtmlName . '" id="' . $regionIdHtmlId . '" value=""/>';
  136. $html .= '</div>' . "\n";
  137. }
  138. $html .= '</div>' . "\n";
  139. return $html;
  140. }
  141. }