PageRenderTime 29ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 1ms

/classes/Translate.php

https://gitlab.com/jslee1/PrestaShop
PHP | 347 lines | 269 code | 20 blank | 58 comment | 14 complexity | 0104381015f8aace4533c8e20643171d MD5 | raw file
  1. <?php
  2. /**
  3. * 2007-2015 PrestaShop
  4. *
  5. * NOTICE OF LICENSE
  6. *
  7. * This source file is subject to the Open Software License (OSL 3.0)
  8. * that is bundled with this package in the file LICENSE.txt.
  9. * It is also available through the world-wide-web at this URL:
  10. * http://opensource.org/licenses/osl-3.0.php
  11. * If you did not receive a copy of the license and are unable to
  12. * obtain it through the world-wide-web, please send an email
  13. * to license@prestashop.com so we can send you a copy immediately.
  14. *
  15. * DISCLAIMER
  16. *
  17. * Do not edit or add to this file if you wish to upgrade PrestaShop to newer
  18. * versions in the future. If you wish to customize PrestaShop for your
  19. * needs please refer to http://www.prestashop.com for more information.
  20. *
  21. * @author PrestaShop SA <contact@prestashop.com>
  22. * @copyright 2007-2015 PrestaShop SA
  23. * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
  24. * International Registered Trademark & Property of PrestaShop SA
  25. */
  26. /**
  27. * @since 1.5.0
  28. */
  29. class TranslateCore
  30. {
  31. public static function getFrontTranslation($string, $class, $addslashes = false, $htmlentities = true, $sprintf = null)
  32. {
  33. global $_LANG;
  34. $iso = Context::getContext()->language->iso_code;
  35. if (empty($iso)) {
  36. $iso = Language::getIsoById((int)Configuration::get('PS_LANG_DEFAULT'));
  37. }
  38. $string = preg_replace("/\\\*'/", "\'", $string);
  39. $key = $class.'_'.md5($string);
  40. if (isset($_LANG[$key])) {
  41. $str = $_LANG[$key];
  42. } else {
  43. $str = $string;
  44. }
  45. if ($htmlentities) {
  46. $str = htmlspecialchars($str, ENT_QUOTES, 'utf-8');
  47. }
  48. $str = str_replace('"', '&quot;', $str);
  49. if ($sprintf !== null) {
  50. $str = Translate::checkAndReplaceArgs($str, $sprintf);
  51. }
  52. return ($addslashes ? addslashes($str) : stripslashes($str));
  53. }
  54. /**
  55. * Get a translation for an admin controller
  56. *
  57. * @param $string
  58. * @param string $class
  59. * @param bool $addslashes
  60. * @param bool $htmlentities
  61. * @return string
  62. */
  63. public static function getAdminTranslation($string, $class = 'AdminTab', $addslashes = false, $htmlentities = true, $sprintf = null)
  64. {
  65. static $modules_tabs = null;
  66. // @todo remove global keyword in translations files and use static
  67. global $_LANGADM;
  68. if ($modules_tabs === null) {
  69. $modules_tabs = Tab::getModuleTabList();
  70. }
  71. if ($_LANGADM == null) {
  72. $iso = Context::getContext()->language->iso_code;
  73. if (empty($iso)) {
  74. $iso = Language::getIsoById((int)Configuration::get('PS_LANG_DEFAULT'));
  75. }
  76. if (file_exists(_PS_TRANSLATIONS_DIR_.$iso.'/admin.php')) {
  77. include_once(_PS_TRANSLATIONS_DIR_.$iso.'/admin.php');
  78. }
  79. }
  80. if (isset($modules_tabs[strtolower($class)])) {
  81. $class_name_controller = $class.'controller';
  82. // if the class is extended by a module, use modules/[module_name]/xx.php lang file
  83. if (class_exists($class_name_controller) && Module::getModuleNameFromClass($class_name_controller)) {
  84. return Translate::getModuleTranslation(Module::$classInModule[$class_name_controller], $string, $class_name_controller, $sprintf, $addslashes);
  85. }
  86. }
  87. $string = preg_replace("/\\\*'/", "\'", $string);
  88. $key = md5($string);
  89. if (isset($_LANGADM[$class.$key])) {
  90. $str = $_LANGADM[$class.$key];
  91. } else {
  92. $str = Translate::getGenericAdminTranslation($string, $key, $_LANGADM);
  93. }
  94. if ($htmlentities) {
  95. $str = htmlspecialchars($str, ENT_QUOTES, 'utf-8');
  96. }
  97. $str = str_replace('"', '&quot;', $str);
  98. if ($sprintf !== null) {
  99. $str = Translate::checkAndReplaceArgs($str, $sprintf);
  100. }
  101. return ($addslashes ? addslashes($str) : stripslashes($str));
  102. }
  103. /**
  104. * Return the translation for a string if it exists for the base AdminController or for helpers
  105. *
  106. * @param $string string to translate
  107. * @param null $key md5 key if already calculated (optional)
  108. * @param array $lang_array Global array of admin translations
  109. * @return string translation
  110. */
  111. public static function getGenericAdminTranslation($string, $key = null, &$lang_array)
  112. {
  113. $string = preg_replace("/\\\*'/", "\'", $string);
  114. if (is_null($key)) {
  115. $key = md5($string);
  116. }
  117. if (isset($lang_array['AdminController'.$key])) {
  118. $str = $lang_array['AdminController'.$key];
  119. } elseif (isset($lang_array['Helper'.$key])) {
  120. $str = $lang_array['Helper'.$key];
  121. } elseif (isset($lang_array['AdminTab'.$key])) {
  122. $str = $lang_array['AdminTab'.$key];
  123. } else {
  124. // note in 1.5, some translations has moved from AdminXX to helper/*.tpl
  125. $str = $string;
  126. }
  127. return $str;
  128. }
  129. /**
  130. * Get a translation for a module
  131. *
  132. * @param string|Module $module
  133. * @param string $string
  134. * @param string $source
  135. * @return string
  136. */
  137. public static function getModuleTranslation($module, $string, $source, $sprintf = null, $js = false)
  138. {
  139. global $_MODULES, $_MODULE, $_LANGADM;
  140. static $lang_cache = array();
  141. // $_MODULES is a cache of translations for all module.
  142. // $translations_merged is a cache of wether a specific module's translations have already been added to $_MODULES
  143. static $translations_merged = array();
  144. $name = $module instanceof Module ? $module->name : $module;
  145. $language = Context::getContext()->language;
  146. if (!isset($translations_merged[$name]) && isset(Context::getContext()->language)) {
  147. $files_by_priority = array(
  148. // Translations in theme
  149. _PS_THEME_DIR_.'modules/'.$name.'/translations/'.$language->iso_code.'.php',
  150. _PS_THEME_DIR_.'modules/'.$name.'/'.$language->iso_code.'.php',
  151. // PrestaShop 1.5 translations
  152. _PS_MODULE_DIR_.$name.'/translations/'.$language->iso_code.'.php',
  153. // PrestaShop 1.4 translations
  154. _PS_MODULE_DIR_.$name.'/'.$language->iso_code.'.php'
  155. );
  156. foreach ($files_by_priority as $file) {
  157. if (file_exists($file)) {
  158. include_once($file);
  159. $_MODULES = !empty($_MODULES) ? $_MODULES + $_MODULE : $_MODULE; //we use "+" instead of array_merge() because array merge erase existing values.
  160. $translations_merged[$name] = true;
  161. }
  162. }
  163. }
  164. $string = preg_replace("/\\\*'/", "\'", $string);
  165. $key = md5($string);
  166. $cache_key = $name.'|'.$string.'|'.$source.'|'.(int)$js;
  167. if (!isset($lang_cache[$cache_key])) {
  168. if ($_MODULES == null) {
  169. if ($sprintf !== null) {
  170. $string = Translate::checkAndReplaceArgs($string, $sprintf);
  171. }
  172. return str_replace('"', '&quot;', $string);
  173. }
  174. $current_key = strtolower('<{'.$name.'}'._THEME_NAME_.'>'.$source).'_'.$key;
  175. $default_key = strtolower('<{'.$name.'}prestashop>'.$source).'_'.$key;
  176. if ('controller' == substr($source, -10, 10)) {
  177. $file = substr($source, 0, -10);
  178. $current_key_file = strtolower('<{'.$name.'}'._THEME_NAME_.'>'.$file).'_'.$key;
  179. $default_key_file = strtolower('<{'.$name.'}prestashop>'.$file).'_'.$key;
  180. }
  181. if (isset($current_key_file) && !empty($_MODULES[$current_key_file])) {
  182. $ret = stripslashes($_MODULES[$current_key_file]);
  183. } elseif (isset($default_key_file) && !empty($_MODULES[$default_key_file])) {
  184. $ret = stripslashes($_MODULES[$default_key_file]);
  185. } elseif (!empty($_MODULES[$current_key])) {
  186. $ret = stripslashes($_MODULES[$current_key]);
  187. } elseif (!empty($_MODULES[$default_key])) {
  188. $ret = stripslashes($_MODULES[$default_key]);
  189. }
  190. // if translation was not found in module, look for it in AdminController or Helpers
  191. elseif (!empty($_LANGADM)) {
  192. $ret = stripslashes(Translate::getGenericAdminTranslation($string, $key, $_LANGADM));
  193. } else {
  194. $ret = stripslashes($string);
  195. }
  196. if ($sprintf !== null) {
  197. $ret = Translate::checkAndReplaceArgs($ret, $sprintf);
  198. }
  199. if ($js) {
  200. $ret = addslashes($ret);
  201. } else {
  202. $ret = htmlspecialchars($ret, ENT_COMPAT, 'UTF-8');
  203. }
  204. if ($sprintf === null) {
  205. $lang_cache[$cache_key] = $ret;
  206. } else {
  207. return $ret;
  208. }
  209. }
  210. return $lang_cache[$cache_key];
  211. }
  212. /**
  213. * Get a translation for a PDF
  214. *
  215. * @param string $string
  216. * @return string
  217. */
  218. public static function getPdfTranslation($string, $sprintf = null)
  219. {
  220. global $_LANGPDF;
  221. $iso = Context::getContext()->language->iso_code;
  222. if (!Validate::isLangIsoCode($iso)) {
  223. Tools::displayError(sprintf('Invalid iso lang (%s)', Tools::safeOutput($iso)));
  224. }
  225. $override_i18n_file = _PS_THEME_DIR_.'pdf/lang/'.$iso.'.php';
  226. $i18n_file = _PS_TRANSLATIONS_DIR_.$iso.'/pdf.php';
  227. if (file_exists($override_i18n_file)) {
  228. $i18n_file = $override_i18n_file;
  229. }
  230. if (!include($i18n_file)) {
  231. Tools::displayError(sprintf('Cannot include PDF translation language file : %s', $i18n_file));
  232. }
  233. if (!isset($_LANGPDF) || !is_array($_LANGPDF)) {
  234. return str_replace('"', '&quot;', $string);
  235. }
  236. $string = preg_replace("/\\\*'/", "\'", $string);
  237. $key = md5($string);
  238. $str = (array_key_exists('PDF'.$key, $_LANGPDF) ? $_LANGPDF['PDF'.$key] : $string);
  239. if ($sprintf !== null) {
  240. $str = Translate::checkAndReplaceArgs($str, $sprintf);
  241. }
  242. return $str;
  243. }
  244. /**
  245. * Check if string use a specif syntax for sprintf and replace arguments if use it
  246. *
  247. * @param $string
  248. * @param $args
  249. * @return string
  250. */
  251. public static function checkAndReplaceArgs($string, $args)
  252. {
  253. if (preg_match_all('#(?:%%|%(?:[0-9]+\$)?[+-]?(?:[ 0]|\'.)?-?[0-9]*(?:\.[0-9]+)?[bcdeufFosxX])#', $string, $matches) && !is_null($args)) {
  254. if (!is_array($args)) {
  255. $args = array($args);
  256. }
  257. return vsprintf($string, $args);
  258. }
  259. return $string;
  260. }
  261. /**
  262. * Perform operations on translations after everything is escaped and before displaying it
  263. */
  264. public static function postProcessTranslation($string, $params)
  265. {
  266. // If tags were explicitely provided, we want to use them *after* the translation string is escaped.
  267. if (!empty($params['tags'])) {
  268. foreach ($params['tags'] as $index => $tag) {
  269. // Make positions start at 1 so that it behaves similar to the %1$d etc. sprintf positional params
  270. $position = $index + 1;
  271. // extract tag name
  272. $match = array();
  273. if (preg_match('/^\s*<\s*(\w+)/', $tag, $match)) {
  274. $opener = $tag;
  275. $closer = '</'.$match[1].'>';
  276. $string = str_replace('['.$position.']', $opener, $string);
  277. $string = str_replace('[/'.$position.']', $closer, $string);
  278. $string = str_replace('['.$position.'/]', $opener.$closer, $string);
  279. }
  280. }
  281. }
  282. return $string;
  283. }
  284. /**
  285. * Compatibility method that just calls postProcessTranslation.
  286. * @deprecated renamed this to postProcessTranslation, since it is not only used in relation to smarty.
  287. */
  288. public static function smartyPostProcessTranslation($string, $params)
  289. {
  290. return Translate::postProcessTranslation($string, $params);
  291. }
  292. /**
  293. * Helper function to make calls to postProcessTranslation more readable.
  294. */
  295. public static function ppTags($string, $tags)
  296. {
  297. return Translate::postProcessTranslation($string, array('tags' => $tags));
  298. }
  299. }