PageRenderTime 44ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 1ms

/lib/internal/Magento/Framework/Translate.php

https://gitlab.com/crazybutterfly815/magento2
PHP | 490 lines | 240 code | 48 blank | 202 comment | 23 complexity | d8c888b63717e43441e5fb22b471d557 MD5 | raw file
  1. <?php
  2. /**
  3. * Copyright © 2016 Magento. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Framework;
  7. use Magento\Framework\App\Filesystem\DirectoryList;
  8. /**
  9. * Translate library
  10. *
  11. * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  12. * @SuppressWarnings(PHPMD.TooManyFields)
  13. */
  14. class Translate implements \Magento\Framework\TranslateInterface
  15. {
  16. /**
  17. * Locale code
  18. *
  19. * @var string
  20. */
  21. protected $_localeCode;
  22. /**
  23. * Translator configuration array
  24. *
  25. * @var array
  26. */
  27. protected $_config;
  28. /**
  29. * Cache identifier
  30. *
  31. * @var string
  32. */
  33. protected $_cacheId;
  34. /**
  35. * Translation data
  36. *
  37. * @var []
  38. */
  39. protected $_data = [];
  40. /**
  41. * @var \Magento\Framework\View\DesignInterface
  42. */
  43. protected $_viewDesign;
  44. /**
  45. * @var \Magento\Framework\Cache\FrontendInterface $cache
  46. */
  47. protected $_cache;
  48. /**
  49. * @var \Magento\Framework\View\FileSystem
  50. */
  51. protected $_viewFileSystem;
  52. /**
  53. * @var \Magento\Framework\Module\ModuleList
  54. */
  55. protected $_moduleList;
  56. /**
  57. * @var \Magento\Framework\Module\Dir\Reader
  58. */
  59. protected $_modulesReader;
  60. /**
  61. * @var \Magento\Framework\App\ScopeResolverInterface
  62. */
  63. protected $_scopeResolver;
  64. /**
  65. * @var \Magento\Framework\Translate\ResourceInterface
  66. */
  67. protected $_translateResource;
  68. /**
  69. * @var \Magento\Framework\Locale\ResolverInterface
  70. */
  71. protected $_locale;
  72. /**
  73. * @var \Magento\Framework\App\State
  74. */
  75. protected $_appState;
  76. /**
  77. * @var \Magento\Framework\Filesystem\Directory\Read
  78. */
  79. protected $directory;
  80. /**
  81. * @var \Magento\Framework\App\RequestInterface
  82. */
  83. protected $request;
  84. /**
  85. * @var \Magento\Framework\File\Csv
  86. */
  87. protected $_csvParser;
  88. /**
  89. * @var \Magento\Framework\App\Language\Dictionary
  90. */
  91. protected $packDictionary;
  92. /**
  93. * @param \Magento\Framework\View\DesignInterface $viewDesign
  94. * @param \Magento\Framework\Cache\FrontendInterface $cache
  95. * @param \Magento\Framework\View\FileSystem $viewFileSystem
  96. * @param \Magento\Framework\Module\ModuleList $moduleList
  97. * @param \Magento\Framework\Module\Dir\Reader $modulesReader
  98. * @param \Magento\Framework\App\ScopeResolverInterface $scopeResolver
  99. * @param \Magento\Framework\Translate\ResourceInterface $translate
  100. * @param \Magento\Framework\Locale\ResolverInterface $locale
  101. * @param \Magento\Framework\App\State $appState
  102. * @param \Magento\Framework\Filesystem $filesystem
  103. * @param \Magento\Framework\App\RequestInterface $request
  104. * @param \Magento\Framework\File\Csv $csvParser
  105. * @param \Magento\Framework\App\Language\Dictionary $packDictionary
  106. *
  107. * @SuppressWarnings(PHPMD.ExcessiveParameterList)
  108. */
  109. public function __construct(
  110. \Magento\Framework\View\DesignInterface $viewDesign,
  111. \Magento\Framework\Cache\FrontendInterface $cache,
  112. \Magento\Framework\View\FileSystem $viewFileSystem,
  113. \Magento\Framework\Module\ModuleList $moduleList,
  114. \Magento\Framework\Module\Dir\Reader $modulesReader,
  115. \Magento\Framework\App\ScopeResolverInterface $scopeResolver,
  116. \Magento\Framework\Translate\ResourceInterface $translate,
  117. \Magento\Framework\Locale\ResolverInterface $locale,
  118. \Magento\Framework\App\State $appState,
  119. \Magento\Framework\Filesystem $filesystem,
  120. \Magento\Framework\App\RequestInterface $request,
  121. \Magento\Framework\File\Csv $csvParser,
  122. \Magento\Framework\App\Language\Dictionary $packDictionary
  123. ) {
  124. $this->_viewDesign = $viewDesign;
  125. $this->_cache = $cache;
  126. $this->_viewFileSystem = $viewFileSystem;
  127. $this->_moduleList = $moduleList;
  128. $this->_modulesReader = $modulesReader;
  129. $this->_scopeResolver = $scopeResolver;
  130. $this->_translateResource = $translate;
  131. $this->_locale = $locale;
  132. $this->_appState = $appState;
  133. $this->request = $request;
  134. $this->directory = $filesystem->getDirectoryRead(DirectoryList::ROOT);
  135. $this->_csvParser = $csvParser;
  136. $this->packDictionary = $packDictionary;
  137. }
  138. /**
  139. * Initialize translation data
  140. *
  141. * @param string|null $area
  142. * @param bool $forceReload
  143. * @return $this
  144. */
  145. public function loadData($area = null, $forceReload = false)
  146. {
  147. $this->setConfig(
  148. ['area' => isset($area) ? $area : $this->_appState->getAreaCode()]
  149. );
  150. if (!$forceReload) {
  151. $this->_data = $this->_loadCache();
  152. if ($this->_data !== false) {
  153. return $this;
  154. }
  155. }
  156. $this->_data = [];
  157. $this->_loadModuleTranslation();
  158. $this->_loadThemeTranslation();
  159. $this->_loadPackTranslation();
  160. $this->_loadDbTranslation();
  161. $this->_saveCache();
  162. return $this;
  163. }
  164. /**
  165. * Initialize configuration
  166. *
  167. * @param array $config
  168. * @return $this
  169. */
  170. protected function setConfig($config)
  171. {
  172. $this->_config = $config;
  173. if (!isset($this->_config['locale'])) {
  174. $this->_config['locale'] = $this->getLocale();
  175. }
  176. if (!isset($this->_config['scope'])) {
  177. $this->_config['scope'] = $this->getScope();
  178. }
  179. if (!isset($this->_config['theme'])) {
  180. $this->_config['theme'] = $this->_viewDesign->getDesignTheme()->getId();
  181. }
  182. if (!isset($this->_config['module'])) {
  183. $this->_config['module'] = $this->getControllerModuleName();
  184. }
  185. return $this;
  186. }
  187. /**
  188. * Retrieve scope code
  189. *
  190. * @return string
  191. */
  192. protected function getScope()
  193. {
  194. $scope = ($this->getConfig('area') == 'adminhtml') ? 'admin' : null;
  195. return $this->_scopeResolver->getScope($scope)->getCode();
  196. }
  197. /**
  198. * Retrieve config value by key
  199. *
  200. * @param string $key
  201. * @return mixed
  202. */
  203. protected function getConfig($key)
  204. {
  205. if (isset($this->_config[$key])) {
  206. return $this->_config[$key];
  207. }
  208. return null;
  209. }
  210. /**
  211. * Retrieve name of the current module
  212. * @return mixed
  213. */
  214. protected function getControllerModuleName()
  215. {
  216. return $this->request->getControllerModule();
  217. }
  218. /**
  219. * Load data from module translation files
  220. *
  221. * @return $this
  222. */
  223. protected function _loadModuleTranslation()
  224. {
  225. $currentModule = $this->getControllerModuleName();
  226. $allModulesExceptCurrent = array_diff($this->_moduleList->getNames(), [$currentModule]);
  227. $this->loadModuleTranslationByModulesList($allModulesExceptCurrent);
  228. $this->loadModuleTranslationByModulesList([$currentModule]);
  229. return $this;
  230. }
  231. /**
  232. * Load data from module translation files by list of modules
  233. *
  234. * @param array $modules
  235. * @return $this
  236. */
  237. protected function loadModuleTranslationByModulesList(array $modules)
  238. {
  239. foreach ($modules as $module) {
  240. $moduleFilePath = $this->_getModuleTranslationFile($module, $this->getLocale());
  241. $this->_addData($this->_getFileData($moduleFilePath));
  242. }
  243. return $this;
  244. }
  245. /**
  246. * Adding translation data
  247. *
  248. * @param array $data
  249. * @return $this
  250. */
  251. protected function _addData($data)
  252. {
  253. foreach ($data as $key => $value) {
  254. if ($key === $value) {
  255. continue;
  256. }
  257. $key = str_replace('""', '"', $key);
  258. $value = str_replace('""', '"', $value);
  259. $this->_data[$key] = $value;
  260. }
  261. return $this;
  262. }
  263. /**
  264. * Load current theme translation
  265. *
  266. * @return $this
  267. */
  268. protected function _loadThemeTranslation()
  269. {
  270. if (!$this->_config['theme']) {
  271. return $this;
  272. }
  273. $file = $this->_getThemeTranslationFile($this->getLocale());
  274. if ($file) {
  275. $this->_addData($this->_getFileData($file));
  276. }
  277. return $this;
  278. }
  279. /**
  280. * Load translation dictionary from language packages
  281. *
  282. * @return void
  283. */
  284. protected function _loadPackTranslation()
  285. {
  286. $data = $this->packDictionary->getDictionary($this->getLocale());
  287. $this->_addData($data);
  288. }
  289. /**
  290. * Loading current translation from DB
  291. *
  292. * @return $this
  293. */
  294. protected function _loadDbTranslation()
  295. {
  296. $data = $this->_translateResource->getTranslationArray(null, $this->getLocale());
  297. $this->_addData(array_map("htmlspecialchars_decode", $data));
  298. return $this;
  299. }
  300. /**
  301. * Retrieve translation file for module
  302. *
  303. * @param string $moduleName
  304. * @param string $locale
  305. * @return string
  306. */
  307. protected function _getModuleTranslationFile($moduleName, $locale)
  308. {
  309. $file = $this->_modulesReader->getModuleDir(Module\Dir::MODULE_I18N_DIR, $moduleName);
  310. $file .= '/' . $locale . '.csv';
  311. return $file;
  312. }
  313. /**
  314. * Retrieve translation file for theme
  315. *
  316. * @param string $locale
  317. * @return string
  318. */
  319. protected function _getThemeTranslationFile($locale)
  320. {
  321. return $this->_viewFileSystem->getLocaleFileName(
  322. 'i18n' . '/' . $locale . '.csv',
  323. ['area' => $this->getConfig('area')]
  324. );
  325. }
  326. /**
  327. * Retrieve data from file
  328. *
  329. * @param string $file
  330. * @return array
  331. */
  332. protected function _getFileData($file)
  333. {
  334. $data = [];
  335. if ($this->directory->isExist($this->directory->getRelativePath($file))) {
  336. $this->_csvParser->setDelimiter(',');
  337. $data = $this->_csvParser->getDataPairs($file);
  338. }
  339. return $data;
  340. }
  341. /**
  342. * Retrieve translation data
  343. *
  344. * @return array
  345. */
  346. public function getData()
  347. {
  348. if ($this->_data === null) {
  349. return [];
  350. }
  351. return $this->_data;
  352. }
  353. /**
  354. * Retrieve locale
  355. *
  356. * @return string
  357. */
  358. public function getLocale()
  359. {
  360. if (null === $this->_localeCode) {
  361. $this->_localeCode = $this->_locale->getLocale();
  362. }
  363. return $this->_localeCode;
  364. }
  365. /**
  366. * Set locale
  367. *
  368. * @param string $locale
  369. * @return \Magento\Framework\TranslateInterface
  370. */
  371. public function setLocale($locale)
  372. {
  373. $this->_localeCode = $locale;
  374. $this->_config['locale'] = $locale;
  375. $this->getCacheId(true);
  376. return $this;
  377. }
  378. /**
  379. * Retrieve theme code
  380. *
  381. * @return string
  382. */
  383. public function getTheme()
  384. {
  385. $theme = $this->request->getParam('theme');
  386. if (empty($theme)) {
  387. return 'theme' . $this->getConfig('theme');
  388. }
  389. return 'theme' . $theme['theme_title'];
  390. }
  391. /**
  392. * Retrieve cache identifier
  393. *
  394. * @param bool $forceReload
  395. * @return string
  396. */
  397. protected function getCacheId($forceReload = false)
  398. {
  399. if ($this->_cacheId === null || $forceReload) {
  400. $this->_cacheId = \Magento\Framework\App\Cache\Type\Translate::TYPE_IDENTIFIER;
  401. if (isset($this->_config['locale'])) {
  402. $this->_cacheId .= '_' . $this->_config['locale'];
  403. }
  404. if (isset($this->_config['area'])) {
  405. $this->_cacheId .= '_' . $this->_config['area'];
  406. }
  407. if (isset($this->_config['scope'])) {
  408. $this->_cacheId .= '_' . $this->_config['scope'];
  409. }
  410. if (isset($this->_config['theme'])) {
  411. $this->_cacheId .= '_' . $this->_config['theme'];
  412. }
  413. if (isset($this->_config['module'])) {
  414. $this->_cacheId .= '_' . $this->_config['module'];
  415. }
  416. }
  417. return $this->_cacheId;
  418. }
  419. /**
  420. * Loading data cache
  421. *
  422. * @return array|bool
  423. */
  424. protected function _loadCache()
  425. {
  426. $data = $this->_cache->load($this->getCacheId());
  427. if ($data) {
  428. $data = unserialize($data);
  429. }
  430. return $data;
  431. }
  432. /**
  433. * Saving data cache
  434. *
  435. * @return $this
  436. */
  437. protected function _saveCache()
  438. {
  439. $this->_cache->save(serialize($this->getData()), $this->getCacheId(true), [], false);
  440. return $this;
  441. }
  442. }