How to get only one Specific Country's States/Province in dropdown?
-
17-03-2021 - |
문제
I'm working on Magento 2.3.2
, I override a Shipping Method
file which is system.xml
for adding custom fields. Here it is:
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Config:etc/system_file.xsd">
<system>
<section id="carriers" type="text" sortOrder="320" showInDefault="1" showInWebsite="1" showInStore="1">
<group id="flatrate" translate="label" type="text" sortOrder="0" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Flat Rate</label>
<field id="tax_address" translate="label" type="text" sortOrder="98" showInDefault="1" showInWebsite="1" showInStore="0" >
<label>Tax Address</label>
</field>
<field id="tax_state" translate="label" type="select" sortOrder="99" showInDefault="1" showInWebsite="1" showInStore="0" >
<label>Tax State</label>
<source_model>Magento\Directory\Model\Config\Source\Allregion</source_model>
</field>
<field id="tax_zip_code" translate="label" type="text" sortOrder="99" showInDefault="1" showInWebsite="1" showInStore="0" >
<label>Tax Zip Code</label>
</field>
</section>
</system>
</config>
In Tax State
field I'm using <source_model>Magento\Directory\Model\Config\Source\Allregion</source_model>
to get Regions/State/Provice, I know it'll fetch me all country regions, I just want to fetch only United Stated Regions.
This is the file Magento\Directory\Model\Config\Source
which is responsible for getting All Regions:
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
namespace Magento\Directory\Model\Config\Source;
/**
* Options provider for regions list
*
* @api
* @since 100.0.2
*/
class Allregion implements \Magento\Framework\Option\ArrayInterface
{
/**
* @var array
*/
protected $_countries;
/**
* @var array
*/
protected $_options;
/**
* @var \Magento\Directory\Model\ResourceModel\Country\CollectionFactory
*/
protected $_countryCollectionFactory;
/**
* @var \Magento\Directory\Model\ResourceModel\Region\CollectionFactory
*/
protected $_regionCollectionFactory;
/**
* @param \Magento\Directory\Model\ResourceModel\Country\CollectionFactory $countryCollectionFactory
* @param \Magento\Directory\Model\ResourceModel\Region\CollectionFactory $regionCollectionFactory
*/
public function __construct(
\Magento\Directory\Model\ResourceModel\Country\CollectionFactory $countryCollectionFactory,
\Magento\Directory\Model\ResourceModel\Region\CollectionFactory $regionCollectionFactory
) {
$this->_countryCollectionFactory = $countryCollectionFactory;
$this->_regionCollectionFactory = $regionCollectionFactory;
}
/**
* @param bool $isMultiselect
* @return array
*/
public function toOptionArray($isMultiselect = false)
{
if (!$this->_options) {
$countriesArray = $this->_countryCollectionFactory->create()->load()->toOptionArray(false);
$this->_countries = [];
foreach ($countriesArray as $a) {
$this->_countries[$a['value']] = $a['label'];
}
$countryRegions = [];
$regionsCollection = $this->_regionCollectionFactory->create()->load();
foreach ($regionsCollection as $region) {
$countryRegions[$region->getCountryId()][$region->getId()] = $region->getDefaultName();
}
uksort($countryRegions, [$this, 'sortRegionCountries']);
$this->_options = [];
foreach ($countryRegions as $countryId => $regions) {
$regionOptions = [];
foreach ($regions as $regionId => $regionName) {
$regionOptions[] = ['label' => $regionName, 'value' => $regionId];
}
$this->_options[] = ['label' => $this->_countries[$countryId], 'value' => $regionOptions];
}
}
$options = $this->_options;
if (!$isMultiselect) {
array_unshift($options, ['value' => '', 'label' => '']);
}
return $options;
}
/**
* @param string $a
* @param string $b
* @return int
*/
public function sortRegionCountries($a, $b)
{
return strcmp($this->_countries[$a], $this->_countries[$b]);
}
}
해결책
Okay finally I found my answer, I create this Modal to get all United States regions app/code/[Vendor]/[Module]/Model/Config/Region/RegionInformationProvider.php
<?php
namespace [Vendor]\[Module]\Model\Config\Region;
class RegionInformationProvider
{
protected $countryInformationAcquirer;
protected $addressRepository;
public function __construct(
\Magento\Directory\Api\CountryInformationAcquirerInterface $countryInformationAcquirer
) {
$this->countryInformationAcquirer = $countryInformationAcquirer;
}
public function toOptionArray()
{
$countries = $this->countryInformationAcquirer->getCountriesInfo();
foreach ($countries as $country) {
if($country->getId() == 'US'){
$regions = [];
if ($availableRegions = $country->getAvailableRegions()) {
foreach ($availableRegions as $region) {
$regions[] = [
'value' => $region->getId(),
'label' => $region->getName()
];
}
}
}
}
return $regions;
}
}
In Magento 2
admin panel, go to Stores → Configuration from the left-side navigation panel. Then Goto General section → General → Country options → Choose ‘United States’ in Allowed Countries. Because we only list the allowed countries states in our custom system configuration field.
And your system.xml
is something like this:
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Config:etc/system_file.xsd">
<system>
<section id="carriers" type="text" sortOrder="320" showInDefault="1" showInWebsite="1" showInStore="1">
<group id="flatrate" translate="label" type="text" sortOrder="0" showInDefault="1" showInWebsite="1" showInStore="1">
<field id="instorepickup_tax_state" translate="label" type="select" sortOrder="99" showInDefault="1" showInWebsite="1" showInStore="0" >
<label>Tax State</label>
<source_model>[Vendor]\[Module]\Model\Config\Region\RegionInformationProvider</source_model>
</field>
</group>
</section>
</system>
</config>