Created
March 31, 2022 14:42
-
-
Save scgoeswild/18f123dea14364164d2f623a3880744a to your computer and use it in GitHub Desktop.
Magento2 not shows currency symbol
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Copyright © Magento, Inc. All rights reserved. | |
* See COPYING.txt for license details. | |
*vendor\magento\module-directory\Model\Currency.php | |
*/ | |
namespace Magento\Directory\Model; | |
use Magento\Framework\App\ObjectManager; | |
use Magento\Framework\Exception\InputException; | |
use Magento\Directory\Model\Currency\Filter; | |
use Magento\Framework\Locale\Currency as LocaleCurrency; | |
use Magento\Framework\Locale\ResolverInterface as LocalResolverInterface; | |
use Magento\Framework\NumberFormatterFactory; | |
use Magento\Framework\Serialize\Serializer\Json; | |
/** | |
* Currency model | |
* | |
* @api | |
* | |
* @SuppressWarnings(PHPMD.CouplingBetweenObjects) | |
* @since 100.0.2 | |
*/ | |
class Currency extends \Magento\Framework\Model\AbstractModel | |
{ | |
/** | |
* CONFIG path constants | |
*/ | |
const XML_PATH_CURRENCY_ALLOW = 'currency/options/allow'; | |
const XML_PATH_CURRENCY_DEFAULT = 'currency/options/default'; | |
const XML_PATH_CURRENCY_BASE = 'currency/options/base'; | |
/** | |
* @var Filter | |
*/ | |
protected $_filter; | |
/** | |
* Currency Rates | |
* | |
* @var array | |
*/ | |
protected $_rates; | |
/** | |
* @var \Magento\Framework\Locale\FormatInterface | |
*/ | |
protected $_localeFormat; | |
/** | |
* @var \Magento\Store\Model\StoreManagerInterface | |
*/ | |
protected $_storeManager; | |
/** | |
* @var \Magento\Directory\Helper\Data | |
*/ | |
protected $_directoryHelper; | |
/** | |
* @var \Magento\Directory\Model\Currency\FilterFactory | |
*/ | |
protected $_currencyFilterFactory; | |
/** | |
* @var \Magento\Framework\Locale\CurrencyInterface | |
*/ | |
protected $_localeCurrency; | |
/** | |
* @var CurrencyConfig | |
*/ | |
private $currencyConfig; | |
/** | |
* @var LocalResolverInterface | |
*/ | |
private $localeResolver; | |
/** | |
* @var NumberFormatterFactory | |
*/ | |
private $numberFormatterFactory; | |
/** | |
* @var \Magento\Framework\NumberFormatter | |
*/ | |
private $numberFormatter; | |
/** | |
* @var array | |
*/ | |
private $numberFormatterCache; | |
/** | |
* @var Json | |
*/ | |
private $serializer; | |
/** | |
* @param \Magento\Framework\Model\Context $context | |
* @param \Magento\Framework\Registry $registry | |
* @param \Magento\Framework\Locale\FormatInterface $localeFormat | |
* @param \Magento\Store\Model\StoreManagerInterface $storeManager | |
* @param \Magento\Directory\Helper\Data $directoryHelper | |
* @param Currency\FilterFactory $currencyFilterFactory | |
* @param \Magento\Framework\Locale\CurrencyInterface $localeCurrency | |
* @param \Magento\Framework\Model\ResourceModel\AbstractResource|null $resource | |
* @param \Magento\Framework\Data\Collection\AbstractDb|null $resourceCollection | |
* @param array $data | |
* @param CurrencyConfig|null $currencyConfig | |
* @param LocalResolverInterface|null $localeResolver | |
* @param NumberFormatterFactory|null $numberFormatterFactory | |
* @param Json|null $serializer | |
* @SuppressWarnings(PHPMD.ExcessiveParameterList) | |
*/ | |
public function __construct( | |
\Magento\Framework\Model\Context $context, | |
\Magento\Framework\Registry $registry, | |
\Magento\Framework\Locale\FormatInterface $localeFormat, | |
\Magento\Store\Model\StoreManagerInterface $storeManager, | |
\Magento\Directory\Helper\Data $directoryHelper, | |
\Magento\Directory\Model\Currency\FilterFactory $currencyFilterFactory, | |
\Magento\Framework\Locale\CurrencyInterface $localeCurrency, | |
\Magento\Framework\Model\ResourceModel\AbstractResource $resource = null, | |
\Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null, | |
array $data = [], | |
CurrencyConfig $currencyConfig = null, | |
LocalResolverInterface $localeResolver = null, | |
\Magento\Framework\NumberFormatterFactory $numberFormatterFactory = null, | |
Json $serializer = null | |
) { | |
parent::__construct( | |
$context, | |
$registry, | |
$resource, | |
$resourceCollection, | |
$data | |
); | |
$this->_localeFormat = $localeFormat; | |
$this->_storeManager = $storeManager; | |
$this->_directoryHelper = $directoryHelper; | |
$this->_currencyFilterFactory = $currencyFilterFactory; | |
$this->_localeCurrency = $localeCurrency; | |
$this->currencyConfig = $currencyConfig ?: ObjectManager::getInstance()->get(CurrencyConfig::class); | |
$this->localeResolver = $localeResolver ?: ObjectManager::getInstance()->get(LocalResolverInterface::class); | |
$this->numberFormatterFactory = $numberFormatterFactory ?: ObjectManager::getInstance()->get(NumberFormatterFactory::class); | |
$this->serializer = $serializer ?: ObjectManager::getInstance()->get(Json::class); | |
} | |
/** | |
* @return void | |
*/ | |
protected function _construct() | |
{ | |
$this->_init(\Magento\Directory\Model\ResourceModel\Currency::class); | |
} | |
/** | |
* Get currency code | |
* | |
* @return string | |
*/ | |
public function getCode() | |
{ | |
return $this->_getData('currency_code'); | |
} | |
/** | |
* Get currency code | |
* | |
* @return string | |
*/ | |
public function getCurrencyCode() | |
{ | |
return $this->_getData('currency_code'); | |
} | |
/** | |
* Currency Rates getter | |
* | |
* @return array | |
*/ | |
public function getRates() | |
{ | |
return $this->_rates; | |
} | |
/** | |
* Currency Rates setter | |
* | |
* @param array $rates Currency Rates | |
* @return $this | |
*/ | |
public function setRates(array $rates) | |
{ | |
$this->_rates = $rates; | |
return $this; | |
} | |
/** | |
* Loading currency data | |
* | |
* @param string $id | |
* @param string $field | |
* @return $this | |
* @SuppressWarnings(PHPMD.UnusedFormalParameter) | |
*/ | |
public function load($id, $field = null) | |
{ | |
$this->unsRate(); | |
$this->setData('currency_code', $id); | |
return $this; | |
} | |
/** | |
* Get currency rate (only base => allowed) | |
* | |
* @param mixed $toCurrency | |
* @return float | |
*/ | |
public function getRate($toCurrency) | |
{ | |
$code = $this->getCurrencyCodeFromToCurrency($toCurrency); | |
$rates = $this->getRates(); | |
if (!isset($rates[$code])) { | |
$rates[$code] = $this->_getResource()->getRate($this->getCode(), $toCurrency); | |
$this->setRates($rates); | |
} | |
return $rates[$code]; | |
} | |
/** | |
* Get currency rate (base=>allowed or allowed=>base) | |
* | |
* @param mixed $toCurrency | |
* @return float | |
*/ | |
public function getAnyRate($toCurrency) | |
{ | |
$code = $this->getCurrencyCodeFromToCurrency($toCurrency); | |
$rates = $this->getRates(); | |
if (!isset($rates[$code])) { | |
$rates[$code] = $this->_getResource()->getAnyRate($this->getCode(), $toCurrency); | |
$this->setRates($rates); | |
} | |
return $rates[$code]; | |
} | |
/** | |
* Convert price to currency format | |
* | |
* @param float $price | |
* @param mixed $toCurrency | |
* @return float | |
* @throws \Exception | |
*/ | |
public function convert($price, $toCurrency = null) | |
{ | |
if ($toCurrency === null) { | |
return $price; | |
} elseif ($rate = $this->getRate($toCurrency)) { | |
return (float)$price * (float)$rate; | |
} | |
throw new \Exception(__( | |
'Undefined rate from "%1-%2".', | |
$this->getCode(), | |
$this->getCurrencyCodeFromToCurrency($toCurrency) | |
)); | |
} | |
/** | |
* @param mixed $toCurrency | |
* @return string | |
* @throws \Magento\Framework\Exception\InputException | |
*/ | |
private function getCurrencyCodeFromToCurrency($toCurrency) | |
{ | |
if (is_string($toCurrency)) { | |
$code = $toCurrency; | |
} elseif ($toCurrency instanceof \Magento\Directory\Model\Currency) { | |
$code = $toCurrency->getCurrencyCode(); | |
} else { | |
throw new InputException(__('Please correct the target currency.')); | |
} | |
return $code; | |
} | |
/** | |
* Get currency filter | |
* | |
* @return Filter | |
*/ | |
public function getFilter() | |
{ | |
if (!$this->_filter) { | |
$this->_filter = $this->_currencyFilterFactory->create(['code' => $this->getCode()]); | |
} | |
return $this->_filter; | |
} | |
/** | |
* Format price to currency format | |
* | |
* @param float $price | |
* @param array $options | |
* @param bool $includeContainer | |
* @param bool $addBrackets | |
* @return string | |
*/ | |
public function format($price, $options = [], $includeContainer = true, $addBrackets = false) | |
{ | |
return $this->formatPrecision($price, 2, $options, $includeContainer, $addBrackets); | |
} | |
/** | |
* Apply currency format to number with specific rounding precision | |
* | |
* @param float $price | |
* @param int $precision | |
* @param array $options | |
* @param bool $includeContainer | |
* @param bool $addBrackets | |
* @return string | |
*/ | |
public function formatPrecision( | |
$price, | |
$precision, | |
$options = [], | |
$includeContainer = true, | |
$addBrackets = false | |
) { | |
if (!isset($options['precision'])) { | |
$options['precision'] = $precision; | |
} | |
if ($includeContainer) { | |
return '<span class="price">' . ($addBrackets ? '[' : '') . $this->formatTxt( | |
$price, | |
$options | |
) . ($addBrackets ? ']' : '') . '</span>'; | |
} | |
return $this->formatTxt($price, $options); | |
} | |
/** | |
* @param float $price | |
* @param array $options | |
* @return string | |
*/ | |
public function formatTxt($price, $options = []) | |
{ | |
if (!is_numeric($price)) { | |
$price = $this->_localeFormat->getNumber($price); | |
} | |
/** | |
* Fix problem with 12 000 000, 1 200 000 | |
* | |
* %f - the argument is treated as a float, and presented as a floating-point number (locale aware). | |
* %F - the argument is treated as a float, and presented as a floating-point number (non-locale aware). | |
*/ | |
$price = sprintf("%F", $price); | |
return $this->_localeCurrency->getCurrency($this->getCode())->toCurrency($price, $options); | |
} | |
/** | |
* Check if to use Intl.NumberFormatter to format currency. | |
* | |
* @param array $options | |
* @return bool | |
*/ | |
private function canUseNumberFormatter(array $options): bool | |
{ | |
$allowedOptions = [ | |
'precision', | |
LocaleCurrency::CURRENCY_OPTION_DISPLAY, | |
LocaleCurrency::CURRENCY_OPTION_SYMBOL | |
]; | |
if (!empty(array_diff(array_keys($options), $allowedOptions))) { | |
return false; | |
} | |
if (array_key_exists('display', $options) | |
&& $options['display'] !== \Magento\Framework\Currency::NO_SYMBOL | |
&& $options['display'] !== \Magento\Framework\Currency::USE_SYMBOL | |
) { | |
return false; | |
} | |
return true; | |
} | |
/** | |
* Format currency. | |
* | |
* @param string $price | |
* @param array $options | |
* @return string | |
*/ | |
private function formatCurrency(string $price, array $options): string | |
{ | |
$customerOptions = new \Magento\Framework\DataObject([]); | |
$this->_eventManager->dispatch( | |
'currency_display_options_forming', | |
['currency_options' => $customerOptions, 'base_code' => $this->getCode()] | |
); | |
$options += $customerOptions->toArray(); | |
$this->numberFormatter = $this->getNumberFormatter($options); | |
$formattedCurrency = $this->numberFormatter->formatCurrency( | |
$price, $this->getCode() ?? $this->numberFormatter->getTextAttribute(\NumberFormatter::CURRENCY_CODE) | |
); | |
if (array_key_exists(LocaleCurrency::CURRENCY_OPTION_SYMBOL, $options)) { | |
// remove only one non-breaking space from custom currency symbol to allow custom NBSP in currency symbol | |
$formattedCurrency = preg_replace('/ /u', '', $formattedCurrency, 1); | |
} | |
if ((array_key_exists(LocaleCurrency::CURRENCY_OPTION_DISPLAY, $options) | |
&& $options[LocaleCurrency::CURRENCY_OPTION_DISPLAY] === \Magento\Framework\Currency::NO_SYMBOL)) { | |
$formattedCurrency = str_replace(' ', '', $formattedCurrency); | |
} | |
return preg_replace('/^\s+|\s+$/u', '', $formattedCurrency); | |
} | |
/** | |
* Get NumberFormatter object from cache. | |
* | |
* @param array $options | |
* @return \Magento\Framework\NumberFormatter | |
*/ | |
private function getNumberFormatter(array $options): \Magento\Framework\NumberFormatter | |
{ | |
$key = 'currency_' . md5($this->localeResolver->getLocale() . $this->serializer->serialize($options)); | |
if (!isset($this->numberFormatterCache[$key])) { | |
$this->numberFormatter = $this->numberFormatterFactory->create( | |
['locale' => $this->localeResolver->getLocale(), 'style' => \NumberFormatter::CURRENCY] | |
); | |
$this->setOptions($options); | |
$this->numberFormatterCache[$key] = $this->numberFormatter; | |
} | |
return $this->numberFormatterCache[$key]; | |
} | |
/** | |
* Set number formatter custom options. | |
* | |
* @param array $options | |
* @return void | |
*/ | |
private function setOptions(array $options): void | |
{ | |
if (array_key_exists(LocaleCurrency::CURRENCY_OPTION_SYMBOL, $options)) { | |
$this->numberFormatter->setSymbol( | |
\NumberFormatter::CURRENCY_SYMBOL, $options[LocaleCurrency::CURRENCY_OPTION_SYMBOL] | |
); | |
} | |
if (array_key_exists(LocaleCurrency::CURRENCY_OPTION_DISPLAY, $options) | |
&& $options[LocaleCurrency::CURRENCY_OPTION_DISPLAY] === \Magento\Framework\Currency::NO_SYMBOL) { | |
$this->numberFormatter->setSymbol(\NumberFormatter::CURRENCY_SYMBOL, ''); | |
} | |
if (array_key_exists('precision', $options)) { | |
$this->numberFormatter->setAttribute(\NumberFormatter::FRACTION_DIGITS, $options['precision']); | |
} | |
} | |
/** | |
* Return currency symbol for current locale and currency code | |
* | |
* @return string | |
*/ | |
public function getCurrencySymbol() | |
{ | |
return $this->_localeCurrency->getCurrency($this->getCode())->getSymbol(); | |
} | |
/** | |
* @return string | |
*/ | |
public function getOutputFormat() | |
{ | |
$formatted = $this->formatTxt(0); | |
$number = $this->formatTxt(0, ['display' => \Magento\Framework\Currency::NO_SYMBOL]); | |
return str_replace($this->trimUnicodeDirectionMark($number), '%s', $formatted); | |
} | |
/** | |
* Retrieve allowed currencies according to config | |
* | |
* @return array | |
*/ | |
public function getConfigAllowCurrencies() | |
{ | |
$allowedCurrencies = $this->currencyConfig->getConfigCurrencies(self::XML_PATH_CURRENCY_ALLOW); | |
$appBaseCurrencyCode = $this->_directoryHelper->getBaseCurrencyCode(); | |
if (!in_array($appBaseCurrencyCode, $allowedCurrencies)) { | |
$allowedCurrencies[] = $appBaseCurrencyCode; | |
} | |
foreach ($this->_storeManager->getStores() as $store) { | |
$code = $store->getBaseCurrencyCode(); | |
if (!in_array($code, $allowedCurrencies)) { | |
$allowedCurrencies[] = $code; | |
} | |
} | |
return $allowedCurrencies; | |
} | |
/** | |
* Retrieve default currencies according to config | |
* | |
* @return array | |
*/ | |
public function getConfigDefaultCurrencies() | |
{ | |
return $this->currencyConfig->getConfigCurrencies(self::XML_PATH_CURRENCY_DEFAULT); | |
} | |
/** | |
* @return array | |
*/ | |
public function getConfigBaseCurrencies() | |
{ | |
return $this->currencyConfig->getConfigCurrencies(self::XML_PATH_CURRENCY_BASE); | |
} | |
/** | |
* Retrieve currency rates to other currencies | |
* | |
* @param string $currency | |
* @param array|null $toCurrencies | |
* @return array | |
*/ | |
public function getCurrencyRates($currency, $toCurrencies = null) | |
{ | |
if ($currency instanceof \Magento\Directory\Model\Currency) { | |
$currency = $currency->getCode(); | |
} | |
$data = $this->_getResource()->getCurrencyRates($currency, $toCurrencies); | |
return $data; | |
} | |
/** | |
* Save currency rates | |
* | |
* @param array $rates | |
* @return $this | |
*/ | |
public function saveRates($rates) | |
{ | |
$this->_getResource()->saveRates($rates); | |
return $this; | |
} | |
/** | |
* This method removes LRM and RLM marks from string | |
* | |
* @param string $string | |
* @return $this | |
*/ | |
private function trimUnicodeDirectionMark($string) | |
{ | |
if (preg_match('/^(\x{200E}|\x{200F})/u', $string, $match)) { | |
$string = preg_replace('/^'.$match[1].'/u', '', $string); | |
} | |
return $string; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment