mirror of
https://github.com/bdnugget/magento2.git
synced 2026-11-07 17:27:36 +00:00
449 lines
13 KiB
PHP
449 lines
13 KiB
PHP
<?php
|
|
/**
|
|
* Copyright © Magento, Inc. All rights reserved.
|
|
* See COPYING.txt for license details.
|
|
*/
|
|
|
|
namespace Magento\Directory\Helper;
|
|
|
|
use Magento\Directory\Model\AllowedCountries;
|
|
use Magento\Directory\Model\Currency;
|
|
use Magento\Directory\Model\CurrencyFactory;
|
|
use Magento\Directory\Model\ResourceModel\Country\Collection;
|
|
use Magento\Directory\Model\ResourceModel\Region\CollectionFactory;
|
|
use Magento\Framework\App\Cache\Type\Config;
|
|
use Magento\Framework\App\Config\ScopeConfigInterface;
|
|
use Magento\Framework\App\Helper\AbstractHelper;
|
|
use Magento\Framework\App\Helper\Context;
|
|
use Magento\Framework\Json\Helper\Data as JsonData;
|
|
use Magento\Framework\ObjectManager\ResetAfterRequestInterface;
|
|
use Magento\Store\Model\ScopeInterface;
|
|
use Magento\Store\Model\StoreManagerInterface;
|
|
|
|
/**
|
|
* Directory data helper
|
|
*
|
|
* @api
|
|
* @since 100.0.2
|
|
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
|
|
*/
|
|
class Data extends AbstractHelper implements ResetAfterRequestInterface
|
|
{
|
|
private const STORE_ID = 'store_id';
|
|
|
|
/**
|
|
* Config value that lists ISO2 country codes which have optional Zip/Postal pre-configured
|
|
*/
|
|
public const OPTIONAL_ZIP_COUNTRIES_CONFIG_PATH = 'general/country/optional_zip_countries';
|
|
|
|
/**
|
|
* Path to config value, which lists countries, for which state is required.
|
|
*/
|
|
public const XML_PATH_STATES_REQUIRED = 'general/region/state_required';
|
|
|
|
/**
|
|
* Path to config value, which detects whether or not display the state for the country, if it is not required
|
|
*/
|
|
public const XML_PATH_DISPLAY_ALL_STATES = 'general/region/display_all';
|
|
|
|
/**#@+
|
|
* Path to config value, which is default country
|
|
*/
|
|
public const XML_PATH_DEFAULT_COUNTRY = 'general/country/default';
|
|
public const XML_PATH_DEFAULT_LOCALE = 'general/locale/code';
|
|
public const XML_PATH_DEFAULT_TIMEZONE = 'general/locale/timezone';
|
|
/**#@-*/
|
|
|
|
/**
|
|
* Path to config value that contains codes of the most used countries.
|
|
* Such countries can be shown on the top of the country list.
|
|
*/
|
|
public const XML_PATH_TOP_COUNTRIES = 'general/country/destinations';
|
|
|
|
/**
|
|
* Path to config value that contains weight unit
|
|
*/
|
|
public const XML_PATH_WEIGHT_UNIT = 'general/locale/weight_unit';
|
|
|
|
/**
|
|
* @var Collection
|
|
*/
|
|
protected $_countryCollection;
|
|
|
|
/**
|
|
* @var \Magento\Directory\Model\ResourceModel\Region\Collection
|
|
*/
|
|
protected $_regionCollection;
|
|
|
|
/**
|
|
* @var string
|
|
*/
|
|
protected $_regionJson;
|
|
|
|
/**
|
|
* @var array
|
|
*/
|
|
protected $_currencyCache = [];
|
|
|
|
/**
|
|
* @var array
|
|
*/
|
|
protected $_optZipCountries = null;
|
|
|
|
/**
|
|
* @var Config
|
|
*/
|
|
protected $_configCacheType;
|
|
|
|
/**
|
|
* @var CollectionFactory
|
|
*/
|
|
protected $_regCollectionFactory;
|
|
|
|
/**
|
|
* @var JsonData
|
|
*/
|
|
protected $jsonHelper;
|
|
|
|
/**
|
|
* @var StoreManagerInterface
|
|
*/
|
|
protected $_storeManager;
|
|
|
|
/**
|
|
* @var CurrencyFactory
|
|
*/
|
|
protected $_currencyFactory;
|
|
|
|
/**
|
|
* Data constructor.
|
|
*
|
|
* @param Context $context
|
|
* @param Config $configCacheType
|
|
* @param Collection $countryCollection
|
|
* @param CollectionFactory $regCollectionFactory
|
|
* @param JsonData $jsonHelper
|
|
* @param StoreManagerInterface $storeManager
|
|
* @param CurrencyFactory $currencyFactory
|
|
*/
|
|
public function __construct(
|
|
Context $context,
|
|
Config $configCacheType,
|
|
Collection $countryCollection,
|
|
CollectionFactory $regCollectionFactory,
|
|
JsonData $jsonHelper,
|
|
StoreManagerInterface $storeManager,
|
|
CurrencyFactory $currencyFactory
|
|
) {
|
|
parent::__construct($context);
|
|
$this->_configCacheType = $configCacheType;
|
|
$this->_countryCollection = $countryCollection;
|
|
$this->_regCollectionFactory = $regCollectionFactory;
|
|
$this->jsonHelper = $jsonHelper;
|
|
$this->_storeManager = $storeManager;
|
|
$this->_currencyFactory = $currencyFactory;
|
|
}
|
|
|
|
/**
|
|
* Retrieve region collection
|
|
*
|
|
* @return \Magento\Directory\Model\ResourceModel\Region\Collection
|
|
*/
|
|
public function getRegionCollection()
|
|
{
|
|
if (!$this->_regionCollection) {
|
|
$this->_regionCollection = $this->_regCollectionFactory->create();
|
|
// phpstan:ignore
|
|
$this->_regionCollection->addCountryFilter($this->getAddress()->getCountryId())->load();
|
|
}
|
|
return $this->_regionCollection;
|
|
}
|
|
|
|
/**
|
|
* Retrieve country collection
|
|
*
|
|
* @param null|int|string|\Magento\Store\Model\Store $store
|
|
* @return Collection
|
|
*/
|
|
public function getCountryCollection($store = null)
|
|
{
|
|
if (!$this->_countryCollection->isLoaded()) {
|
|
$this->_countryCollection->loadByStore($store);
|
|
}
|
|
return $this->_countryCollection;
|
|
}
|
|
|
|
/**
|
|
* Retrieve regions data json
|
|
*
|
|
* @return string
|
|
* @throws \Magento\Framework\Exception\NoSuchEntityException
|
|
*/
|
|
public function getRegionJson()
|
|
{
|
|
\Magento\Framework\Profiler::start('TEST: ' . __METHOD__, ['group' => 'TEST', 'method' => __METHOD__]);
|
|
if (!$this->_regionJson) {
|
|
$scope = $this->getCurrentScope();
|
|
$scopeKey = $scope['value'] ? '_' . implode('_', $scope) : null;
|
|
$cacheKey = 'DIRECTORY_REGIONS_JSON_STORE' . $scopeKey;
|
|
$json = $this->_configCacheType->load($cacheKey);
|
|
if (empty($json)) {
|
|
$regions = $this->getRegionData();
|
|
$json = $this->jsonHelper->jsonEncode($regions);
|
|
if ($json === false) {
|
|
$json = 'false';
|
|
}
|
|
$this->_configCacheType->save($json, $cacheKey);
|
|
}
|
|
$this->_regionJson = $json;
|
|
}
|
|
|
|
\Magento\Framework\Profiler::stop('TEST: ' . __METHOD__);
|
|
return $this->_regionJson;
|
|
}
|
|
|
|
/**
|
|
* Convert currency
|
|
*
|
|
* @param float $amount
|
|
* @param string $from
|
|
* @param string $to
|
|
*
|
|
* @return float
|
|
* @SuppressWarnings(PHPMD.ShortVariable)
|
|
* @throws \Magento\Framework\Exception\NoSuchEntityException
|
|
*/
|
|
public function currencyConvert($amount, $from, $to = null)
|
|
{
|
|
if (empty($this->_currencyCache[$from])) {
|
|
$this->_currencyCache[$from] = $this->_currencyFactory->create()->load($from);
|
|
}
|
|
if ($to === null) {
|
|
$to = $this->_storeManager->getStore()->getCurrentCurrencyCode();
|
|
}
|
|
$converted = $this->_currencyCache[$from]->convert($amount, $to);
|
|
return $converted;
|
|
}
|
|
|
|
/**
|
|
* Return ISO2 country codes, which have optional Zip/Postal pre-configured
|
|
*
|
|
* @param bool $asJson
|
|
* @return array|string
|
|
*/
|
|
public function getCountriesWithOptionalZip($asJson = false)
|
|
{
|
|
if (null === $this->_optZipCountries) {
|
|
$value = trim(
|
|
(string)$this->scopeConfig->getValue(
|
|
self::OPTIONAL_ZIP_COUNTRIES_CONFIG_PATH,
|
|
ScopeInterface::SCOPE_STORE
|
|
)
|
|
);
|
|
$this->_optZipCountries = preg_split('/\,/', $value, 0, PREG_SPLIT_NO_EMPTY);
|
|
}
|
|
if ($asJson) {
|
|
return $this->jsonHelper->jsonEncode($this->_optZipCountries);
|
|
}
|
|
return $this->_optZipCountries;
|
|
}
|
|
|
|
/**
|
|
* Check whether zip code is optional for specified country code
|
|
*
|
|
* @param string $countryCode
|
|
* @return boolean
|
|
*/
|
|
public function isZipCodeOptional($countryCode)
|
|
{
|
|
$this->getCountriesWithOptionalZip();
|
|
return in_array($countryCode, $this->_optZipCountries);
|
|
}
|
|
|
|
/**
|
|
* Returns the list of countries, for which region is required
|
|
*
|
|
* @param boolean $asJson
|
|
* @return array|string
|
|
*/
|
|
public function getCountriesWithStatesRequired($asJson = false)
|
|
{
|
|
$value = trim(
|
|
(string)$this->scopeConfig->getValue(
|
|
self::XML_PATH_STATES_REQUIRED,
|
|
ScopeInterface::SCOPE_STORE
|
|
)
|
|
);
|
|
$countryList = preg_split('/\,/', $value, 0, PREG_SPLIT_NO_EMPTY);
|
|
if ($asJson) {
|
|
return $this->jsonHelper->jsonEncode($countryList);
|
|
}
|
|
return $countryList;
|
|
}
|
|
|
|
/**
|
|
* Return, whether non-required state should be shown
|
|
*
|
|
* @return bool
|
|
*/
|
|
public function isShowNonRequiredState()
|
|
{
|
|
return $this->scopeConfig->isSetFlag(
|
|
self::XML_PATH_DISPLAY_ALL_STATES,
|
|
ScopeInterface::SCOPE_STORE
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Returns flag, which indicates whether region is required for specified country
|
|
*
|
|
* @param string $countryId
|
|
* @return bool
|
|
*/
|
|
public function isRegionRequired($countryId)
|
|
{
|
|
$countyList = $this->getCountriesWithStatesRequired();
|
|
if (!is_array($countyList)) {
|
|
return false;
|
|
}
|
|
return in_array($countryId, $countyList);
|
|
}
|
|
|
|
/**
|
|
* Retrieve application base currency code
|
|
*
|
|
* @return string
|
|
*/
|
|
public function getBaseCurrencyCode()
|
|
{
|
|
return $this->scopeConfig->getValue(
|
|
Currency::XML_PATH_CURRENCY_BASE,
|
|
'default'
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Return default country code
|
|
*
|
|
* @param \Magento\Store\Model\Store|string|int $store
|
|
* @return string
|
|
*/
|
|
public function getDefaultCountry($store = null)
|
|
{
|
|
return $this->scopeConfig->getValue(
|
|
self::XML_PATH_DEFAULT_COUNTRY,
|
|
ScopeInterface::SCOPE_STORE,
|
|
$store
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Retrieve regions data
|
|
*
|
|
* @return array
|
|
*/
|
|
public function getRegionData()
|
|
{
|
|
$scope = $this->getCurrentScope();
|
|
$allowedCountries = $this->scopeConfig->getValue(
|
|
AllowedCountries::ALLOWED_COUNTRIES_PATH,
|
|
$scope['type'],
|
|
$scope['value']
|
|
) ?? '';
|
|
$countryIds = explode(',', $allowedCountries);
|
|
$collection = $this->_regCollectionFactory->create();
|
|
$collection->addCountryFilter($countryIds)->load();
|
|
$regions = [
|
|
'config' => [
|
|
'show_all_regions' => $this->isShowNonRequiredState(),
|
|
'regions_required' => $this->getCountriesWithStatesRequired(),
|
|
],
|
|
];
|
|
foreach ($collection as $region) {
|
|
/** @var $region \Magento\Directory\Model\Region */
|
|
if (!$region->getRegionId()) {
|
|
continue;
|
|
}
|
|
$regions[$region->getCountryId()][$region->getRegionId()] = [
|
|
'code' => $region->getCode(),
|
|
'name' => (string)__($region->getName()),
|
|
];
|
|
}
|
|
return $regions;
|
|
}
|
|
|
|
/**
|
|
* Retrieve list of codes of the most used countries
|
|
*
|
|
* @return array
|
|
*/
|
|
public function getTopCountryCodes()
|
|
{
|
|
$configValue = (string)$this->scopeConfig->getValue(
|
|
self::XML_PATH_TOP_COUNTRIES,
|
|
ScopeInterface::SCOPE_STORE
|
|
);
|
|
return !empty($configValue) ? explode(',', $configValue) : [];
|
|
}
|
|
|
|
/**
|
|
* Retrieve weight unit
|
|
*
|
|
* @return string
|
|
*/
|
|
public function getWeightUnit()
|
|
{
|
|
return $this->scopeConfig->getValue(self::XML_PATH_WEIGHT_UNIT, ScopeInterface::SCOPE_STORE);
|
|
}
|
|
|
|
/**
|
|
* Get current scope from request
|
|
*
|
|
* @return array
|
|
* @throws \Magento\Framework\Exception\NoSuchEntityException
|
|
*/
|
|
private function getCurrentScope(): array
|
|
{
|
|
$scope = [
|
|
'type' => ScopeConfigInterface::SCOPE_TYPE_DEFAULT,
|
|
'value' => null,
|
|
];
|
|
$request = $this->_getRequest();
|
|
if ($request->getParam(ScopeInterface::SCOPE_WEBSITE)) {
|
|
$scope = [
|
|
'type' => ScopeInterface::SCOPE_WEBSITE,
|
|
'value' => $request->getParam(ScopeInterface::SCOPE_WEBSITE),
|
|
];
|
|
} elseif ($request->getParam(ScopeInterface::SCOPE_STORE)) {
|
|
$scope = [
|
|
'type' => ScopeInterface::SCOPE_STORE,
|
|
'value' => $request->getParam(ScopeInterface::SCOPE_STORE),
|
|
];
|
|
} elseif ($request->getParam(self::STORE_ID)) {
|
|
$scope = [
|
|
'type' => ScopeInterface::SCOPE_STORE,
|
|
'value' => $request->getParam(self::STORE_ID),
|
|
];
|
|
} else {
|
|
$storeId = $this->_storeManager->getStore()->getId() ?? null;
|
|
if ($storeId) {
|
|
$scope = [
|
|
'type' => ScopeInterface::SCOPE_STORE,
|
|
'value' => $storeId,
|
|
];
|
|
}
|
|
}
|
|
|
|
return $scope;
|
|
}
|
|
|
|
/**
|
|
* @inheritDoc
|
|
*/
|
|
public function _resetState(): void
|
|
{
|
|
$this->_regionJson = null;
|
|
$this->_currencyCache = [];
|
|
}
|
|
}
|