Currencysymbol.php 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\CurrencySymbol\Model\System;
  7. use Magento\Framework\App\ObjectManager;
  8. use Magento\Framework\Locale\Bundle\CurrencyBundle;
  9. use Magento\Framework\Serialize\Serializer\Json;
  10. /**
  11. * Custom currency symbol model
  12. *
  13. * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  14. *
  15. * @api
  16. * @since 100.0.2
  17. */
  18. class Currencysymbol
  19. {
  20. /**
  21. * Custom currency symbol properties
  22. *
  23. * @var array
  24. */
  25. protected $_symbolsData = [];
  26. /**
  27. * Store id
  28. *
  29. * @var string|null
  30. */
  31. protected $_storeId;
  32. /**
  33. * Website id
  34. *
  35. * @var string|null
  36. */
  37. protected $_websiteId;
  38. /**
  39. * Cache types which should be invalidated
  40. *
  41. * @var array
  42. */
  43. protected $_cacheTypes = [
  44. \Magento\Framework\App\Cache\Type\Config::TYPE_IDENTIFIER,
  45. \Magento\Framework\App\Cache\Type\Block::TYPE_IDENTIFIER,
  46. \Magento\Framework\App\Cache\Type\Layout::TYPE_IDENTIFIER,
  47. \Magento\PageCache\Model\Cache\Type::TYPE_IDENTIFIER,
  48. ];
  49. /**
  50. * Config path to custom currency symbol value
  51. */
  52. const XML_PATH_CUSTOM_CURRENCY_SYMBOL = 'currency/options/customsymbol';
  53. const XML_PATH_ALLOWED_CURRENCIES = \Magento\Directory\Model\Currency::XML_PATH_CURRENCY_ALLOW;
  54. /*
  55. * Separator used in config in allowed currencies list
  56. */
  57. const ALLOWED_CURRENCIES_CONFIG_SEPARATOR = ',';
  58. /**
  59. * Config currency section
  60. */
  61. const CONFIG_SECTION = 'currency';
  62. /**
  63. * Core event manager proxy
  64. *
  65. * @var \Magento\Framework\Event\ManagerInterface
  66. */
  67. protected $_eventManager;
  68. /**
  69. * @var \Magento\Framework\App\Cache\TypeListInterface
  70. */
  71. protected $_cacheTypeList;
  72. /**
  73. * @var \Magento\Config\Model\Config\Factory
  74. */
  75. protected $_configFactory;
  76. /**
  77. * @var \Magento\Store\Model\System\Store
  78. */
  79. protected $_systemStore;
  80. /**
  81. * @var \Magento\Store\Model\StoreManagerInterface
  82. */
  83. protected $_storeManager;
  84. /**
  85. * @var \Magento\Framework\Locale\ResolverInterface
  86. */
  87. protected $localeResolver;
  88. /**
  89. * @var \Magento\Framework\App\Config\ReinitableConfigInterface
  90. */
  91. protected $_coreConfig;
  92. /**
  93. * Core store config
  94. *
  95. * @var \Magento\Framework\App\Config\ScopeConfigInterface
  96. */
  97. protected $_scopeConfig;
  98. /**
  99. * @var Json
  100. */
  101. private $serializer;
  102. /**
  103. * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
  104. * @param \Magento\Framework\App\Config\ReinitableConfigInterface $coreConfig
  105. * @param \Magento\Config\Model\Config\Factory $configFactory
  106. * @param \Magento\Framework\App\Cache\TypeListInterface $cacheTypeList
  107. * @param \Magento\Store\Model\StoreManagerInterface $storeManager
  108. * @param \Magento\Framework\Locale\ResolverInterface $localeResolver
  109. * @param \Magento\Store\Model\System\Store $systemStore
  110. * @param \Magento\Framework\Event\ManagerInterface $eventManager
  111. * @param Json|null $serializer
  112. */
  113. public function __construct(
  114. \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
  115. \Magento\Framework\App\Config\ReinitableConfigInterface $coreConfig,
  116. \Magento\Config\Model\Config\Factory $configFactory,
  117. \Magento\Framework\App\Cache\TypeListInterface $cacheTypeList,
  118. \Magento\Store\Model\StoreManagerInterface $storeManager,
  119. \Magento\Framework\Locale\ResolverInterface $localeResolver,
  120. \Magento\Store\Model\System\Store $systemStore,
  121. \Magento\Framework\Event\ManagerInterface $eventManager,
  122. Json $serializer = null
  123. ) {
  124. $this->_coreConfig = $coreConfig;
  125. $this->_configFactory = $configFactory;
  126. $this->_cacheTypeList = $cacheTypeList;
  127. $this->_storeManager = $storeManager;
  128. $this->localeResolver = $localeResolver;
  129. $this->_systemStore = $systemStore;
  130. $this->_eventManager = $eventManager;
  131. $this->_scopeConfig = $scopeConfig;
  132. $this->serializer = $serializer ?: ObjectManager::getInstance()->get(Json::class);
  133. }
  134. /**
  135. * Return currency symbol properties array based on config values
  136. *
  137. * @return array
  138. */
  139. public function getCurrencySymbolsData()
  140. {
  141. if ($this->_symbolsData) {
  142. return $this->_symbolsData;
  143. }
  144. $this->_symbolsData = [];
  145. $currentSymbols = $this->_unserializeStoreConfig(self::XML_PATH_CUSTOM_CURRENCY_SYMBOL);
  146. foreach ($this->getAllowedCurrencies() as $code) {
  147. $currencies = (new CurrencyBundle())->get($this->localeResolver->getLocale())['Currencies'];
  148. $symbol = $currencies[$code][0] ?: $code;
  149. $name = $currencies[$code][1] ?: $code;
  150. $this->_symbolsData[$code] = ['parentSymbol' => $symbol, 'displayName' => $name];
  151. if (isset($currentSymbols[$code]) && !empty($currentSymbols[$code])) {
  152. $this->_symbolsData[$code]['displaySymbol'] = $currentSymbols[$code];
  153. } else {
  154. $this->_symbolsData[$code]['displaySymbol'] = $this->_symbolsData[$code]['parentSymbol'];
  155. }
  156. $this->_symbolsData[$code]['inherited'] =
  157. ($this->_symbolsData[$code]['parentSymbol'] == $this->_symbolsData[$code]['displaySymbol']);
  158. }
  159. return $this->_symbolsData;
  160. }
  161. /**
  162. * Save currency symbol to config
  163. *
  164. * @param array $symbols
  165. * @return $this
  166. */
  167. public function setCurrencySymbolsData($symbols = [])
  168. {
  169. if (!$this->_storeManager->isSingleStoreMode()) {
  170. foreach ($this->getCurrencySymbolsData() as $code => $values) {
  171. if (isset($symbols[$code]) && ($symbols[$code] == $values['parentSymbol'] || empty($symbols[$code]))) {
  172. unset($symbols[$code]);
  173. }
  174. }
  175. }
  176. $value = [];
  177. if ($symbols) {
  178. $value['options']['fields']['customsymbol']['value'] = $this->serializer->serialize($symbols);
  179. } else {
  180. $value['options']['fields']['customsymbol']['inherit'] = 1;
  181. }
  182. $this->_configFactory->create()
  183. ->setSection(self::CONFIG_SECTION)
  184. ->setWebsite(null)
  185. ->setStore(null)
  186. ->setGroups($value)
  187. ->save();
  188. $this->_eventManager->dispatch(
  189. 'admin_system_config_changed_section_currency_before_reinit',
  190. ['website' => $this->_websiteId, 'store' => $this->_storeId]
  191. );
  192. // reinit configuration
  193. $this->_coreConfig->reinit();
  194. $this->clearCache();
  195. //Reset symbols cache since new data is added
  196. $this->_symbolsData = [];
  197. $this->_eventManager->dispatch(
  198. 'admin_system_config_changed_section_currency',
  199. ['website' => $this->_websiteId, 'store' => $this->_storeId]
  200. );
  201. return $this;
  202. }
  203. /**
  204. * Return custom currency symbol by currency code
  205. *
  206. * @param string $code
  207. * @return string|false
  208. */
  209. public function getCurrencySymbol($code)
  210. {
  211. $customSymbols = $this->_unserializeStoreConfig(self::XML_PATH_CUSTOM_CURRENCY_SYMBOL);
  212. if (array_key_exists($code, $customSymbols)) {
  213. return $customSymbols[$code];
  214. }
  215. return false;
  216. }
  217. /**
  218. * Clear translate cache
  219. *
  220. * @return $this
  221. */
  222. protected function clearCache()
  223. {
  224. // clear cache for frontend
  225. foreach ($this->_cacheTypes as $cacheType) {
  226. $this->_cacheTypeList->invalidate($cacheType);
  227. }
  228. return $this;
  229. }
  230. /**
  231. * Unserialize data from Store Config.
  232. *
  233. * @param string $configPath
  234. * @param int $storeId
  235. * @return array
  236. */
  237. protected function _unserializeStoreConfig($configPath, $storeId = null)
  238. {
  239. $result = [];
  240. $configData = (string)$this->_scopeConfig->getValue(
  241. $configPath,
  242. \Magento\Store\Model\ScopeInterface::SCOPE_STORE,
  243. $storeId
  244. );
  245. if ($configData) {
  246. $result = $this->serializer->unserialize($configData);
  247. }
  248. return is_array($result) ? $result : [];
  249. }
  250. /**
  251. * Return allowed currencies
  252. *
  253. * @return array
  254. */
  255. protected function getAllowedCurrencies()
  256. {
  257. $allowedCurrencies = explode(
  258. self::ALLOWED_CURRENCIES_CONFIG_SEPARATOR,
  259. $this->_scopeConfig->getValue(
  260. self::XML_PATH_ALLOWED_CURRENCIES,
  261. \Magento\Store\Model\ScopeInterface::SCOPE_STORE,
  262. null
  263. )
  264. );
  265. $storeModel = $this->_systemStore;
  266. /** @var \Magento\Store\Model\Website $website */
  267. foreach ($storeModel->getWebsiteCollection() as $website) {
  268. $websiteShow = false;
  269. /** @var \Magento\Store\Model\Group $group */
  270. foreach ($storeModel->getGroupCollection() as $group) {
  271. if ($group->getWebsiteId() != $website->getId()) {
  272. continue;
  273. }
  274. /** @var \Magento\Store\Model\Store $store */
  275. foreach ($storeModel->getStoreCollection() as $store) {
  276. if ($store->getGroupId() != $group->getId()) {
  277. continue;
  278. }
  279. if (!$websiteShow) {
  280. $websiteShow = true;
  281. $websiteSymbols = $website->getConfig(self::XML_PATH_ALLOWED_CURRENCIES);
  282. $allowedCurrencies = array_merge(
  283. $allowedCurrencies,
  284. explode(self::ALLOWED_CURRENCIES_CONFIG_SEPARATOR, $websiteSymbols)
  285. );
  286. }
  287. $storeSymbols = $this->_scopeConfig->getValue(
  288. self::XML_PATH_ALLOWED_CURRENCIES,
  289. \Magento\Store\Model\ScopeInterface::SCOPE_STORE,
  290. $store
  291. );
  292. $allowedCurrencies = array_merge(
  293. $allowedCurrencies,
  294. explode(self::ALLOWED_CURRENCIES_CONFIG_SEPARATOR, $storeSymbols)
  295. );
  296. }
  297. }
  298. }
  299. return array_unique($allowedCurrencies);
  300. }
  301. }