PageRenderTime 47ms CodeModel.GetById 10ms RepoModel.GetById 0ms app.codeStats 0ms

/ace/prestashop/admin7/tabs/AdminTranslations.php

https://github.com/sealence/local
PHP | 858 lines | 773 code | 60 blank | 25 comment | 118 complexity | 37459addb2c18472ff85903e7b4664bd MD5 | raw file
  1. <?php
  2. /**
  3. * Translations tab for admin panel, AdminTranslations.php
  4. * @category admin
  5. *
  6. * @author PrestaShop <support@prestashop.com>
  7. * @copyright PrestaShop
  8. * @license http://www.opensource.org/licenses/osl-3.0.php Open-source licence 3.0
  9. * @version 1.2
  10. *
  11. */
  12. include_once(PS_ADMIN_DIR.'/../classes/AdminTab.php');
  13. define ('TEXTAREA_SIZED', 70);
  14. class AdminTranslations extends AdminTab
  15. {
  16. private function getModuleTranslations()
  17. {
  18. global $_MODULES, $_MODULE;
  19. if (!isset($_MODULE) AND !isset($_MODULES))
  20. $_MODULES = array();
  21. elseif (isset($_MODULE))
  22. $_MODULES = (is_array($_MODULES) AND is_array($_MODULE)) ? array_merge($_MODULES, $_MODULE) : $_MODULE;
  23. }
  24. private function checkDirAndCreate($dest)
  25. {
  26. $bool = true;
  27. $dir = trim(str_replace(_PS_ROOT_DIR_, '', dirname($dest)), '/');
  28. $subdir = explode('/', $dir);
  29. for ($i = 0, $path = ''; $subdir[$i]; $i++)
  30. {
  31. $path .= $subdir[$i].'/';
  32. if (!createDir(_PS_ROOT_DIR_.'/'.$path, 0777))
  33. {
  34. $bool &= false;
  35. $this->_errors[] = $this->l('Cannot create the folder').' "'.$path.'". '.$this->l('Check directory writing permisions.');
  36. break ;
  37. }
  38. }
  39. return $bool;
  40. }
  41. private function writeTranslationFile($type, $path, $mark = false, $fullmark = false)
  42. {
  43. global $currentIndex;
  44. if ($fd = fopen($path, 'w'))
  45. {
  46. unset($_POST['submitTranslations'.$type], $_POST['lang']);
  47. unset($_POST['token']);
  48. $toInsert = array();
  49. foreach($_POST as $key => $value)
  50. if (!empty($value))
  51. $toInsert[$key] = /*htmlentities(*/$value/*, ENT_COMPAT, 'UTF-8')*/;
  52. $tab = ($fullmark ? Tools::strtoupper($fullmark) : 'LANG').($mark ? Tools::strtoupper($mark) : '');
  53. fwrite($fd, "<?php\n\nglobal \$_".$tab.";\n\$_".$tab." = array();\n");
  54. foreach($toInsert as $key => $value)
  55. fwrite($fd, '$_'.$tab.'[\''.pSQL($key, true).'\'] = \''.pSQL($value, true).'\';'."\n");
  56. fwrite($fd, "\n?>");
  57. fclose($fd);
  58. Tools::redirectAdmin($currentIndex.'&conf=4&token='.$this->token);
  59. }
  60. else
  61. die('Cannot write language file');
  62. }
  63. public function submitCopyLang()
  64. {
  65. global $currentIndex;
  66. if (!($fromLang = strval(Tools::getValue('fromLang'))) OR !($toLang = strval(Tools::getValue('toLang'))))
  67. $this->_errors[] = $this->l('you must select 2 languages in order to copy data from one to another');
  68. elseif (!($fromTheme = strval(Tools::getValue('fromTheme'))) OR !($toTheme = strval(Tools::getValue('toTheme'))))
  69. $this->_errors[] = $this->l('you must select 2 themes in order to copy data from one to another');
  70. elseif (!Language::copyLanguageData(Language::getIdByIso($fromLang), Language::getIdByIso($toLang)))
  71. $this->_errors[] = $this->l('an error occurred while copying data');
  72. elseif ($fromLang == $toLang AND $fromTheme == $toTheme)
  73. $this->_errors[] = $this->l('nothing to copy! (same language and theme)');
  74. if (sizeof($this->_errors))
  75. return ;
  76. $bool = true;
  77. $items = Language::getFilesList($fromLang, $fromTheme, $toLang, $toTheme, false, false, true);
  78. foreach ($items as $source => $dest)
  79. {
  80. $bool &= $this->checkDirAndCreate($dest);
  81. $bool &= @copy($source, $dest);
  82. }
  83. if ($bool)
  84. Tools::redirectLink($currentIndex.'&conf=14&token='.$this->token);
  85. $this->_errors[] = $this->l('a part of the data has been copied but some language files could not be found or copied');
  86. }
  87. public function submitExportLang()
  88. {
  89. global $currentIndex;
  90. $lang = strtolower(Tools::getValue('iso_code'));
  91. $theme = strval(Tools::getValue('theme'));
  92. if ($lang AND $theme)
  93. {
  94. $items = array_flip(Language::getFilesList($lang, $theme, false, false, false, false, true));
  95. $gz = new Archive_Tar(_PS_TRANSLATIONS_DIR_.'/export/'.$lang.'.gzip', true);
  96. if ($gz->createModify($items, NULL, _PS_ROOT_DIR_));
  97. Tools::redirect('translations/export/'.$lang.'.gzip');
  98. $this->_errors[] = Tools::displayError('an error occurred while creating archive');
  99. }
  100. $this->_errors[] = Tools::displayError('please choose a language and a theme');
  101. }
  102. public function submitImportLang()
  103. {
  104. global $currentIndex;
  105. if (!isset($_FILES['file']['tmp_name']) OR !$_FILES['file']['tmp_name'])
  106. $this->_errors[] = Tools::displayError('no file selected');
  107. else
  108. {
  109. $gz = new Archive_Tar($_FILES['file']['tmp_name'], true);
  110. if ($gz->extract(_PS_TRANSLATIONS_DIR_.'../', false))
  111. Tools::redirectAdmin($currentIndex.'&conf=15&token='.$this->token);
  112. $this->_errors[] = Tools::displayError('archive cannot be extracted');
  113. }
  114. }
  115. public function findAndWriteTranslationsIntoFile($filename, $files, $themeName, $moduleName, $dir = false)
  116. {
  117. static $_cacheFile = array();
  118. if (!isset($_cacheFile[$filename]))
  119. {
  120. $_cacheFile[$filename] = true;
  121. if (!$fd = fopen($filename, 'w'))
  122. die ($this->l('Cannot write the theme\'s language file ').'('.$filename.')'.$this->l('. Please check write permissions.'));
  123. fwrite($fd, "<?php\n\nglobal \$_MODULE;\n\$_MODULE = array();\n");
  124. fclose($fd);
  125. }
  126. $tplRegex = '/\{l s=\''._PS_TRANS_PATTERN_.'\'( mod=\'.+\')?( js=1)?\}/U';
  127. $phpRegex = '/->l\(\''._PS_TRANS_PATTERN_.'\'(, \'(.+)\')?(, (.+))?\)/U';
  128. if (!$dir)
  129. $dir = ($themeName == 'prestashop' ? _PS_MODULE_DIR_.$moduleName.'/' : _PS_ALL_THEMES_DIR_.$themeName.'/modules/'.$moduleName.'/');
  130. if (!$writeFd = fopen($filename, 'a+'))
  131. die ($this->l('Cannot write the theme\'s language file ').'('.$filename.')'.$this->l('. Please check write permissions.'));
  132. else
  133. {
  134. $_tmp = array();
  135. foreach ($files AS $templateFile)
  136. {
  137. if ((preg_match('/^(.*).tpl$/', $templateFile) OR ($themeName == 'prestashop' AND preg_match('/^(.*).php$/', $templateFile))) AND file_exists($tpl = $dir.$templateFile))
  138. {
  139. /* Get translations key */
  140. $readFd = fopen($tpl, 'r');
  141. $content = (filesize($tpl) ? fread($readFd, filesize($tpl)) : '');
  142. preg_match_all(substr($templateFile, -4) == '.tpl' ? $tplRegex : $phpRegex, $content, $matches);
  143. fclose($readFd);
  144. /* Write each translation on its module file */
  145. $templateName = substr(basename($templateFile), 0, -4);
  146. foreach ($matches[1] as $key)
  147. {
  148. $postKey = md5($moduleName.'_'.$themeName.'_'.$templateName.'_'.md5($key));
  149. $pattern = '\'<{'.$moduleName.'}'.$themeName.'>'.Tools::strtolower($templateName).'_'.md5($key).'\'';
  150. if (array_key_exists($postKey, $_POST) AND !empty($_POST[$postKey]) AND !array_key_exists($pattern, $_tmp))
  151. {
  152. $_tmp[$pattern] = true;
  153. fwrite($writeFd, '$_MODULE['.$pattern.'] = \''.pSQL($_POST[$postKey]).'\';'."\n");
  154. }
  155. }
  156. }
  157. }
  158. fclose($writeFd);
  159. }
  160. }
  161. public function findAndFillTranslations($files, &$translationsArray, $themeName, $moduleName, $dir = false)
  162. {
  163. global $_MODULES;
  164. $tplRegex = '/\{l s=\''._PS_TRANS_PATTERN_.'\'( mod=\'.+\')?( js=1)?\}/U';
  165. $phpRegex = '/->l\(\''._PS_TRANS_PATTERN_.'\'(, \'(.+)\')?(, (.+))?\)/U';
  166. $count = 0;
  167. if (!$dir)
  168. $dir = ($themeName == 'prestashop' ? _PS_MODULE_DIR_.$moduleName.'/' : _PS_ALL_THEMES_DIR_.$themeName.'/modules/'.$moduleName.'/');
  169. foreach ($files AS $templateFile)
  170. if ((preg_match('/^(.*).tpl$/', $templateFile) OR ($themeName == 'prestashop' AND preg_match('/^(.*).php$/', $templateFile))) AND file_exists($tpl = $dir.$templateFile))
  171. {
  172. /* Get translations key */
  173. $readFd = fopen($tpl, 'r');
  174. $content = (filesize($tpl) ? fread($readFd, filesize($tpl)) : '');
  175. preg_match_all(substr($templateFile, -4) == '.tpl' ? $tplRegex : $phpRegex, $content, $matches);
  176. fclose($readFd);
  177. /* Write each translation on its module file */
  178. $templateName = substr(basename($templateFile), 0, -4);
  179. foreach ($matches[1] as $key)
  180. {
  181. $moduleKey = '<{'.$moduleName.'}'.$themeName.'>'.Tools::strtolower($templateName).'_'.md5($key);
  182. $translationsArray[$themeName][$moduleName][$templateName][$key] = key_exists($moduleKey, $_MODULES) ? html_entity_decode($_MODULES[$moduleKey], ENT_COMPAT, 'UTF-8') : '';
  183. }
  184. $count += isset($translationsArray[$themeName][$moduleName][$templateName]) ? sizeof($translationsArray[$themeName][$moduleName][$templateName]) : 0;
  185. }
  186. return ($count);
  187. }
  188. public function postProcess()
  189. {
  190. global $currentIndex;
  191. if (Tools::isSubmit('submitCopyLang'))
  192. {
  193. if ($this->tabAccess['add'] === '1')
  194. $this->submitCopyLang();
  195. else
  196. $this->_errors[] = Tools::displayError('You do not have permission to add anything here.');
  197. }
  198. elseif (Tools::isSubmit('submitExport'))
  199. {
  200. if ($this->tabAccess['add'] === '1')
  201. $this->submitExportLang();
  202. else
  203. $this->_errors[] = Tools::displayError('You do not have permission to add anything here.');
  204. }
  205. elseif (Tools::isSubmit('submitImport'))
  206. {
  207. if ($this->tabAccess['add'] === '1')
  208. $this->submitImportLang();
  209. else
  210. $this->_errors[] = Tools::displayError('You do not have permission to add anything here.');
  211. }
  212. elseif (Tools::isSubmit('submitTranslationsFront'))
  213. {
  214. if ($this->tabAccess['edit'] === '1')
  215. $this->writeTranslationFile('Front', _PS_THEME_DIR_.'lang/'.Tools::strtolower(Tools::getValue('lang')).'.php');
  216. else
  217. $this->_errors[] = Tools::displayError('You do not have permission to edit anything here.');
  218. }
  219. elseif (Tools::isSubmit('submitTranslationsPDF'))
  220. {
  221. if ($this->tabAccess['edit'] === '1')
  222. $this->writeTranslationFile('PDF', _PS_TRANSLATIONS_DIR_.Tools::strtolower(Tools::getValue('lang')).'/pdf.php', 'PDF');
  223. else
  224. $this->_errors[] = Tools::displayError('You do not have permission to edit anything here.');
  225. }
  226. elseif (Tools::isSubmit('submitTranslationsBack'))
  227. {
  228. if ($this->tabAccess['edit'] === '1')
  229. $this->writeTranslationFile('Back', _PS_TRANSLATIONS_DIR_.Tools::strtolower(Tools::getValue('lang')).'/admin.php', 'ADM');
  230. else
  231. $this->_errors[] = Tools::displayError('You do not have permission to edit anything here.');
  232. }
  233. elseif (Tools::isSubmit('submitTranslationsErrors'))
  234. {
  235. if ($this->tabAccess['edit'] === '1')
  236. $this->writeTranslationFile('Errors', _PS_TRANSLATIONS_DIR_.Tools::strtolower(Tools::getValue('lang')).'/errors.php', false, 'ERRORS');
  237. else
  238. $this->_errors[] = Tools::displayError('You do not have permission to edit anything here.');
  239. }
  240. elseif (Tools::isSubmit('submitTranslationsFields'))
  241. {
  242. if ($this->tabAccess['edit'] === '1')
  243. $this->writeTranslationFile('Fields', _PS_TRANSLATIONS_DIR_.Tools::strtolower(Tools::getValue('lang')).'/fields.php', false, 'FIELDS');
  244. else
  245. $this->_errors[] = Tools::displayError('You do not have permission to edit anything here.');
  246. }
  247. elseif (Tools::isSubmit('submitTranslationsModules'))
  248. {
  249. if ($this->tabAccess['edit'] === '1')
  250. {
  251. $lang = Tools::strtolower($_POST['lang']);
  252. if (!$modules = scandir(_PS_MODULE_DIR_))
  253. $this->displayWarning(Tools::displayError('There are no modules in your copy of PrestaShop. Use the Modules tab to activate them or go to our Website to download additional Modules.'));
  254. else
  255. {
  256. foreach ($modules AS $module)
  257. if ($module{0} != '.' AND is_dir(_PS_MODULE_DIR_.$module))
  258. {
  259. $filename = _PS_MODULE_DIR_.$module.'/'.$lang.'.php';
  260. $content = scandir(_PS_MODULE_DIR_.$module);
  261. foreach ($content as $cont)
  262. if ($cont{0} != '.' AND $cont != 'img' AND $cont != 'mails' AND $cont != 'js' AND is_dir(_PS_MODULE_DIR_.$module.'/'.$cont))
  263. if ($files = @scandir(_PS_MODULE_DIR_.$module.'/'.$cont))
  264. $this->findAndWriteTranslationsIntoFile($filename, $files, 'prestashop', $module, _PS_MODULE_DIR_.$module.'/'.$cont.'/');
  265. if ($files = @scandir(_PS_MODULE_DIR_.$module.'/'))
  266. $this->findAndWriteTranslationsIntoFile($filename, $files, 'prestashop', $module);
  267. }
  268. }
  269. /* Search language tags (eg {l s='to translate'}) */
  270. if ($themes = scandir(_PS_ALL_THEMES_DIR_))
  271. foreach ($themes AS $theme)
  272. if ($theme{0} != '.' AND is_dir(_PS_ALL_THEMES_DIR_.$theme) AND file_exists(_PS_ALL_THEMES_DIR_.$theme.'/modules/'))
  273. {
  274. if ($modules = scandir(_PS_ALL_THEMES_DIR_.$theme.'/modules/'))
  275. foreach ($modules AS $module)
  276. if ($module{0} != '.' AND is_dir(_PS_ALL_THEMES_DIR_.$theme.'/modules/'.$module) AND $files = scandir(_PS_ALL_THEMES_DIR_.$theme.'/modules/'.$module.'/'))
  277. $this->findAndWriteTranslationsIntoFile(_PS_ALL_THEMES_DIR_.$theme.'/modules/'.$module.'/'.$lang.'.php', $files, $theme, $module);
  278. }
  279. Tools::redirectAdmin($currentIndex.'&conf=4&token='.$this->token);
  280. }
  281. else
  282. $this->_errors[] = Tools::displayError('You do not have permission to edit anything here.');
  283. }
  284. }
  285. public function display()
  286. {
  287. global $currentIndex, $cookie;
  288. $translations = array(
  289. 'front' => $this->l('Front Office translations'),
  290. 'back' => $this->l('Back Office translations'),
  291. 'errors' => $this->l('Errors messages translations'),
  292. 'fields' => $this->l('Fields name translations'),
  293. 'modules' => $this->l('Modules translations'),
  294. 'pdf' => $this->l('PDF translations'),
  295. );
  296. if ($type = Tools::getValue('type'))
  297. $this->{'displayForm'.$type}(Tools::strtolower(Tools::getValue('lang')));
  298. else
  299. {
  300. $languages = Language::getLanguages();
  301. echo '<fieldset class="width2"><legend><img src="../img/admin/translation.gif" />'.$this->l('Modify translations').'</legend>'.
  302. $this->l('Here you can modify translations for every text input on PrestaShop.').'<br />'.
  303. $this->l('First, select a section (such as Back Office or Modules), then click the flag representing the language you want to edit.').'<br /><br />
  304. <form method="get" action="index.php" id="typeTranslationForm">
  305. <input type="hidden" name="tab" value="AdminTranslations" />
  306. <input type="hidden" name="lang" id="translation_lang" value="0" />
  307. <select name="type" style="float:left; margin-right:10px;">';
  308. foreach ($translations as $key => $translation)
  309. echo '<option value="'.$key.'">'.$translation.'&nbsp;</option>';
  310. echo '</select>';
  311. foreach ($languages as $language)
  312. echo '<a href="javascript:chooseTypeTranslation(\''.$language['iso_code'].'\')">
  313. <img src="'._THEME_LANG_DIR_.$language['id_lang'].'.jpg" alt="'.$language['iso_code'].'" title="'.$language['iso_code'].'" />
  314. </a>';
  315. echo '<input type="hidden" name="token" value="'.$this->token.'" /></form></fieldset>
  316. <br /><br /><h2>'.$this->l('Translation exchange').'</h2>
  317. <form action="'.$currentIndex.'&token='.$this->token.'" method="post" enctype="multipart/form-data">
  318. <fieldset class="width2"><legend><img src="../img/admin/import.gif" />'.$this->l('Import a language pack').'</legend>
  319. <p>'.$this->l('Import data from file (language pack).').'<br />'.
  320. $this->l('Be careful, as it will replace all existing data for the destination language!').'<br />'.
  321. $this->l('Browse your computer for the language file to be imported:').'</p>
  322. <div style="float:left;">
  323. <p>
  324. <div style="width:75px; font-weight:bold; float:left;">'.$this->l('From:').'</div>
  325. <input type="file" name="file" />
  326. </p>
  327. </div>
  328. <div style="float:left;">
  329. <input type="submit" value="'.$this->l('Import').'" name="submitImport" class="button" style="margin:10px 0px 0px 25px;" />
  330. </div>
  331. </fieldset>
  332. </form>
  333. <br /><br />
  334. <form action="'.$currentIndex.'&token='.$this->token.'" method="post" enctype="multipart/form-data">
  335. <fieldset class="width2"><legend><img src="../img/admin/export.gif" />'.$this->l('Export a language').'</legend>
  336. <p>'.$this->l('Export data from one language to a file (language pack).').'<br />'.
  337. $this->l('Choose the theme from which you want to export translations.').'<br />
  338. <select name="iso_code" style="margin-top:10px;">';
  339. foreach ($languages as $language)
  340. echo '<option value="'.$language['iso_code'].'">'.$language['name'].'</option>';
  341. echo '
  342. </select>
  343. &nbsp;&nbsp;&nbsp;
  344. <select name="theme" style="margin-top:10px;">';
  345. $themes = self::getThemesList();
  346. foreach ($themes as $theme)
  347. echo '<option value="'.$theme['name'].'">'.$theme['name'].'</option>';
  348. echo '
  349. </select>&nbsp;&nbsp;
  350. <input type="submit" class="button" name="submitExport" value="'.$this->l('Export').'" />
  351. </fieldset>
  352. </form>
  353. <br /><br />';
  354. $allLanguages = Language::getLanguages(false);
  355. echo '
  356. <form action="'.$currentIndex.'&token='.$this->token.'" method="post">
  357. <fieldset class="width2"><legend><img src="../img/admin/copy_files.gif" />'.$this->l('Copy').'</legend>
  358. <p>'.$this->l('Copies data from one language to another.').'<br />'.
  359. $this->l('Be careful, as it will replace all existing data for the destination language!').'<br />'.
  360. $this->l('If necessary').', <b><a href="index.php?tab=AdminLanguages&addlang&token='.Tools::getAdminToken('AdminLanguages'.intval(Tab::getIdFromClassName('AdminLanguages')).intval($cookie->id_employee)).'">'.$this->l('first create a new language').'</a></b>.</p>
  361. <div style="float:left;">
  362. <p>
  363. <div style="width:75px; font-weight:bold; float:left;">'.$this->l('From:').'</div>
  364. <select name="fromLang">';
  365. foreach ($languages AS $language)
  366. echo '<option value="'.$language['iso_code'].'">'.$language['name'].'</option>';
  367. echo '
  368. </select>
  369. &nbsp;&nbsp;&nbsp;
  370. <select name="fromTheme">';
  371. $themes = self::getThemesList();
  372. foreach ($themes as $theme)
  373. echo '<option value="'.$theme['name'].'">'.$theme['name'].'</option>';
  374. echo '
  375. </select> <span style="font-style: bold; color: red;">*</span>
  376. </p>
  377. <p>
  378. <div style="width:75px; font-weight:bold; float:left;">'.$this->l('To:').'</div>
  379. <select name="toLang">';
  380. foreach ($allLanguages AS $language)
  381. echo '<option value="'.$language['iso_code'].'">'.$language['name'].'</option>';
  382. echo '
  383. </select>
  384. &nbsp;&nbsp;&nbsp;
  385. <select name="toTheme">';
  386. $themes = self::getThemesList();
  387. foreach ($themes as $theme)
  388. echo '<option value="'.$theme['name'].'">'.$theme['name'].'</option>';
  389. echo '
  390. </select>
  391. </p>
  392. </div>
  393. <div style="float:left;">
  394. <input type="submit" value="'.$this->l(' Copy ').'" name="submitCopyLang" class="button" style="margin:25px 0px 0px 25px;" />
  395. </div>
  396. <p style="clear: left; padding: 16px 0px 0px 0px;"><span style="font-style: bold; color: red;">*</span> '.$this->l('Language files (as indicated at Tools >> Languages >> Edition) must be complete to allow copying of translations').'</p>
  397. </fieldset>
  398. </form>';
  399. }
  400. }
  401. function fileExists($dir, $file, $var)
  402. {
  403. ${$var} = array();
  404. if (!file_exists($dir))
  405. if (!mkdir($dir, 0700))
  406. die('Please create the directory '.$dir);
  407. if (!file_exists($dir.'/'.$file))
  408. if (!file_put_contents($dir.'/'.$file, "<?php\n\nglobal \$".$var.";\n\$".$var." = array();\n\n?>"))
  409. die('Please create a "'.$file.'" file in '.$dir);
  410. if (!is_writable($dir.'/'.$file))
  411. $this->displayWarning(Tools::displayError('This file has to be writable:').' '.$dir.'/'.$file);
  412. include($dir.'/'.$file);
  413. return ${$var};
  414. }
  415. function displayToggleButton()
  416. {
  417. echo '
  418. <script type="text/javascript">
  419. var openAll = \''.html_entity_decode($this->l('Expand all fieldsets'), ENT_NOQUOTES, 'UTF-8').'\';
  420. var closeAll = \''.html_entity_decode($this->l('Close all fieldsets'), ENT_NOQUOTES, 'UTF-8').'\';
  421. </script>
  422. <input type="button" class="button" id="buttonall" onclick="openCloseAllDiv(\''.$_GET['type'].'_div\', this.value == openAll); toggleElemValue(this.id, openAll, closeAll);" />
  423. <script type="text/javascript">toggleElemValue(\'buttonall\', openAll, closeAll);</script>';
  424. }
  425. function displayFormfront($lang)
  426. {
  427. global $currentIndex;
  428. $_LANG = $this->fileExists(_PS_THEME_DIR_.'lang', Tools::strtolower($lang).'.php', '_LANG');
  429. /* List templates to parse */
  430. $templates = scandir(_PS_THEME_DIR_);
  431. $count = 0;
  432. $files = array();
  433. foreach ($templates AS $template)
  434. if (preg_match('/^(.*).tpl$/', $template) AND file_exists($tpl = _PS_THEME_DIR_.$template))
  435. {
  436. $template = substr(basename($template), 0, -4);
  437. $newLang = array();
  438. $fd = fopen($tpl, 'r');
  439. $content = fread($fd, filesize($tpl));
  440. /* Search language tags (eg {l s='to translate'}) */
  441. $regex = '/\{l s=\''._PS_TRANS_PATTERN_.'\'( js=1)?\}/U';
  442. preg_match_all($regex, $content, $matches);
  443. /* Get string translation */
  444. foreach($matches[1] as $key)
  445. {
  446. $key2 = $template.'_'.md5($key);
  447. $newLang[$key] = (key_exists($key2, $_LANG)) ? html_entity_decode($_LANG[$key2], ENT_COMPAT, 'UTF-8') : '';
  448. }
  449. $files[$template] = $newLang;
  450. $count += sizeof($newLang);
  451. }
  452. echo '
  453. <h2>'.$this->l('Language').' : '.Tools::strtoupper($lang).'</h2>
  454. '.$this->l('Total expressions').' : <b>'.$count.'</b>. '.$this->l('Click the fieldset title to expand or close the fieldset.').'.<br /><br />
  455. <form method="post" action="'.$currentIndex.'&submitTranslationsFront=1&token='.$this->token.'" class="form">';
  456. $this->displayToggleButton();
  457. echo '<input type="hidden" name="lang" value="'.$lang.'" /><input type="submit" name="submitTranslationsFront" value="'.$this->l('Update translations').'" class="button" /><br /><br />';
  458. foreach ($files as $k => $newLang)
  459. if (sizeof($newLang))
  460. {
  461. $countValues = array_count_values($newLang);
  462. $empty = isset($countValues['']) ? $countValues[''] : 0;
  463. echo '
  464. <fieldset><legend style="cursor : pointer" onclick="openCloseLayer(\''.$k.'\')">'.$k.' - <font color="blue">'.sizeof($newLang).'</font> '.$this->l('expressions').' (<font color="red">'.$empty.'</font>)</legend>
  465. <div name="front_div" id="'.$k.'" style="display: '.($empty ? 'block' : 'none').';">
  466. <table cellpadding="2">';
  467. foreach ($newLang as $key => $value)
  468. {
  469. echo '<tr><td style="width: 40%">'.stripslashes($key).'</td><td>= ';
  470. if (strlen($key) < TEXTAREA_SIZED)
  471. echo '<input type="text" style="width: 450px" name="'.$k.'_'.md5($key).'" value="'.stripslashes(preg_replace('/"/', '\&quot;', stripslashes($value))).'" /></td></tr>';
  472. else
  473. echo '<textarea rows="'.intval(strlen($key) / TEXTAREA_SIZED).'" style="width: 450px" name="'.$k.'_'.md5($key).'">'.stripslashes(preg_replace('/"/', '\&quot;', stripslashes($value))).'</textarea></td></tr>';
  474. }
  475. echo '
  476. </table>
  477. </div>
  478. </fieldset><br />';
  479. }
  480. echo '<br /><input type="submit" name="submitTranslationsFront" value="'.$this->l('Update translations').'" class="button" /></form>';
  481. }
  482. function displayFormback($lang)
  483. {
  484. global $currentIndex;
  485. $_LANGADM = $this->fileExists(_PS_TRANSLATIONS_DIR_.$lang, 'admin.php', '_LANGADM');
  486. /* List templates to parse */
  487. $count = 0;
  488. $tabs = scandir(PS_ADMIN_DIR.'/tabs');
  489. $tabs[] = '../../classes/AdminTab.php';
  490. $files = array();
  491. foreach ($tabs AS $tab)
  492. if (preg_match('/^(.*)\.php$/', $tab) AND file_exists($tpl = PS_ADMIN_DIR.'/tabs/'.$tab))
  493. {
  494. $tab = basename(substr($tab, 0, -4));
  495. $fd = fopen($tpl, 'r');
  496. $content = fread($fd, filesize($tpl));
  497. fclose($fd);
  498. $regex = '/this->l\(\''._PS_TRANS_PATTERN_.'\'[\)|\,]/U';
  499. preg_match_all($regex, $content, $matches);
  500. foreach ($matches[1] as $key)
  501. $tabsArray[$tab][$key] = stripslashes(key_exists($tab.md5($key), $_LANGADM) ? html_entity_decode($_LANGADM[$tab.md5($key)], ENT_COMPAT, 'UTF-8') : '');
  502. $count += isset($tabsArray[$tab]) ? sizeof($tabsArray[$tab]) : 0;
  503. }
  504. foreach (array('header.inc', 'index', 'login', 'password') as $tab)
  505. {
  506. $tab = PS_ADMIN_DIR.'/'.$tab.'.php';
  507. $fd = fopen($tab, 'r');
  508. $content = fread($fd, filesize($tab));
  509. fclose($fd);
  510. $regex = '/translate\(\''._PS_TRANS_PATTERN_.'\'\)/U';
  511. preg_match_all($regex, $content, $matches);
  512. foreach ($matches[1] as $key)
  513. $tabsArray['index'][$key] = stripslashes(key_exists('index'.md5($key), $_LANGADM) ? html_entity_decode($_LANGADM['index'.md5($key)], ENT_COMPAT, 'UTF-8') : '');
  514. $count += isset($tabsArray['index']) ? sizeof($tabsArray['index']) : 0;
  515. }
  516. echo '
  517. <h2>'.$this->l('Language').' : '.Tools::strtoupper($lang).'</h2>
  518. '.$this->l('Expressions to translate').' : <b>'.$count.'</b>. '.$this->l('Click on the titles to open fieldsets').'.<br /><br />
  519. <form method="post" action="'.$currentIndex.'&submitTranslationsBack=1&token='.$this->token.'" class="form">';
  520. $this->displayToggleButton();
  521. echo '<input type="hidden" name="lang" value="'.$lang.'" /><input type="submit" name="submitTranslationsBack" value="'.$this->l('Update translations').'" class="button" /><br /><br />';
  522. foreach ($tabsArray as $k => $newLang)
  523. if (sizeof($newLang))
  524. {
  525. $countValues = array_count_values($newLang);
  526. $empty = isset($countValues['']) ? $countValues[''] : 0;
  527. echo '
  528. <fieldset><legend style="cursor : pointer" onclick="openCloseLayer(\''.$k.'\')">'.$k.' - <font color="blue">'.sizeof($newLang).'</font> '.$this->l('expressions').' (<font color="red">'.$empty.'</font>)</legend>
  529. <div name="back_div" id="'.$k.'" style="display: '.($empty ? 'block' : 'none').';">
  530. <table cellpadding="2">';
  531. foreach ($newLang as $key => $value)
  532. {
  533. echo '<tr><td style="width: 40%">'.stripslashes($key).'</td><td>= ';
  534. if (strlen($key) < TEXTAREA_SIZED)
  535. echo '<input type="text" style="width: 450px" name="'.$k.md5($key).'" value="'.stripslashes(preg_replace('/"/', '\&quot;', $value)).'" /></td></tr>';
  536. else
  537. echo '<textarea rows="'.intval(strlen($key) / TEXTAREA_SIZED).'" style="width: 450px" name="'.$k.md5($key).'">'.stripslashes(preg_replace('/"/', '\&quot;', $value)).'</textarea></td></tr>';
  538. }
  539. echo '
  540. </table>
  541. </div>
  542. </fieldset><br />';
  543. }
  544. echo '<br /><input type="submit" name="submitTranslationsBack" value="'.$this->l('Update translations').'" class="button" /></form>';
  545. }
  546. function displayFormerrors($lang)
  547. {
  548. global $currentIndex;
  549. $_ERRORS = $this->fileExists(_PS_TRANSLATIONS_DIR_.$lang, 'errors.php', '_ERRORS');
  550. /* List files to parse */
  551. $stringToTranslate = array();
  552. $dirToParse = array(PS_ADMIN_DIR.'/../',
  553. PS_ADMIN_DIR.'/../classes/',
  554. PS_ADMIN_DIR.'/',
  555. PS_ADMIN_DIR.'/tabs/');
  556. if (!file_exists(_PS_MODULE_DIR_))
  557. die($this->displayWarning(Tools::displayError('Fatal error: Module directory is not here anymore ').'('._PS_MODULE_DIR_.')'));
  558. if (!is_writable(_PS_MODULE_DIR_))
  559. $this->displayWarning(Tools::displayError('The module directory must be writable'));
  560. if (!$modules = scandir(_PS_MODULE_DIR_))
  561. $this->displayWarning(Tools::displayError('There are no modules in your copy of PrestaShop. Use the Modules tab to activate them or go to our Website to download additional Modules.'));
  562. else
  563. {
  564. $count = 0;
  565. foreach ($modules AS $module)
  566. if (is_dir(_PS_MODULE_DIR_.$module) && $module != '.' && $module != '..' && $module != '.svn' )
  567. $dirToParse[] = _PS_MODULE_DIR_.$module.'/';
  568. }
  569. foreach ($dirToParse AS $dir)
  570. foreach (scandir($dir) AS $file)
  571. if (preg_match('/.php$/', $file) AND file_exists($fn = $dir.$file) AND $file != 'index.php')
  572. {
  573. preg_match_all('/Tools::displayError\(\''._PS_TRANS_PATTERN_.'\'(, true)?\)/U', fread(fopen($fn, 'r'), filesize($fn)), $matches);
  574. foreach($matches[1] as $key)
  575. $stringToTranslate[$key] = (key_exists(md5($key), $_ERRORS)) ? html_entity_decode($_ERRORS[md5($key)], ENT_COMPAT, 'UTF-8') : '';
  576. }
  577. $irow = 0;
  578. echo '<h2>'.$this->l('Language').' : '.Tools::strtoupper($lang).'</h2>'.$this->l('Errors to translate').' : <b>'.sizeof($stringToTranslate).'</b><br /><br />
  579. <form method="post" action="'.$currentIndex.'&submitTranslationsErrors=1&lang='.$lang.'&token='.$this->token.'" class="form">
  580. <input type="submit" name="submitTranslationsErrors" value="'.$this->l('Update translations').'" class="button" /><br /><br />
  581. <table cellpadding="0" cellspacing="0" class="table">';
  582. ksort($stringToTranslate);
  583. foreach ($stringToTranslate as $key => $value)
  584. echo '<tr '.(empty($value) ? 'style="background-color:#FBB"' : (++$irow % 2 ? 'class="alt_row"' : '')).'><td>'.stripslashes($key).'</td><td style="width: 430px">= <input type="text" name="'.md5($key).'" value="'.preg_replace('/"/', '&quot;', stripslashes($value)).'" style="width: 400px"></td></tr>';
  585. echo '</table><br /><input type="submit" name="submitTranslationsErrors" value="'.$this->l('Update translations').'" class="button" /></form>';
  586. }
  587. function displayFormfields($lang)
  588. {
  589. global $currentIndex;
  590. $_FIELDS = $this->fileExists(_PS_TRANSLATIONS_DIR_.$lang, 'fields.php', '_FIELDS');
  591. $classArray = array();
  592. $count = 0;
  593. foreach (scandir(_PS_CLASS_DIR_) AS $classFile)
  594. {
  595. if (!preg_match('/\.php$/', $classFile) OR $classFile == 'index.php')
  596. continue;
  597. include_once(_PS_CLASS_DIR_.$classFile);
  598. $className = substr($classFile, 0, -4);
  599. if (!class_exists($className))
  600. continue;
  601. if (!is_subclass_of($className, 'ObjectModel'))
  602. continue;
  603. $classArray[$className] = call_user_func(array($className, 'getValidationRules'), $className);
  604. if (isset($classArray[$className]['validate']))
  605. $count += sizeof($classArray[$className]['validate']);
  606. if (isset($classArray[$className]['validateLang']))
  607. $count += sizeof($classArray[$className]['validateLang']);
  608. }
  609. echo '
  610. <h2>'.$this->l('Language').' : '.Tools::strtoupper($lang).'</h2>
  611. '.$this->l('Fields to translate').' : <b>'.$count.'</b>. '.$this->l('Click on the titles to open fieldsets').'.<br /><br />
  612. <form method="post" action="'.$currentIndex.'&submitTranslationsFields=1&token='.$this->token.'" class="form">';
  613. $this->displayToggleButton();
  614. echo '<input type="hidden" name="lang" value="'.$lang.'" /><input type="submit" name="submitTranslationsFields" value="'.$this->l('Update translations').'" class="button" /><br /><br />';
  615. foreach ($classArray AS $className => $rules)
  616. {
  617. $translated = 0;
  618. $toTranslate = 0;
  619. if (isset($rules['validate']))
  620. foreach ($rules['validate'] AS $key => $value)
  621. (array_key_exists($className.'_'.md5($key), $_FIELDS)) ? ++$translated : ++$toTranslate;
  622. if (isset($rules['validateLang']))
  623. foreach ($rules['validateLang'] AS $key => $value)
  624. (array_key_exists($className.'_'.md5($key), $_FIELDS)) ? ++$translated : ++$toTranslate;
  625. echo '
  626. <fieldset class="width3"><legend style="cursor : pointer" onclick="openCloseLayer(\''.$className.'\')">'.$className.' - <font color="blue">'.($toTranslate + $translated).'</font> '.$this->l('fields').' (<font color="red">'.$toTranslate.'</font>)</legend>
  627. <div name="fields_div" id="'.$className.'" style="display: '.($toTranslate ? 'block' : 'none').';">
  628. <table cellpadding="2">';
  629. if (isset($rules['validate']))
  630. foreach ($rules['validate'] AS $key => $value)
  631. echo '<tr><td>'.stripslashes($key).'</td><td style="width: 380px">= <input type="text" name="'.$className.'_'.md5(addslashes($key)).'" value="'.(array_key_exists($className.'_'.md5(addslashes($key)), $_FIELDS) ? html_entity_decode($_FIELDS[$className.'_'.md5(addslashes($key))], ENT_NOQUOTES, 'UTF-8') : '').'" style="width: 350px"></td></tr>';
  632. if (isset($rules['validateLang']))
  633. foreach ($rules['validateLang'] AS $key => $value)
  634. echo '<tr><td>'.stripslashes($key).'</td><td style="width: 380px">= <input type="text" name="'.$className.'_'.md5(addslashes($key)).'" value="'.(array_key_exists($className.'_'.md5(addslashes($key)), $_FIELDS) ? html_entity_decode($_FIELDS[$className.'_'.md5(addslashes($key))], ENT_COMPAT, 'UTF-8') : '').'" style="width: 350px"></td></tr>';
  635. echo '
  636. </table>
  637. </div>
  638. </fieldset><br />';
  639. }
  640. echo '<br /><input type="submit" name="submitTranslationsFields" value="'.$this->l('Update translations').'" class="button" /></form>';
  641. }
  642. function displayFormModules($lang)
  643. {
  644. global $currentIndex, $_MODULES;
  645. if (!file_exists(_PS_MODULE_DIR_))
  646. die($this->displayWarning(Tools::displayError('Fatal error: Module directory is not here anymore ').'('._PS_MODULE_DIR_.')'));
  647. if (!is_writable(_PS_MODULE_DIR_))
  648. $this->displayWarning(Tools::displayError('The module directory must be writable'));
  649. if (!$modules = scandir(_PS_MODULE_DIR_))
  650. $this->displayWarning(Tools::displayError('There are no modules in your copy of PrestaShop. Use the Modules tab to activate them or go to our Website to download additional Modules.'));
  651. else
  652. {
  653. $allfiles = array();
  654. $count = 0;
  655. foreach ($modules AS $module)
  656. if ($module{0} != '.' AND is_dir(_PS_MODULE_DIR_.$module))
  657. {
  658. @include_once(_PS_MODULE_DIR_.$module.'/'.$lang.'.php');
  659. self::getModuleTranslations();
  660. $content = scandir(_PS_MODULE_DIR_.$module);
  661. foreach ($content as $cont)
  662. if ($cont{0} != '.' AND $cont != 'img' AND $cont != 'mails' AND $cont != 'js' AND is_dir(_PS_MODULE_DIR_.$module.'/'.$cont))
  663. if ($files = @scandir(_PS_MODULE_DIR_.$module.'/'.$cont))
  664. $count += $this->findAndFillTranslations($files, $allfiles, 'prestashop', $module, _PS_MODULE_DIR_.$module.'/'.$cont.'/');
  665. if ($files = @scandir(_PS_MODULE_DIR_.$module.'/'))
  666. $count += $this->findAndFillTranslations($files, $allfiles, 'prestashop', $module);
  667. }
  668. if ($themes = scandir(_PS_ALL_THEMES_DIR_))
  669. foreach ($themes AS $theme)
  670. if ($theme{0} != '.' AND is_dir(_PS_ALL_THEMES_DIR_.$theme) AND file_exists(_PS_ALL_THEMES_DIR_.$theme.'/modules/'))
  671. {
  672. $modules = scandir(_PS_ALL_THEMES_DIR_.$theme.'/modules/');
  673. if ($modules)
  674. foreach ($modules AS $module)
  675. if ($module{0} != '.' AND is_dir(_PS_ALL_THEMES_DIR_.$theme.'/modules/'.$module))
  676. {
  677. @include_once(_PS_ALL_THEMES_DIR_.$theme.'/modules/'.$module.'/'.$lang.'.php');
  678. self::getModuleTranslations();
  679. $files = scandir(_PS_ALL_THEMES_DIR_.$theme.'/modules/'.$module.'/');
  680. if ($files)
  681. $count += $this->findAndFillTranslations($files, $allfiles, $theme, $module);
  682. }
  683. }
  684. echo '
  685. <h2>'.$this->l('Language').' : '.Tools::strtoupper($lang).'</h2>
  686. '.$this->l('Total expressions').' : <b>'.$count.'</b>. '.$this->l('Click the fieldset title to expand or close the fieldset.').'.<br /><br />
  687. <form method="post" action="'.$currentIndex.'&submitTranslationsModules=1&token='.$this->token.'" class="form">';
  688. $this->displayToggleButton();
  689. echo '<input type="hidden" name="lang" value="'.$lang.'" /><input type="submit" name="submitTranslationsModules" value="'.$this->l('Update translations').'" class="button" /><br /><br />';
  690. foreach ($allfiles AS $theme_name => $theme)
  691. foreach ($theme AS $module_name => $module)
  692. foreach ($module AS $template_name => $newLang)
  693. if (sizeof($newLang))
  694. {
  695. $countValues = array_count_values($newLang);
  696. $empty = isset($countValues['']) ? $countValues[''] : 0;
  697. echo '
  698. <fieldset><legend style="cursor : pointer" onclick="openCloseLayer(\''.$theme_name.'_'.$module_name.'_'.$template_name.'\')">'.$theme_name.' - '.$template_name.' - <font color="blue">'.sizeof($newLang).'</font> '.$this->l('expressions').' (<font color="red">'.$empty.'</font>)</legend>
  699. <div name="modules_div" id="'.$theme_name.'_'.$module_name.'_'.$template_name.'" style="display: '.($empty ? 'block' : 'none').';">
  700. <table cellpadding="2">';
  701. foreach ($newLang as $key => $value)
  702. {
  703. echo '<tr><td style="width: 40%">'.stripslashes($key).'</td><td>= ';
  704. if (strlen($key) < TEXTAREA_SIZED)
  705. echo '<input type="text" style="width: 450px" name="'.md5($module_name.'_'.$theme_name.'_'.$template_name.'_'.md5($key)).'" value="'.stripslashes(preg_replace('/"/', '\&quot;', stripslashes($value))).'" /></td></tr>';
  706. else
  707. echo '<textarea rows="'.intval(strlen($key) / TEXTAREA_SIZED).'" style="width: 450px" name="'.md5($module_name.'_'.$theme_name.'_'.$template_name.'_'.md5($key)).'">'.stripslashes(preg_replace('/"/', '\&quot;', stripslashes($value))).'</textarea></td></tr>';
  708. }
  709. echo '
  710. </table>
  711. </div>
  712. </fieldset><br />';
  713. }
  714. echo '<br /><input type="submit" name="submitTranslationsModules" value="'.$this->l('Update translations').'" class="button" /></form>';
  715. }
  716. }
  717. function displayFormPDF()
  718. {
  719. global $currentIndex;
  720. $lang = Tools::strtolower(Tools::getValue('lang'));
  721. $_LANG = array();
  722. if (!file_exists(_PS_TRANSLATIONS_DIR_.$lang))
  723. if (!mkdir(_PS_TRANSLATIONS_DIR_.$lang, 0700))
  724. die('Please create a "'.$iso.'" directory in '._PS_TRANSLATIONS_DIR_);
  725. if (!file_exists(_PS_TRANSLATIONS_DIR_.$lang.'/pdf.php'))
  726. if (!file_put_contents(_PS_TRANSLATIONS_DIR_.$lang.'/pdf.php', "<?php\n\nglobal \$_LANGPDF;\n\$_LANGPDF = array();\n\n?>"))
  727. die('Please create a "'.Tools::strtolower($lang).'.php" file in '.realpath(PS_ADMIN_DIR.'/'));
  728. unset($_LANGPDF);
  729. @include(_PS_TRANSLATIONS_DIR_.$lang.'/pdf.php');
  730. $files = array();
  731. $count = 0;
  732. $tab = 'PDF_invoice';
  733. $pdf = _PS_CLASS_DIR_.'PDF.php';
  734. $newLang = array();
  735. $fd = fopen($pdf, 'r');
  736. $content = fread($fd, filesize($pdf));
  737. fclose($fd);
  738. $regex = '/self::l\(\''._PS_TRANS_PATTERN_.'\'[\)|\,]/U';
  739. preg_match_all($regex, $content, $matches);
  740. foreach($matches[1] as $key)
  741. $tabsArray[$tab][$key] = stripslashes(key_exists($tab.md5(addslashes($key)), $_LANGPDF) ? html_entity_decode($_LANGPDF[$tab.md5(addslashes($key))], ENT_COMPAT, 'UTF-8') : '');
  742. $count += isset($tabsArray[$tab]) ? sizeof($tabsArray[$tab]) : 0;
  743. echo '
  744. <h2>'.$this->l('Language').' : '.Tools::strtoupper($lang).'</h2>
  745. '.$this->l('Expressions to translate').' : <b>'.$count.'</b>. '.$this->l('Click on the titles to open fieldsets').'.<br /><br />
  746. <form method="post" action="'.$currentIndex.'&submitTranslationsPDF=1&token='.$this->token.'" class="form">
  747. <script type="text/javascript">
  748. var openAll = \''.html_entity_decode($this->l('Expand all fieldsets'), ENT_NOQUOTES, 'UTF-8').'\';
  749. var closeAll = \''.html_entity_decode($this->l('Close all fieldsets'), ENT_NOQUOTES, 'UTF-8').'\';
  750. </script>
  751. <input type="hidden" name="lang" value="'.$lang.'" />
  752. <input type="button" class="button" id="buttonall" onclick="openCloseAllDiv(\'pdf_div\', this.value == openAll); toggleElemValue(this.id, openAll, closeAll);" />
  753. <script type="text/javascript">
  754. toggleElemValue(\'buttonall\', openAll, closeAll);
  755. </script>';
  756. echo '<input type="submit" name="submitTranslationsPDF" value="'.$this->l('Update translations').'" class="button" /><br /><br />';
  757. foreach ($tabsArray as $k => $newLang)
  758. if (sizeof($newLang))
  759. {
  760. $countValues = array_count_values($newLang);
  761. $empty = isset($countValues['']) ? $countValues[''] : 0;
  762. echo '
  763. <fieldset style="width: 700px"><legend style="cursor : pointer" onclick="openCloseLayer(\''.$k.'\')">'.$k.' - <font color="blue">'.sizeof($newLang).'</font> '.$this->l('expressions').' (<font color="red">'.$empty.'</font>)</legend>
  764. <div name="pdf_div" id="'.$k.'" style="display: '.($empty ? 'block' : 'none').';">
  765. <table cellpadding="2">';
  766. foreach ($newLang as $key => $value)
  767. {
  768. echo '
  769. <tr>
  770. <td>'.stripslashes($key).'</td>
  771. <td style="width: 280px">
  772. = <input type="text" name="'.$k.md5($key).'" value="'.stripslashes(preg_replace('/"/', '\&quot;', $value)).'" style="width: 250px">
  773. </td>
  774. </tr>';
  775. }
  776. echo '
  777. </table>
  778. </div>
  779. </fieldset><br />';
  780. }
  781. echo '<br /><input type="submit" name="submitTranslationsPDF" value="'.$this->l('Update translations').'" class="button" /></form>';
  782. }
  783. /**
  784. * Return an array with themes and thumbnails
  785. *
  786. * @return array
  787. */
  788. static public function getThemesList()
  789. {
  790. $dir = opendir(_PS_ALL_THEMES_DIR_);
  791. while ($folder = readdir($dir))
  792. if ($folder != '.' AND $folder != '..' AND file_exists(_PS_ALL_THEMES_DIR_.'/'.$folder.'/preview.jpg'))
  793. $themes[$folder]['name'] = $folder;
  794. closedir($dir);
  795. return isset($themes) ? $themes : array();
  796. }
  797. }
  798. ?>