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

/admin444/tabs/AdminTranslations.php

http://marocmall.googlecode.com/
PHP | 1039 lines | 940 code | 74 blank | 25 comment | 145 complexity | d2cb0bdc50ad0c52c629805d636fb923 MD5 | raw file
Possible License(s): LGPL-2.1
  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.3
  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 checkAndAddMailsFiles ($iso_code, $files_list)
  103. {
  104. $mails = scandir(_PS_MAIL_DIR_.'en/');
  105. $mails_new_lang = array();
  106. foreach ($files_list as $file)
  107. {
  108. if (preg_match('#^mails\/([a-z0-9]+)\/#Ui', $file['filename'], $matches))
  109. {
  110. $slash_pos = strrpos($file['filename'], '/');
  111. $mails_new_lang[] = substr($file['filename'], -(strlen($file['filename'])-$slash_pos-1));
  112. }
  113. }
  114. $arr_mails_needed = array_diff($mails, $mails_new_lang);
  115. foreach ($arr_mails_needed as $mail_to_add)
  116. {
  117. if ($mail_to_add !== '.' && $mail_to_add !== '..' && $mail_to_add !== '.svn')
  118. {
  119. @copy(_PS_MAIL_DIR_.'en/'.$mail_to_add, _PS_MAIL_DIR_.$iso_code.'/'.$mail_to_add);
  120. }
  121. }
  122. }
  123. public function submitImportLang()
  124. {
  125. global $currentIndex;
  126. if (!isset($_FILES['file']['tmp_name']) OR !$_FILES['file']['tmp_name'])
  127. $this->_errors[] = Tools::displayError('no file selected');
  128. else
  129. {
  130. $gz = new Archive_Tar($_FILES['file']['tmp_name'], true);
  131. $iso_code = str_replace('.gzip', '', $_FILES['file']['name']);
  132. $files_list = $gz->listContent();
  133. if ($gz->extract(_PS_TRANSLATIONS_DIR_.'../', false))
  134. {
  135. $this->checkAndAddMailsFiles($iso_code, $files_list);
  136. if(preg_match('/^[a-zA-Z]{2,3}[\.gzip]{5}$/', $_FILES['file']['name']))
  137. {
  138. $iso_code = str_replace('.gzip', '', $_FILES['file']['name']);
  139. if(!$this->_checkAndAddLangage($iso_code))
  140. $conf = 20;
  141. }
  142. Tools::redirectAdmin($currentIndex.'&conf='.(isset($conf) ? $conf : '15').'&token='.$this->token);
  143. }
  144. $this->_errors[] = Tools::displayError('archive cannot be extracted');
  145. }
  146. }
  147. public function findAndWriteTranslationsIntoFile($filename, $files, $themeName, $moduleName, $dir = false)
  148. {
  149. static $_cacheFile = array();
  150. if (!isset($_cacheFile[$filename]))
  151. {
  152. $_cacheFile[$filename] = true;
  153. if (!$fd = fopen($filename, 'w'))
  154. die ($this->l('Cannot write the theme\'s language file ').'('.$filename.')'.$this->l('. Please check write permissions.'));
  155. fwrite($fd, "<?php\n\nglobal \$_MODULE;\n\$_MODULE = array();\n");
  156. fclose($fd);
  157. }
  158. $tplRegex = '/\{l s=\''._PS_TRANS_PATTERN_.'\'( mod=\'.+\')?( js=1)?\}/U';
  159. $phpRegex = '/->l\(\''._PS_TRANS_PATTERN_.'\'(, \'(.+)\')?(, (.+))?\)/U';
  160. if (!$dir)
  161. $dir = ($themeName == 'prestashop' ? _PS_MODULE_DIR_.$moduleName.'/' : _PS_ALL_THEMES_DIR_.$themeName.'/modules/'.$moduleName.'/');
  162. if (!$writeFd = fopen($filename, 'a+'))
  163. die ($this->l('Cannot write the theme\'s language file ').'('.$filename.')'.$this->l('. Please check write permissions.'));
  164. else
  165. {
  166. $_tmp = array();
  167. foreach ($files AS $templateFile)
  168. {
  169. if ((preg_match('/^(.*).tpl$/', $templateFile) OR ($themeName == 'prestashop' AND preg_match('/^(.*).php$/', $templateFile))) AND file_exists($tpl = $dir.$templateFile))
  170. {
  171. /* Get translations key */
  172. $readFd = fopen($tpl, 'r');
  173. $content = (filesize($tpl) ? fread($readFd, filesize($tpl)) : '');
  174. preg_match_all(substr($templateFile, -4) == '.tpl' ? $tplRegex : $phpRegex, $content, $matches);
  175. fclose($readFd);
  176. /* Write each translation on its module file */
  177. $templateName = substr(basename($templateFile), 0, -4);
  178. foreach ($matches[1] as $key)
  179. {
  180. $postKey = md5($moduleName.'_'.$themeName.'_'.$templateName.'_'.md5($key));
  181. $pattern = '\'<{'.$moduleName.'}'.$themeName.'>'.$templateName.'_'.md5($key).'\'';
  182. if (array_key_exists($postKey, $_POST) AND !empty($_POST[$postKey]) AND !array_key_exists($pattern, $_tmp))
  183. {
  184. $_tmp[$pattern] = true;
  185. fwrite($writeFd, '$_MODULE['.$pattern.'] = \''.pSQL($_POST[$postKey]).'\';'."\n");
  186. }
  187. }
  188. }
  189. }
  190. fclose($writeFd);
  191. }
  192. }
  193. public function findAndFillTranslations($files, &$translationsArray, $themeName, $moduleName, $dir = false)
  194. {
  195. global $_MODULES;
  196. $tplRegex = '/\{l s=\''._PS_TRANS_PATTERN_.'\'( mod=\'.+\')?( js=1)?\}/U';
  197. $phpRegex = '/->l\(\''._PS_TRANS_PATTERN_.'\'(, \'(.+)\')?(, (.+))?\)/U';
  198. $count = 0;
  199. if (!$dir)
  200. $dir = ($themeName == 'prestashop' ? _PS_MODULE_DIR_.$moduleName.'/' : _PS_ALL_THEMES_DIR_.$themeName.'/modules/'.$moduleName.'/');
  201. foreach ($files AS $templateFile)
  202. if ((preg_match('/^(.*).tpl$/', $templateFile) OR ($themeName == 'prestashop' AND preg_match('/^(.*).php$/', $templateFile))) AND file_exists($tpl = $dir.$templateFile))
  203. {
  204. /* Get translations key */
  205. $readFd = fopen($tpl, 'r');
  206. $content = (filesize($tpl) ? fread($readFd, filesize($tpl)) : '');
  207. preg_match_all(substr($templateFile, -4) == '.tpl' ? $tplRegex : $phpRegex, $content, $matches);
  208. fclose($readFd);
  209. /* Write each translation on its module file */
  210. $templateName = substr(basename($templateFile), 0, -4);
  211. foreach ($matches[1] as $key)
  212. {
  213. $moduleKey = '<{'.$moduleName.'}'.$themeName.'>'.$templateName.'_'.md5($key);
  214. $translationsArray[$themeName][$moduleName][$templateName][$key] = key_exists($moduleKey, $_MODULES) ? html_entity_decode($_MODULES[$moduleKey], ENT_COMPAT, 'UTF-8') : '';
  215. }
  216. $count += isset($translationsArray[$themeName][$moduleName][$templateName]) ? sizeof($translationsArray[$themeName][$moduleName][$templateName]) : 0;
  217. }
  218. return ($count);
  219. }
  220. public function postProcess()
  221. {
  222. global $currentIndex;
  223. if (Tools::isSubmit('submitCopyLang'))
  224. {
  225. if ($this->tabAccess['add'] === '1')
  226. $this->submitCopyLang();
  227. else
  228. $this->_errors[] = Tools::displayError('You do not have permission to add anything here.');
  229. }
  230. elseif (Tools::isSubmit('submitExport'))
  231. {
  232. if ($this->tabAccess['add'] === '1')
  233. $this->submitExportLang();
  234. else
  235. $this->_errors[] = Tools::displayError('You do not have permission to add anything here.');
  236. }
  237. elseif (Tools::isSubmit('submitImport'))
  238. {
  239. if ($this->tabAccess['add'] === '1')
  240. $this->submitImportLang();
  241. else
  242. $this->_errors[] = Tools::displayError('You do not have permission to add anything here.');
  243. }
  244. elseif (Tools::isSubmit('submitTranslationsFront'))
  245. {
  246. if ($this->tabAccess['edit'] === '1')
  247. {
  248. if (!Validate::isLanguageIsoCode(Tools::strtolower(Tools::getValue('lang'))))
  249. die(Tools::displayError());
  250. $this->writeTranslationFile('Front', _PS_THEME_DIR_.'lang/'.Tools::strtolower(Tools::getValue('lang')).'.php');
  251. }
  252. else
  253. $this->_errors[] = Tools::displayError('You do not have permission to edit anything here.');
  254. }
  255. elseif (Tools::isSubmit('submitTranslationsPDF'))
  256. {
  257. if ($this->tabAccess['edit'] === '1')
  258. {
  259. if (!Validate::isLanguageIsoCode(Tools::strtolower(Tools::getValue('lang'))))
  260. die(Tools::displayError());
  261. $this->writeTranslationFile('PDF', _PS_TRANSLATIONS_DIR_.Tools::strtolower(Tools::getValue('lang')).'/pdf.php', 'PDF');
  262. }
  263. else
  264. $this->_errors[] = Tools::displayError('You do not have permission to edit anything here.');
  265. }
  266. elseif (Tools::isSubmit('submitTranslationsBack'))
  267. {
  268. if ($this->tabAccess['edit'] === '1')
  269. {
  270. if (!Validate::isLanguageIsoCode(Tools::strtolower(Tools::getValue('lang'))))
  271. die(Tools::displayError());
  272. $this->writeTranslationFile('Back', _PS_TRANSLATIONS_DIR_.Tools::strtolower(Tools::getValue('lang')).'/admin.php', 'ADM');
  273. }
  274. else
  275. $this->_errors[] = Tools::displayError('You do not have permission to edit anything here.');
  276. }
  277. elseif (Tools::isSubmit('submitTranslationsErrors'))
  278. {
  279. if ($this->tabAccess['edit'] === '1')
  280. {
  281. if (!Validate::isLanguageIsoCode(Tools::strtolower(Tools::getValue('lang'))))
  282. die(Tools::displayError());
  283. $this->writeTranslationFile('Errors', _PS_TRANSLATIONS_DIR_.Tools::strtolower(Tools::getValue('lang')).'/errors.php', false, 'ERRORS');
  284. }
  285. else
  286. $this->_errors[] = Tools::displayError('You do not have permission to edit anything here.');
  287. }
  288. elseif (Tools::isSubmit('submitTranslationsFields'))
  289. {
  290. if ($this->tabAccess['edit'] === '1')
  291. {
  292. if (!Validate::isLanguageIsoCode(Tools::strtolower(Tools::getValue('lang'))))
  293. die(Tools::displayError());
  294. $this->writeTranslationFile('Fields', _PS_TRANSLATIONS_DIR_.Tools::strtolower(Tools::getValue('lang')).'/fields.php', false, 'FIELDS');
  295. }
  296. else
  297. $this->_errors[] = Tools::displayError('You do not have permission to edit anything here.');
  298. }
  299. elseif (Tools::isSubmit('submitTranslationsModules'))
  300. {
  301. if ($this->tabAccess['edit'] === '1')
  302. {
  303. $lang = Tools::strtolower($_POST['lang']);
  304. if (!Validate::isLanguageIsoCode($lang))
  305. die(Tools::displayError());
  306. if (!$modules = scandir(_PS_MODULE_DIR_))
  307. $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.'));
  308. else
  309. {
  310. foreach ($modules AS $module)
  311. if ($module{0} != '.' AND is_dir(_PS_MODULE_DIR_.$module))
  312. {
  313. $filename = _PS_MODULE_DIR_.$module.'/'.$lang.'.php';
  314. $content = scandir(_PS_MODULE_DIR_.$module);
  315. foreach ($content as $cont)
  316. if ($cont{0} != '.' AND $cont != 'img' AND $cont != 'mails' AND $cont != 'js' AND is_dir(_PS_MODULE_DIR_.$module.'/'.$cont))
  317. if ($files = @scandir(_PS_MODULE_DIR_.$module.'/'.$cont))
  318. $this->findAndWriteTranslationsIntoFile($filename, $files, 'prestashop', $module, _PS_MODULE_DIR_.$module.'/'.$cont.'/');
  319. if ($files = @scandir(_PS_MODULE_DIR_.$module.'/'))
  320. $this->findAndWriteTranslationsIntoFile($filename, $files, 'prestashop', $module);
  321. }
  322. }
  323. /* Search language tags (eg {l s='to translate'}) */
  324. if ($themes = scandir(_PS_ALL_THEMES_DIR_))
  325. foreach ($themes AS $theme)
  326. if ($theme{0} != '.' AND is_dir(_PS_ALL_THEMES_DIR_.$theme) AND file_exists(_PS_ALL_THEMES_DIR_.$theme.'/modules/'))
  327. {
  328. if ($modules = scandir(_PS_ALL_THEMES_DIR_.$theme.'/modules/'))
  329. foreach ($modules AS $module)
  330. if ($module{0} != '.' AND is_dir(_PS_ALL_THEMES_DIR_.$theme.'/modules/'.$module) AND $files = scandir(_PS_ALL_THEMES_DIR_.$theme.'/modules/'.$module.'/'))
  331. $this->findAndWriteTranslationsIntoFile(_PS_ALL_THEMES_DIR_.$theme.'/modules/'.$module.'/'.$lang.'.php', $files, $theme, $module);
  332. }
  333. Tools::redirectAdmin($currentIndex.'&conf=4&token='.$this->token);
  334. }
  335. else
  336. $this->_errors[] = Tools::displayError('You do not have permission to edit anything here.');
  337. }
  338. }
  339. public function display()
  340. {
  341. global $currentIndex, $cookie;
  342. $translations = array(
  343. 'front' => $this->l('Front Office translations'),
  344. 'back' => $this->l('Back Office translations'),
  345. 'errors' => $this->l('Error message translations'),
  346. 'fields' => $this->l('Field name translations'),
  347. 'modules' => $this->l('Module translations'),
  348. 'pdf' => $this->l('PDF translations'),
  349. );
  350. if ($type = Tools::getValue('type'))
  351. $this->{'displayForm'.$type}(Tools::strtolower(Tools::getValue('lang')));
  352. else
  353. {
  354. $languages = Language::getLanguages();
  355. echo '<fieldset class="width2"><legend><img src="../img/admin/translation.gif" />'.$this->l('Modify translations').'</legend>'.
  356. $this->l('Here you can modify translations for every text input on PrestaShop.').'<br />'.
  357. $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 />
  358. <form method="get" action="index.php" id="typeTranslationForm">
  359. <input type="hidden" name="tab" value="AdminTranslations" />
  360. <input type="hidden" name="lang" id="translation_lang" value="0" />
  361. <select name="type" style="float:left; margin-right:10px;">';
  362. foreach ($translations as $key => $translation)
  363. echo '<option value="'.$key.'">'.$translation.'&nbsp;</option>';
  364. echo '</select>';
  365. foreach ($languages as $language)
  366. echo '<a href="javascript:chooseTypeTranslation(\''.$language['iso_code'].'\')">
  367. <img src="'._THEME_LANG_DIR_.$language['id_lang'].'.jpg" alt="'.$language['iso_code'].'" title="'.$language['iso_code'].'" />
  368. </a>';
  369. echo '<input type="hidden" name="token" value="'.$this->token.'" /></form></fieldset>
  370. <br /><br /><h2>'.$this->l('Translation exchange').'</h2>
  371. <form action="'.$currentIndex.'&token='.$this->token.'" method="post" enctype="multipart/form-data">
  372. <fieldset class="width2"><legend><img src="../img/admin/import.gif" />'.$this->l('Import a language pack').'</legend>
  373. <p>'.$this->l('Import data from file (language pack).').'<br />'.
  374. $this->l('If the name format is: isocode.gzip (eg fr.gzip) and the language corresponding to this package does not exist, it will automatically create.').'<br />'.
  375. $this->l('Be careful, as it will replace all existing data for the destination language!').'<br />'.
  376. $this->l('Browse your computer for the language file to be imported:').'</p>
  377. <div style="float:left;">
  378. <p>
  379. <div style="width:75px; font-weight:bold; float:left;">'.$this->l('From:').'</div>
  380. <input type="file" name="file" />
  381. </p>
  382. </div>
  383. <div style="float:left;">
  384. <input type="submit" value="'.$this->l('Import').'" name="submitImport" class="button" style="margin:10px 0px 0px 25px;" />
  385. </div>
  386. </fieldset>
  387. </form>
  388. <br /><br />
  389. <form action="'.$currentIndex.'&token='.$this->token.'" method="post" enctype="multipart/form-data">
  390. <fieldset class="width2"><legend><img src="../img/admin/export.gif" />'.$this->l('Export a language').'</legend>
  391. <p>'.$this->l('Export data from one language to a file (language pack).').'<br />'.
  392. $this->l('Choose the theme from which you want to export translations.').'<br />
  393. <select name="iso_code" style="margin-top:10px;">';
  394. foreach ($languages as $language)
  395. echo '<option value="'.$language['iso_code'].'">'.$language['name'].'</option>';
  396. echo '
  397. </select>
  398. &nbsp;&nbsp;&nbsp;
  399. <select name="theme" style="margin-top:10px;">';
  400. $themes = self::getThemesList();
  401. foreach ($themes as $theme)
  402. echo '<option value="'.$theme['name'].'">'.$theme['name'].'</option>';
  403. echo '
  404. </select>&nbsp;&nbsp;
  405. <input type="submit" class="button" name="submitExport" value="'.$this->l('Export').'" />
  406. </fieldset>
  407. </form>
  408. <br /><br />';
  409. $allLanguages = Language::getLanguages(false);
  410. echo '
  411. <form action="'.$currentIndex.'&token='.$this->token.'" method="post">
  412. <fieldset class="width2"><legend><img src="../img/admin/copy_files.gif" />'.$this->l('Copy').'</legend>
  413. <p>'.$this->l('Copies data from one language to another.').'<br />'.
  414. $this->l('Be careful, as it will replace all existing data for the destination language!').'<br />'.
  415. $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>
  416. <div style="float:left;">
  417. <p>
  418. <div style="width:75px; font-weight:bold; float:left;">'.$this->l('From:').'</div>
  419. <select name="fromLang">';
  420. foreach ($languages AS $language)
  421. echo '<option value="'.$language['iso_code'].'">'.$language['name'].'</option>';
  422. echo '
  423. </select>
  424. &nbsp;&nbsp;&nbsp;
  425. <select name="fromTheme">';
  426. $themes = self::getThemesList();
  427. foreach ($themes as $theme)
  428. echo '<option value="'.$theme['name'].'">'.$theme['name'].'</option>';
  429. echo '
  430. </select> <span style="font-style: bold; color: red;">*</span>
  431. </p>
  432. <p>
  433. <div style="width:75px; font-weight:bold; float:left;">'.$this->l('To:').'</div>
  434. <select name="toLang">';
  435. foreach ($allLanguages AS $language)
  436. echo '<option value="'.$language['iso_code'].'">'.$language['name'].'</option>';
  437. echo '
  438. </select>
  439. &nbsp;&nbsp;&nbsp;
  440. <select name="toTheme">';
  441. $themes = self::getThemesList();
  442. foreach ($themes as $theme)
  443. echo '<option value="'.$theme['name'].'">'.$theme['name'].'</option>';
  444. echo '
  445. </select>
  446. </p>
  447. </div>
  448. <div style="float:left;">
  449. <input type="submit" value="'.$this->l(' Copy ').'" name="submitCopyLang" class="button" style="margin:25px 0px 0px 25px;" />
  450. </div>
  451. <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>
  452. </fieldset>
  453. </form>';
  454. }
  455. }
  456. function fileExists($dir, $file, $var)
  457. {
  458. ${$var} = array();
  459. if (!file_exists($dir))
  460. if (!mkdir($dir, 0700))
  461. die('Please create the directory '.$dir);
  462. if (!file_exists($dir.'/'.$file))
  463. if (!file_put_contents($dir.'/'.$file, "<?php\n\nglobal \$".$var.";\n\$".$var." = array();\n\n?>"))
  464. die('Please create a "'.$file.'" file in '.$dir);
  465. if (!is_writable($dir.'/'.$file))
  466. $this->displayWarning(Tools::displayError('This file has to be writable:').' '.$dir.'/'.$file);
  467. include($dir.'/'.$file);
  468. return ${$var};
  469. }
  470. function displayToggleButton($closed = false)
  471. {
  472. echo '
  473. <script type="text/javascript">
  474. var openAll = \''.html_entity_decode($this->l('Expand all fieldsets'), ENT_NOQUOTES, 'UTF-8').'\';
  475. var closeAll = \''.html_entity_decode($this->l('Close all fieldsets'), ENT_NOQUOTES, 'UTF-8').'\';
  476. </script>
  477. <input type="button" class="button" id="buttonall" onclick="openCloseAllDiv(\''.$_GET['type'].'_div\', this.value == openAll); toggleElemValue(this.id, openAll, closeAll);" />
  478. <script type="text/javascript">toggleElemValue(\'buttonall\', '.($closed ? 'openAll' : 'closeAll').', '.($closed ? 'closeAll' : 'openAll').');</script>';
  479. }
  480. public function displayLimitPostWarning($count)
  481. {
  482. if (ini_get('suhosin.post.max_vars') AND ini_get('suhosin.post.max_vars') < $count)
  483. {
  484. ini_set('suhosin.post.max_vars', $count + 100);
  485. if (ini_get('suhosin.post.max_vars') < $count)
  486. echo '<div class="warning">'.$this->l('Warning, your hosting provider is using the suhosin patch for PHP, and is limiting the maximum fields which could be posted to')
  487. .' <b>'.ini_get('suhosin.post.max_vars').'</b>'.$this->l('. As a result, your translations will be partially saved. Please ask your hosting provider to increase this limit to')
  488. .' <u><b>'.((int)$count + 100).' '.$this->l('at least.').'</b></u></div>';
  489. }
  490. }
  491. function displayFormfront($lang)
  492. {
  493. global $currentIndex;
  494. $_LANG = $this->fileExists(_PS_THEME_DIR_.'lang', Tools::strtolower($lang).'.php', '_LANG');
  495. /* List templates to parse */
  496. $templates = scandir(_PS_THEME_DIR_);
  497. $count = 0;
  498. $files = array();
  499. foreach ($templates AS $template)
  500. if (preg_match('/^(.*).tpl$/', $template) AND file_exists($tpl = _PS_THEME_DIR_.$template))
  501. {
  502. $template = substr(basename($template), 0, -4);
  503. $newLang = array();
  504. $fd = fopen($tpl, 'r');
  505. $content = fread($fd, filesize($tpl));
  506. /* Search language tags (eg {l s='to translate'}) */
  507. $regex = '/\{l s=\''._PS_TRANS_PATTERN_.'\'( js=1)?\}/U';
  508. preg_match_all($regex, $content, $matches);
  509. /* Get string translation */
  510. foreach($matches[1] as $key)
  511. {
  512. $key2 = $template.'_'.md5($key);
  513. $newLang[$key] = (key_exists($key2, $_LANG)) ? html_entity_decode($_LANG[$key2], ENT_COMPAT, 'UTF-8') : '';
  514. }
  515. $files[$template] = $newLang;
  516. $count += sizeof($newLang);
  517. }
  518. echo '
  519. <h2>'.$this->l('Language').' : '.Tools::strtoupper($lang).'</h2>
  520. '.$this->l('Total expressions').' : <b>'.$count.'</b>. '.$this->l('Click the fieldset title to expand or close the fieldset.').'.<br /><br />';
  521. $this->displayLimitPostWarning($count);
  522. echo '
  523. <form method="post" action="'.$currentIndex.'&submitTranslationsFront=1&token='.$this->token.'" class="form">';
  524. $this->displayToggleButton(sizeof($_LANG) >= $count);
  525. echo '<input type="hidden" name="lang" value="'.$lang.'" /><input type="submit" name="submitTranslationsFront" value="'.$this->l('Update translations').'" class="button" /><br /><br />';
  526. foreach ($files as $k => $newLang)
  527. if (sizeof($newLang))
  528. {
  529. $countValues = array_count_values($newLang);
  530. $empty = isset($countValues['']) ? $countValues[''] : 0;
  531. echo '
  532. <fieldset><legend style="cursor : pointer" onclick="openCloseLayer(\''.$k.'\')">'.$k.' - <font color="blue">'.sizeof($newLang).'</font> '.$this->l('expressions').' (<font color="red">'.$empty.'</font>)</legend>
  533. <div name="front_div" id="'.$k.'" style="display: '.($empty ? 'block' : 'none').';">
  534. <table cellpadding="2">';
  535. foreach ($newLang as $key => $value)
  536. {
  537. echo '<tr><td style="width: 40%">'.stripslashes($key).'</td><td>= ';
  538. if (strlen($key) < TEXTAREA_SIZED)
  539. echo '<input type="text" style="width: 450px" name="'.$k.'_'.md5($key).'" value="'.stripslashes(preg_replace('/"/', '\&quot;', stripslashes($value))).'" /></td></tr>';
  540. else
  541. echo '<textarea rows="'.intval(strlen($key) / TEXTAREA_SIZED).'" style="width: 450px" name="'.$k.'_'.md5($key).'">'.stripslashes(preg_replace('/"/', '\&quot;', stripslashes($value))).'</textarea></td></tr>';
  542. }
  543. echo '
  544. </table>
  545. </div>
  546. </fieldset><br />';
  547. }
  548. echo '<br /><input type="submit" name="submitTranslationsFront" value="'.$this->l('Update translations').'" class="button" /></form>';
  549. }
  550. function displayFormback($lang)
  551. {
  552. global $currentIndex;
  553. $_LANGADM = $this->fileExists(_PS_TRANSLATIONS_DIR_.$lang, 'admin.php', '_LANGADM');
  554. /* List templates to parse */
  555. $count = 0;
  556. $tabs = scandir(PS_ADMIN_DIR.'/tabs');
  557. $tabs[] = '../../classes/AdminTab.php';
  558. $files = array();
  559. foreach ($tabs AS $tab)
  560. if (preg_match('/^(.*)\.php$/', $tab) AND file_exists($tpl = PS_ADMIN_DIR.'/tabs/'.$tab))
  561. {
  562. $tab = basename(substr($tab, 0, -4));
  563. $fd = fopen($tpl, 'r');
  564. $content = fread($fd, filesize($tpl));
  565. fclose($fd);
  566. $regex = '/this->l\(\''._PS_TRANS_PATTERN_.'\'[\)|\,]/U';
  567. preg_match_all($regex, $content, $matches);
  568. foreach ($matches[1] as $key)
  569. $tabsArray[$tab][$key] = stripslashes(key_exists($tab.md5($key), $_LANGADM) ? html_entity_decode($_LANGADM[$tab.md5($key)], ENT_COMPAT, 'UTF-8') : '');
  570. $count += isset($tabsArray[$tab]) ? sizeof($tabsArray[$tab]) : 0;
  571. }
  572. foreach (array('header.inc', 'index', 'login', 'password') as $tab)
  573. {
  574. $tab = PS_ADMIN_DIR.'/'.$tab.'.php';
  575. $fd = fopen($tab, 'r');
  576. $content = fread($fd, filesize($tab));
  577. fclose($fd);
  578. $regex = '/translate\(\''._PS_TRANS_PATTERN_.'\'\)/U';
  579. preg_match_all($regex, $content, $matches);
  580. foreach ($matches[1] as $key)
  581. $tabsArray['index'][$key] = stripslashes(key_exists('index'.md5($key), $_LANGADM) ? html_entity_decode($_LANGADM['index'.md5($key)], ENT_COMPAT, 'UTF-8') : '');
  582. $count += isset($tabsArray['index']) ? sizeof($tabsArray['index']) : 0;
  583. }
  584. echo '
  585. <h2>'.$this->l('Language').' : '.Tools::strtoupper($lang).'</h2>
  586. '.$this->l('Expressions to translate').' : <b>'.$count.'</b>. '.$this->l('Click on the titles to open fieldsets').'.<br /><br />';
  587. $this->displayLimitPostWarning($count);
  588. echo '
  589. <form method="post" action="'.$currentIndex.'&submitTranslationsBack=1&token='.$this->token.'" class="form">';
  590. $this->displayToggleButton();
  591. echo '<input type="hidden" name="lang" value="'.$lang.'" /><input type="submit" name="submitTranslationsBack" value="'.$this->l('Update translations').'" class="button" /><br /><br />';
  592. foreach ($tabsArray as $k => $newLang)
  593. if (sizeof($newLang))
  594. {
  595. $countValues = array_count_values($newLang);
  596. $empty = isset($countValues['']) ? $countValues[''] : 0;
  597. echo '
  598. <fieldset><legend style="cursor : pointer" onclick="openCloseLayer(\''.$k.'\')">'.$k.' - <font color="blue">'.sizeof($newLang).'</font> '.$this->l('expressions').' (<font color="red">'.$empty.'</font>)</legend>
  599. <div name="back_div" id="'.$k.'" style="display: '.($empty ? 'block' : 'none').';">
  600. <table cellpadding="2">';
  601. foreach ($newLang as $key => $value)
  602. {
  603. echo '<tr><td style="width: 40%">'.stripslashes($key).'</td><td>= ';
  604. if (strlen($key) < TEXTAREA_SIZED)
  605. echo '<input type="text" style="width: 450px" name="'.$k.md5($key).'" value="'.stripslashes(preg_replace('/"/', '\&quot;', $value)).'" /></td></tr>';
  606. else
  607. echo '<textarea rows="'.intval(strlen($key) / TEXTAREA_SIZED).'" style="width: 450px" name="'.$k.md5($key).'">'.stripslashes(preg_replace('/"/', '\&quot;', $value)).'</textarea></td></tr>';
  608. }
  609. echo '
  610. </table>
  611. </div>
  612. </fieldset><br />';
  613. }
  614. echo '<br /><input type="submit" name="submitTranslationsBack" value="'.$this->l('Update translations').'" class="button" /></form>';
  615. }
  616. function displayFormerrors($lang)
  617. {
  618. global $currentIndex;
  619. $_ERRORS = $this->fileExists(_PS_TRANSLATIONS_DIR_.$lang, 'errors.php', '_ERRORS');
  620. /* List files to parse */
  621. $stringToTranslate = array();
  622. $dirToParse = array(PS_ADMIN_DIR.'/../',
  623. PS_ADMIN_DIR.'/../classes/',
  624. PS_ADMIN_DIR.'/',
  625. PS_ADMIN_DIR.'/tabs/');
  626. if (!file_exists(_PS_MODULE_DIR_))
  627. die($this->displayWarning(Tools::displayError('Fatal error: Module directory is not here anymore ').'('._PS_MODULE_DIR_.')'));
  628. if (!is_writable(_PS_MODULE_DIR_))
  629. $this->displayWarning(Tools::displayError('The module directory must be writable'));
  630. if (!$modules = scandir(_PS_MODULE_DIR_))
  631. $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.'));
  632. else
  633. {
  634. $count = 0;
  635. foreach ($modules AS $module)
  636. if (is_dir(_PS_MODULE_DIR_.$module) && $module != '.' && $module != '..' && $module != '.svn' )
  637. $dirToParse[] = _PS_MODULE_DIR_.$module.'/';
  638. }
  639. foreach ($dirToParse AS $dir)
  640. foreach (scandir($dir) AS $file)
  641. if (preg_match('/.php$/', $file) AND file_exists($fn = $dir.$file) AND $file != 'index.php')
  642. {
  643. if (!filesize($fn))
  644. continue;
  645. preg_match_all('/Tools::displayError\(\''._PS_TRANS_PATTERN_.'\'(, true)?\)/U', fread(fopen($fn, 'r'), filesize($fn)), $matches);
  646. foreach($matches[1] as $key)
  647. $stringToTranslate[$key] = (key_exists(md5($key), $_ERRORS)) ? html_entity_decode($_ERRORS[md5($key)], ENT_COMPAT, 'UTF-8') : '';
  648. }
  649. $irow = 0;
  650. echo '<h2>'.$this->l('Language').' : '.Tools::strtoupper($lang).'</h2>'.$this->l('Errors to translate').' : <b>'.sizeof($stringToTranslate).'</b><br /><br />';
  651. $this->displayLimitPostWarning(sizeof($stringToTranslate));
  652. echo '
  653. <form method="post" action="'.$currentIndex.'&submitTranslationsErrors=1&lang='.$lang.'&token='.$this->token.'" class="form">
  654. <input type="submit" name="submitTranslationsErrors" value="'.$this->l('Update translations').'" class="button" /><br /><br />
  655. <table cellpadding="0" cellspacing="0" class="table">';
  656. ksort($stringToTranslate);
  657. foreach ($stringToTranslate as $key => $value)
  658. 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>';
  659. echo '</table><br /><input type="submit" name="submitTranslationsErrors" value="'.$this->l('Update translations').'" class="button" /></form>';
  660. }
  661. function displayFormfields($lang)
  662. {
  663. global $currentIndex;
  664. $_FIELDS = $this->fileExists(_PS_TRANSLATIONS_DIR_.$lang, 'fields.php', '_FIELDS');
  665. $classArray = array();
  666. $count = 0;
  667. foreach (scandir(_PS_CLASS_DIR_) AS $classFile)
  668. {
  669. if (!preg_match('/\.php$/', $classFile) OR $classFile == 'index.php')
  670. continue;
  671. include_once(_PS_CLASS_DIR_.$classFile);
  672. $className = substr($classFile, 0, -4);
  673. if (!class_exists($className))
  674. continue;
  675. if (!is_subclass_of($className, 'ObjectModel'))
  676. continue;
  677. $classArray[$className] = call_user_func(array($className, 'getValidationRules'), $className);
  678. if (isset($classArray[$className]['validate']))
  679. $count += sizeof($classArray[$className]['validate']);
  680. if (isset($classArray[$className]['validateLang']))
  681. $count += sizeof($classArray[$className]['validateLang']);
  682. }
  683. echo '
  684. <h2>'.$this->l('Language').' : '.Tools::strtoupper($lang).'</h2>
  685. '.$this->l('Fields to translate').' : <b>'.$count.'</b>. '.$this->l('Click on the titles to open fieldsets').'.<br /><br />';
  686. $this->displayLimitPostWarning($count);
  687. echo '
  688. <form method="post" action="'.$currentIndex.'&submitTranslationsFields=1&token='.$this->token.'" class="form">';
  689. $this->displayToggleButton();
  690. echo '<input type="hidden" name="lang" value="'.$lang.'" /><input type="submit" name="submitTranslationsFields" value="'.$this->l('Update translations').'" class="button" /><br /><br />';
  691. foreach ($classArray AS $className => $rules)
  692. {
  693. $translated = 0;
  694. $toTranslate = 0;
  695. if (isset($rules['validate']))
  696. foreach ($rules['validate'] AS $key => $value)
  697. (array_key_exists($className.'_'.md5($key), $_FIELDS)) ? ++$translated : ++$toTranslate;
  698. if (isset($rules['validateLang']))
  699. foreach ($rules['validateLang'] AS $key => $value)
  700. (array_key_exists($className.'_'.md5($key), $_FIELDS)) ? ++$translated : ++$toTranslate;
  701. echo '
  702. <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>
  703. <div name="fields_div" id="'.$className.'" style="display: '.($toTranslate ? 'block' : 'none').';">
  704. <table cellpadding="2">';
  705. if (isset($rules['validate']))
  706. foreach ($rules['validate'] AS $key => $value)
  707. 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>';
  708. if (isset($rules['validateLang']))
  709. foreach ($rules['validateLang'] AS $key => $value)
  710. 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>';
  711. echo '
  712. </table>
  713. </div>
  714. </fieldset><br />';
  715. }
  716. echo '<br /><input type="submit" name="submitTranslationsFields" value="'.$this->l('Update translations').'" class="button" /></form>';
  717. }
  718. function displayFormModules($lang)
  719. {
  720. global $currentIndex, $_MODULES;
  721. if (!file_exists(_PS_MODULE_DIR_))
  722. die($this->displayWarning(Tools::displayError('Fatal error: Module directory is not here anymore ').'('._PS_MODULE_DIR_.')'));
  723. if (!is_writable(_PS_MODULE_DIR_))
  724. $this->displayWarning(Tools::displayError('The module directory must be writable'));
  725. if (!$modules = scandir(_PS_MODULE_DIR_))
  726. $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.'));
  727. else
  728. {
  729. $allfiles = array();
  730. $count = 0;
  731. foreach ($modules AS $module)
  732. if ($module{0} != '.' AND is_dir(_PS_MODULE_DIR_.$module))
  733. {
  734. @include_once(_PS_MODULE_DIR_.$module.'/'.$lang.'.php');
  735. self::getModuleTranslations();
  736. $content = scandir(_PS_MODULE_DIR_.$module);
  737. foreach ($content as $cont)
  738. if ($cont{0} != '.' AND $cont != 'img' AND $cont != 'mails' AND $cont != 'js' AND is_dir(_PS_MODULE_DIR_.$module.'/'.$cont))
  739. if ($files = @scandir(_PS_MODULE_DIR_.$module.'/'.$cont))
  740. $count += $this->findAndFillTranslations($files, $allfiles, 'prestashop', $module, _PS_MODULE_DIR_.$module.'/'.$cont.'/');
  741. if ($files = @scandir(_PS_MODULE_DIR_.$module.'/'))
  742. $count += $this->findAndFillTranslations($files, $allfiles, 'prestashop', $module);
  743. }
  744. if ($themes = scandir(_PS_ALL_THEMES_DIR_))
  745. foreach ($themes AS $theme)
  746. if ($theme{0} != '.' AND is_dir(_PS_ALL_THEMES_DIR_.$theme) AND file_exists(_PS_ALL_THEMES_DIR_.$theme.'/modules/'))
  747. {
  748. $modules = scandir(_PS_ALL_THEMES_DIR_.$theme.'/modules/');
  749. if ($modules)
  750. foreach ($modules AS $module)
  751. if ($module{0} != '.' AND is_dir(_PS_ALL_THEMES_DIR_.$theme.'/modules/'.$module))
  752. {
  753. @include_once(_PS_ALL_THEMES_DIR_.$theme.'/modules/'.$module.'/'.$lang.'.php');
  754. self::getModuleTranslations();
  755. $files = scandir(_PS_ALL_THEMES_DIR_.$theme.'/modules/'.$module.'/');
  756. if ($files)
  757. $count += $this->findAndFillTranslations($files, $allfiles, $theme, $module);
  758. }
  759. }
  760. echo '
  761. <h2>'.$this->l('Language').' : '.Tools::strtoupper($lang).'</h2>
  762. '.$this->l('Total expressions').' : <b>'.$count.'</b>. '.$this->l('Click the fieldset title to expand or close the fieldset.').'.<br /><br />';
  763. $this->displayLimitPostWarning($count);
  764. echo '
  765. <form method="post" action="'.$currentIndex.'&submitTranslationsModules=1&token='.$this->token.'" class="form">';
  766. $this->displayToggleButton();
  767. echo '<input type="hidden" name="lang" value="'.$lang.'" /><input type="submit" name="submitTranslationsModules" value="'.$this->l('Update translations').'" class="button" /><br /><br />';
  768. foreach ($allfiles AS $theme_name => $theme)
  769. foreach ($theme AS $module_name => $module)
  770. foreach ($module AS $template_name => $newLang)
  771. if (sizeof($newLang))
  772. {
  773. $countValues = array_count_values($newLang);
  774. $empty = isset($countValues['']) ? $countValues[''] : 0;
  775. echo '
  776. <fieldset><legend style="cursor : pointer" onclick="openCloseLayer(\''.$theme_name.'_'.$module_name.'_'.$template_name.'\')">'.$module_name.' - '.$template_name.' - '.$theme_name.' - <font color="blue">'.sizeof($newLang).'</font> '.$this->l('expressions').' (<font color="red">'.$empty.'</font>)</legend>
  777. <div name="modules_div" id="'.$theme_name.'_'.$module_name.'_'.$template_name.'" style="display: '.($empty ? 'block' : 'none').';">
  778. <table cellpadding="2">';
  779. foreach ($newLang as $key => $value)
  780. {
  781. echo '<tr><td style="width: 40%">'.stripslashes($key).'</td><td>= ';
  782. if (strlen($key) < TEXTAREA_SIZED)
  783. 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>';
  784. else
  785. 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>';
  786. }
  787. echo '
  788. </table>
  789. </div>
  790. </fieldset><br />';
  791. }
  792. echo '<br /><input type="submit" name="submitTranslationsModules" value="'.$this->l('Update translations').'" class="button" /></form>';
  793. }
  794. }
  795. function displayFormPDF()
  796. {
  797. global $currentIndex;
  798. $lang = Tools::strtolower(Tools::getValue('lang'));
  799. $_LANG = array();
  800. if (!file_exists(_PS_TRANSLATIONS_DIR_.$lang))
  801. if (!mkdir(_PS_TRANSLATIONS_DIR_.$lang, 0700))
  802. die('Please create a "'.$iso.'" directory in '._PS_TRANSLATIONS_DIR_);
  803. if (!file_exists(_PS_TRANSLATIONS_DIR_.$lang.'/pdf.php'))
  804. if (!file_put_contents(_PS_TRANSLATIONS_DIR_.$lang.'/pdf.php', "<?php\n\nglobal \$_LANGPDF;\n\$_LANGPDF = array();\n\n?>"))
  805. die('Please create a "'.Tools::strtolower($lang).'.php" file in '.realpath(PS_ADMIN_DIR.'/'));
  806. unset($_LANGPDF);
  807. @include(_PS_TRANSLATIONS_DIR_.$lang.'/pdf.php');
  808. $files = array();
  809. $count = 0;
  810. $tab = 'PDF_invoice';
  811. $pdf = _PS_CLASS_DIR_.'PDF.php';
  812. $newLang = array();
  813. $fd = fopen($pdf, 'r');
  814. $content = fread($fd, filesize($pdf));
  815. fclose($fd);
  816. $regex = '/self::l\(\''._PS_TRANS_PATTERN_.'\'[\)|\,]/U';
  817. preg_match_all($regex, $content, $matches);
  818. foreach($matches[1] as $key)
  819. $tabsArray[$tab][$key] = stripslashes(key_exists($tab.md5(addslashes($key)), $_LANGPDF) ? html_entity_decode($_LANGPDF[$tab.md5(addslashes($key))], ENT_COMPAT, 'UTF-8') : '');
  820. $count += isset($tabsArray[$tab]) ? sizeof($tabsArray[$tab]) : 0;
  821. $closed = sizeof($_LANGPDF) >= $count;
  822. echo '
  823. <h2>'.$this->l('Language').' : '.Tools::strtoupper($lang).'</h2>
  824. '.$this->l('Expressions to translate').' : <b>'.$count.'</b>. '.$this->l('Click on the titles to open fieldsets').'.<br /><br />';
  825. $this->displayLimitPostWarning($count);
  826. echo '
  827. <form method="post" action="'.$currentIndex.'&submitTranslationsPDF=1&token='.$this->token.'" class="form">
  828. <script type="text/javascript">
  829. var openAll = \''.html_entity_decode($this->l('Expand all fieldsets'), ENT_NOQUOTES, 'UTF-8').'\';
  830. var closeAll = \''.html_entity_decode($this->l('Close all fieldsets'), ENT_NOQUOTES, 'UTF-8').'\';
  831. </script>
  832. <input type="hidden" name="lang" value="'.$lang.'" />
  833. <input type="button" class="button" id="buttonall" onclick="openCloseAllDiv(\'pdf_div\', this.value == openAll); toggleElemValue(this.id, openAll, closeAll);" />
  834. <script type="text/javascript">
  835. toggleElemValue(\'buttonall\', '.($closed ? 'openAll' : 'closeAll').', '.($closed ? 'closeAll' : 'openAll').');
  836. </script>';
  837. echo '<input type="submit" name="submitTranslationsPDF" value="'.$this->l('Update translations').'" class="button" /><br /><br />';
  838. foreach ($tabsArray as $k => $newLang)
  839. if (sizeof($newLang))
  840. {
  841. $countValues = array_count_values($newLang);
  842. $empty = isset($countValues['']) ? $countValues[''] : 0;
  843. echo '
  844. <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>
  845. <div name="pdf_div" id="'.$k.'" style="display: '.($empty ? 'block' : 'none').';">
  846. <table cellpadding="2">';
  847. foreach ($newLang as $key => $value)
  848. {
  849. echo '
  850. <tr>
  851. <td>'.stripslashes($key).'</td>
  852. <td style="width: 280px">
  853. = <input type="text" name="'.$k.md5($key).'" value="'.stripslashes(preg_replace('/"/', '\&quot;', $value)).'" style="width: 250px">
  854. </td>
  855. </tr>';
  856. }
  857. echo '
  858. </table>
  859. </div>
  860. </fieldset><br />';
  861. }
  862. echo '<br /><input type="submit" name="submitTranslationsPDF" value="'.$this->l('Update translations').'" class="button" /></form>';
  863. }
  864. /**
  865. * Return an array with themes and thumbnails
  866. *
  867. * @return array
  868. */
  869. static public function getThemesList()
  870. {
  871. $dir = opendir(_PS_ALL_THEMES_DIR_);
  872. while ($folder = readdir($dir))
  873. if ($folder != '.' AND $folder != '..' AND file_exists(_PS_ALL_THEMES_DIR_.'/'.$folder.'/preview.jpg'))
  874. $themes[$folder]['name'] = $folder;
  875. closedir($dir);
  876. return isset($themes) ? $themes : array();
  877. }
  878. private function _copyNoneFlag($id)
  879. {
  880. copy(dirname(__FILE__).'/../../img/l/none.jpg', dirname(__FILE__).'/../../img/l/'.$id.'.jpg');
  881. }
  882. private function _checkAndAddLangage($iso_code)
  883. {
  884. $result = Db::getInstance()->getValue('
  885. SELECT COUNT(`id_lang`) AS total
  886. FROM `'._DB_PREFIX_.'lang`
  887. WHERE `iso_code` = \''.pSQL($iso_code).'\'
  888. ');
  889. if ($result)
  890. return true;
  891. else
  892. {
  893. if(@fsockopen('www.prestashop.com', 80))
  894. {
  895. $lang_packs = unserialize(@file_get_contents('http://www.prestashop.com/rss/lang_exists.php'));
  896. $lang = new Language();
  897. $lang->iso_code = $iso_code;
  898. $lang->active = true;
  899. if ($lang_packs)
  900. {
  901. foreach($lang_packs AS $lang_pack)
  902. if ($lang_pack['iso_code'] == $iso_code)
  903. $lang->name = $lang_pack['name'];
  904. }
  905. if (!$lang->name)
  906. return false;
  907. if (!$lang->add())
  908. return false;
  909. $insert_id = Db::getInstance()->getValue('
  910. SELECT id_lang
  911. FROM `'._DB_PREFIX_.'lang`
  912. WHERE `iso_code` = \''.pSQL($iso_code).'\'
  913. AND `name` = \''.pSQL($lang->name).'\'
  914. ');
  915. if ($lang_packs)
  916. {
  917. $flag = file_get_contents('http://www.prestashop.com/download/lang_packs/flags/jpeg/'.$iso_code.'.jpg');
  918. if ($flag != NULL && !preg_match('/<body>/', $flag))
  919. {
  920. $file = @fopen(dirname(__FILE__).'/../../img/l/'.$insert_id.'.jpg', 'w');
  921. if ($file)
  922. {
  923. fwrite($file, $flag);
  924. fclose($file);
  925. }
  926. else
  927. $this->_copyNoneFlag($insert_id);
  928. }
  929. else
  930. $this->_copyNoneFlag($insert_id);
  931. }
  932. else
  933. $this->_copyNoneFlag($insert_id);
  934. $url_to_dir = dirname(__FILE__).'/../../img/l/';
  935. $files_copy = array(
  936. '/en.jpg',
  937. '/en-default-thickbox.jpg',
  938. '/en-default-home.jpg',
  939. '/en-default-large.jpg',
  940. '/en-default-medium.jpg',
  941. '/en-default-small.jpg',
  942. '/en-default-large_scene.jpg'
  943. );
  944. $tos = array(
  945. dirname(__FILE__).'/../../img/c',
  946. dirname(__FILE__).'/../../img/m',
  947. dirname(__FILE__).'/../../img/p',
  948. dirname(__FILE__).'/../../img/su'
  949. );
  950. foreach($tos AS $to)
  951. {
  952. foreach($files_copy AS $file)
  953. {
  954. $name = str_replace('/en', '/'.$iso_code, $file);
  955. copy($url_to_dir.$file, $to.$name);
  956. }
  957. }
  958. return true;
  959. }
  960. else
  961. return false;
  962. }
  963. }
  964. }
  965. ?>