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

/controllers/admin/AdminLanguagesController.php

https://gitlab.com/staging06/myproject
PHP | 581 lines | 481 code | 45 blank | 55 comment | 87 complexity | e4e972d83ddbb50a9fbc269a72d66254 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. * @property Language $object
  28. */
  29. class AdminLanguagesControllerCore extends AdminController
  30. {
  31. public function __construct()
  32. {
  33. $this->bootstrap = true;
  34. $this->table = 'lang';
  35. $this->className = 'Language';
  36. $this->lang = false;
  37. $this->deleted = false;
  38. $this->multishop_context = Shop::CONTEXT_ALL;
  39. $this->context = Context::getContext();
  40. $this->fieldImageSettings = array(
  41. array(
  42. 'name' => 'flag',
  43. 'dir' => 'l'
  44. ),
  45. array(
  46. 'name' => 'no_picture',
  47. 'dir' => 'p'
  48. )
  49. );
  50. $this->fields_list = array(
  51. 'id_lang' => array(
  52. 'title' => $this->l('ID'),
  53. 'align' => 'center',
  54. 'class' => 'fixed-width-xs'
  55. ),
  56. 'flag' => array(
  57. 'title' => $this->l('Flag'),
  58. 'align' => 'center',
  59. 'image' => 'l',
  60. 'orderby' => false,
  61. 'search' => false,
  62. 'class' => 'fixed-width-xs'
  63. ),
  64. 'name' => array(
  65. 'title' => $this->l('Name')
  66. ),
  67. 'iso_code' => array(
  68. 'title' => $this->l('ISO code'),
  69. 'align' => 'center',
  70. 'class' => 'fixed-width-xs'
  71. ),
  72. 'language_code' => array(
  73. 'title' => $this->l('Language code'),
  74. 'align' => 'center',
  75. 'class' => 'fixed-width-xs'
  76. ),
  77. 'date_format_lite' => array(
  78. 'title' => $this->l('Date format')
  79. ),
  80. 'date_format_full' => array(
  81. 'title' => $this->l('Date format (full)')
  82. ),
  83. 'active' => array(
  84. 'title' => $this->l('Enabled'),
  85. 'align' => 'center',
  86. 'active' => 'status',
  87. 'type' => 'bool',
  88. 'class' => 'fixed-width-sm'
  89. )
  90. );
  91. $this->bulk_actions = array(
  92. 'delete' => array(
  93. 'text' => $this->l('Delete selected'),
  94. 'confirm' => $this->l('Delete selected items?'),
  95. 'icon' => 'icon-trash'
  96. )
  97. );
  98. $this->specificConfirmDelete = $this->l('When you delete a language, all related translations in the database will be deleted. Are you sure you want to proceed?');
  99. parent::__construct();
  100. }
  101. public function initPageHeaderToolbar()
  102. {
  103. if (empty($this->display)) {
  104. $this->page_header_toolbar_btn['new_language'] = array(
  105. 'href' => self::$currentIndex.'&addlang&token='.$this->token,
  106. 'desc' => $this->l('Add new language', null, null, false),
  107. 'icon' => 'process-icon-new'
  108. );
  109. }
  110. parent::initPageHeaderToolbar();
  111. }
  112. public function renderList()
  113. {
  114. $this->addRowAction('edit');
  115. $this->addRowAction('delete');
  116. $this->displayWarning($this->l('When you delete a language, all related translations in the database will be deleted.'));
  117. if (!is_writable(_PS_ROOT_DIR_.'/.htaccess') && Configuration::get('PS_REWRITING_SETTINGS')) {
  118. $this->displayInformation($this->l('Your .htaccess file must be writable.'));
  119. }
  120. return parent::renderList();
  121. }
  122. public function renderForm()
  123. {
  124. $this->fields_form = array(
  125. 'legend' => array(
  126. 'title' => $this->l('Languages'),
  127. 'icon' => 'icon-globe'
  128. ),
  129. 'input' => array(
  130. array(
  131. 'type' => 'hidden',
  132. 'name' => 'ps_version'
  133. ),
  134. array(
  135. 'type' => 'text',
  136. 'label' => $this->l('Name'),
  137. 'name' => 'name',
  138. 'maxlength' => 32,
  139. 'required' => true
  140. ),
  141. array(
  142. 'type' => 'text',
  143. 'label' => $this->l('ISO code'),
  144. 'name' => 'iso_code',
  145. 'required' => true,
  146. 'maxlength' => 2,
  147. 'hint' => $this->l('Two-letter ISO code (e.g. FR, EN, DE).')
  148. ),
  149. array(
  150. 'type' => 'text',
  151. 'label' => $this->l('Language code'),
  152. 'name' => 'language_code',
  153. 'required' => true,
  154. 'maxlength' => 5,
  155. 'hint' => $this->l('IETF language tag (e.g. en-US, pt-BR).')
  156. /* TO DO - ajouter les liens dans le hint ? */
  157. /*'desc' => $this->l('IETF language tag (e.g. en-US, pt-BR).').' '.sprintf('<a href="http://en.wikipedia.org/wiki/IETF_language_tag" target="_blank">%s <img src="../img/admin/external_link.png" class="icon-top" /></a>', $this->l('IETF on Wikipedia'))*/
  158. ),
  159. array(
  160. 'type' => 'text',
  161. 'label' => $this->l('Date format'),
  162. 'name' => 'date_format_lite',
  163. 'required' => true,
  164. 'hint' => sprintf($this->l('Short date format (e.g., %s).'), 'Y-m-d')
  165. /* TO DO - ajouter les liens dans le hint ? */
  166. /*'desc' => sprintf($this->l('Short date format (e.g., %s)'), '<a href="http://php.net/date" target="_blank">Y-m-d</a>')*/
  167. ),
  168. array(
  169. 'type' => 'text',
  170. 'label' => $this->l('Date format (full)'),
  171. 'name' => 'date_format_full',
  172. 'required' => true,
  173. 'hint' => sprintf($this->l('Full date format (e.g., %s).'), 'Y-m-d H:i:s')
  174. /* TO DO - ajouter les liens dans le hint ? */
  175. /*'desc' => sprintf($this->l('Full date format (e.g., %s)'), '<a href="http://php.net/date" target="_blank">Y-m-d H:i:s</a>')*/
  176. ),
  177. array(
  178. 'type' => 'file',
  179. 'label' => $this->l('Flag'),
  180. 'name' => 'flag',
  181. 'required' => true,
  182. 'hint' => $this->l('Upload the country flag from your computer.')
  183. ),
  184. array(
  185. 'type' => 'file',
  186. 'label' => $this->l('"No-picture" image'),
  187. 'name' => 'no_picture',
  188. 'hint' => $this->l('Image is displayed when "no picture is found".')
  189. ),
  190. array(
  191. 'type' => 'switch',
  192. 'label' => $this->l('Is RTL language'),
  193. 'name' => 'is_rtl',
  194. 'required' => false,
  195. 'is_bool' => true,
  196. 'values' => array(
  197. array(
  198. 'id' => 'is_rtl_on',
  199. 'value' => 1,
  200. 'label' => $this->l('Enabled')
  201. ),
  202. array(
  203. 'id' => 'active_off',
  204. 'value' => 0,
  205. 'label' => $this->l('Disabled')
  206. )
  207. ),
  208. 'hint' => array(
  209. $this->l('Enable if this language is read from right to left.').' '.
  210. $this->l('(Experimental: your theme must be compliant with RTL languages).')
  211. )
  212. ),
  213. array(
  214. 'type' => 'switch',
  215. 'label' => $this->l('Status'),
  216. 'name' => 'active',
  217. 'required' => false,
  218. 'is_bool' => true,
  219. 'values' => array(
  220. array(
  221. 'id' => 'active_on',
  222. 'value' => 1,
  223. 'label' => $this->l('Enabled')
  224. ),
  225. array(
  226. 'id' => 'active_off',
  227. 'value' => 0,
  228. 'label' => $this->l('Disabled')
  229. )
  230. ),
  231. 'hint' => $this->l('Activate this language.')
  232. ),
  233. array(
  234. 'type' => 'special',
  235. 'name' => 'resultCheckLangPack',
  236. 'text' => $this->l('Check to see if a language pack is available for this ISO code.'),
  237. 'img' => 'ajax-loader.gif'
  238. )
  239. )
  240. );
  241. if (Shop::isFeatureActive()) {
  242. $this->fields_form['input'][] = array(
  243. 'type' => 'shop',
  244. 'label' => $this->l('Shop association'),
  245. 'name' => 'checkBoxShopAsso',
  246. );
  247. }
  248. $this->fields_form['submit'] = array(
  249. 'title' => $this->l('Save'),
  250. );
  251. /** @var Language $obj */
  252. if (!($obj = $this->loadObject(true))) {
  253. return;
  254. }
  255. if ($obj->id && !$obj->checkFiles()) {
  256. $this->fields_form['new'] = array(
  257. 'legend' => array(
  258. 'title' => $this->l('Warning'),
  259. 'image' => '../img/admin/warning.gif'
  260. ),
  261. 'list_files' => array(
  262. array(
  263. 'label' => $this->l('Translation files'),
  264. 'files' => Language::getFilesList($obj->iso_code, _THEME_NAME_, false, false, 'tr', true)
  265. ),
  266. array(
  267. 'label' => $this->l('Theme files'),
  268. 'files' => Language::getFilesList($obj->iso_code, _THEME_NAME_, false, false, 'theme', true)
  269. ),
  270. array(
  271. 'label' => $this->l('Mail files'),
  272. 'files' => Language::getFilesList($obj->iso_code, _THEME_NAME_, false, false, 'mail', true)
  273. )
  274. )
  275. );
  276. }
  277. $this->fields_value = array('ps_version' => _PS_VERSION_);
  278. return parent::renderForm();
  279. }
  280. public function processDelete()
  281. {
  282. $object = $this->loadObject();
  283. if (!$this->checkDeletion($object)) {
  284. return false;
  285. }
  286. if (!$this->deleteNoPictureImages((int)$object->id)) {
  287. $this->errors[] = Tools::displayError('An error occurred while deleting the object.').' <b>'.$this->table.'</b> ';
  288. }
  289. return parent::processDelete();
  290. }
  291. protected function processBulkDelete()
  292. {
  293. $can_bulk = true;
  294. if (is_array($this->boxes) && !empty($this->boxes)) {
  295. foreach ($this->boxes as $id_lang) {
  296. $object = new Language((int)$id_lang);
  297. if (!$this->checkDeletion($object)) {
  298. return false;
  299. }
  300. if (!$this->deleteNoPictureImages((int)$object->id)) {
  301. $this->errors[] = Tools::displayError('An error occurred while deleting the object.').' <b>'.$this->table.'</b> ';
  302. return false;
  303. }
  304. }
  305. }
  306. return parent::processBulkDelete();
  307. }
  308. protected function checkDeletion($object)
  309. {
  310. if (_PS_MODE_DEMO_) {
  311. $this->errors[] = Tools::displayError('This functionality has been disabled.');
  312. return;
  313. }
  314. if (Validate::isLoadedObject($object)) {
  315. if ($object->id == Configuration::get('PS_LANG_DEFAULT')) {
  316. $this->errors[] = $this->l('You cannot delete the default language.');
  317. } elseif ($object->id == $this->context->language->id) {
  318. $this->errors[] = $this->l('You cannot delete the language currently in use. Please select a different language.');
  319. } else {
  320. return true;
  321. }
  322. } else {
  323. $this->errors[] = Tools::displayError('(cannot load object)');
  324. }
  325. return false;
  326. }
  327. protected function checkDisableStatus($object)
  328. {
  329. if (_PS_MODE_DEMO_) {
  330. $this->errors[] = Tools::displayError('This functionality has been disabled.');
  331. return;
  332. }
  333. if (!Validate::isLoadedObject($object)) {
  334. $this->errors[] = Tools::displayError('An error occurred while updating the status for an object.').' <b>'.$this->table.'</b> '.Tools::displayError('(cannot load object)');
  335. } else {
  336. if ($object->id == (int)Configuration::get('PS_LANG_DEFAULT')) {
  337. $this->errors[] = Tools::displayError('You cannot change the status of the default language.');
  338. } else {
  339. return true;
  340. }
  341. }
  342. return false;
  343. }
  344. public function processStatus()
  345. {
  346. $object = $this->loadObject();
  347. if ($this->checkDisableStatus($object)) {
  348. $this->checkEmployeeIdLang($object->id);
  349. return parent::processStatus();
  350. }
  351. return false;
  352. }
  353. protected function processBulkDisableSelection()
  354. {
  355. if (is_array($this->boxes) && !empty($this->boxes)) {
  356. foreach ($this->boxes as $id_lang) {
  357. $object = new Language((int)$id_lang);
  358. if (!$this->checkDisableStatus($object)) {
  359. return false;
  360. }
  361. $this->checkEmployeeIdLang($object->id);
  362. }
  363. }
  364. return parent::processBulkDisableSelection();
  365. }
  366. public function processAdd()
  367. {
  368. if (_PS_MODE_DEMO_) {
  369. $this->errors[] = Tools::displayError('This functionality has been disabled.');
  370. return;
  371. }
  372. if (isset($_POST['iso_code']) && !empty($_POST['iso_code']) && Validate::isLanguageIsoCode(Tools::getValue('iso_code')) && Language::getIdByIso($_POST['iso_code'])) {
  373. $this->errors[] = Tools::displayError('This ISO code is already linked to another language.');
  374. }
  375. if ((!empty($_FILES['no_picture']['tmp_name']) || !empty($_FILES['flag']['tmp_name'])) && Validate::isLanguageIsoCode(Tools::getValue('iso_code'))) {
  376. if ($_FILES['no_picture']['error'] == UPLOAD_ERR_OK) {
  377. $this->copyNoPictureImage(strtolower(Tools::getValue('iso_code')));
  378. }
  379. unset($_FILES['no_picture']);
  380. } else {
  381. $this->errors[] = Tools::displayError('Flag and "No picture" image fields are required.');
  382. }
  383. return parent::processAdd();
  384. }
  385. public function processUpdate()
  386. {
  387. if (_PS_MODE_DEMO_) {
  388. $this->errors[] = Tools::displayError('This functionality has been disabled.');
  389. return;
  390. }
  391. if ((isset($_FILES['no_picture']) && !$_FILES['no_picture']['error'] || isset($_FILES['flag']) && !$_FILES['flag']['error'])
  392. && Validate::isLanguageIsoCode(Tools::getValue('iso_code'))) {
  393. if ($_FILES['no_picture']['error'] == UPLOAD_ERR_OK) {
  394. $this->copyNoPictureImage(strtolower(Tools::getValue('iso_code')));
  395. }
  396. // class AdminTab deal with every $_FILES content, don't do that for no_picture
  397. unset($_FILES['no_picture']);
  398. }
  399. /** @var Language $object */
  400. $object = $this->loadObject();
  401. if (Tools::getValue('active') != (int)$object->active) {
  402. if (!$this->checkDisableStatus($object)) {
  403. return false;
  404. }
  405. }
  406. $this->checkEmployeeIdLang($object->id);
  407. return parent::processUpdate();
  408. }
  409. /**
  410. * Copy a no-product image
  411. *
  412. * @param string $language Language iso_code for no_picture image filename
  413. *
  414. * @return void|false
  415. */
  416. public function copyNoPictureImage($language)
  417. {
  418. if (isset($_FILES['no_picture']) && $_FILES['no_picture']['error'] === 0) {
  419. if ($error = ImageManager::validateUpload($_FILES['no_picture'], Tools::getMaxUploadSize())) {
  420. $this->errors[] = $error;
  421. } else {
  422. if (!($tmp_name = tempnam(_PS_TMP_IMG_DIR_, 'PS')) || !move_uploaded_file($_FILES['no_picture']['tmp_name'], $tmp_name)) {
  423. return false;
  424. }
  425. if (!ImageManager::resize($tmp_name, _PS_IMG_DIR_.'p/'.$language.'.jpg')) {
  426. $this->errors[] = Tools::displayError('An error occurred while copying "No Picture" image to your product folder.');
  427. }
  428. if (!ImageManager::resize($tmp_name, _PS_IMG_DIR_.'c/'.$language.'.jpg')) {
  429. $this->errors[] = Tools::displayError('An error occurred while copying "No picture" image to your category folder.');
  430. }
  431. if (!ImageManager::resize($tmp_name, _PS_IMG_DIR_.'m/'.$language.'.jpg')) {
  432. $this->errors[] = Tools::displayError('An error occurred while copying "No picture" image to your manufacturer folder.');
  433. } else {
  434. $images_types = ImageType::getImagesTypes('products');
  435. foreach ($images_types as $k => $image_type) {
  436. if (!ImageManager::resize($tmp_name, _PS_IMG_DIR_.'p/'.$language.'-default-'.stripslashes($image_type['name']).'.jpg', $image_type['width'], $image_type['height'])) {
  437. $this->errors[] = Tools::displayError('An error occurred while resizing "No picture" image to your product directory.');
  438. }
  439. if (!ImageManager::resize($tmp_name, _PS_IMG_DIR_.'c/'.$language.'-default-'.stripslashes($image_type['name']).'.jpg', $image_type['width'], $image_type['height'])) {
  440. $this->errors[] = Tools::displayError('An error occurred while resizing "No picture" image to your category directory.');
  441. }
  442. if (!ImageManager::resize($tmp_name, _PS_IMG_DIR_.'m/'.$language.'-default-'.stripslashes($image_type['name']).'.jpg', $image_type['width'], $image_type['height'])) {
  443. $this->errors[] = Tools::displayError('An error occurred while resizing "No picture" image to your manufacturer directory.');
  444. }
  445. }
  446. }
  447. unlink($tmp_name);
  448. }
  449. }
  450. }
  451. /**
  452. * deleteNoPictureImages will delete all default image created for the language id_language
  453. *
  454. * @param string $id_language
  455. * @return bool true if no error
  456. */
  457. protected function deleteNoPictureImages($id_language)
  458. {
  459. $language = Language::getIsoById($id_language);
  460. $images_types = ImageType::getImagesTypes('products');
  461. $dirs = array(_PS_PROD_IMG_DIR_, _PS_CAT_IMG_DIR_, _PS_MANU_IMG_DIR_, _PS_SUPP_IMG_DIR_, _PS_MANU_IMG_DIR_);
  462. foreach ($dirs as $dir) {
  463. foreach ($images_types as $k => $image_type) {
  464. if (file_exists($dir.$language.'-default-'.stripslashes($image_type['name']).'.jpg')) {
  465. if (!unlink($dir.$language.'-default-'.stripslashes($image_type['name']).'.jpg')) {
  466. $this->errors[] = Tools::displayError('An error occurred during image deletion process.');
  467. }
  468. }
  469. }
  470. if (file_exists($dir.$language.'.jpg')) {
  471. if (!unlink($dir.$language.'.jpg')) {
  472. $this->errors[] = Tools::displayError('An error occurred during image deletion process.');
  473. }
  474. }
  475. }
  476. return !count($this->errors) ? true : false;
  477. }
  478. /**
  479. * @param Language $object
  480. * @param string $table
  481. */
  482. protected function copyFromPost(&$object, $table)
  483. {
  484. if ($object->id && ($object->iso_code != $_POST['iso_code'])) {
  485. if (Validate::isLanguageIsoCode($_POST['iso_code'])) {
  486. $object->moveToIso($_POST['iso_code']);
  487. }
  488. }
  489. parent::copyFromPost($object, $table);
  490. }
  491. public function ajaxProcessCheckLangPack()
  492. {
  493. $this->json = true;
  494. if (!Tools::getValue('iso_lang') || !Validate::isLanguageIsoCode(Tools::getValue('iso_lang'))) {
  495. $this->status = 'error';
  496. $this->errors[] = $this->l('Iso code is not valid');
  497. return;
  498. }
  499. if (!Tools::getValue('ps_version') || !Validate::isPrestaShopVersion(Tools::getValue('ps_version'))) {
  500. $this->status = 'error';
  501. $this->errors[] = $this->l('Technical Error: ps_version is not valid');
  502. return;
  503. }
  504. // Get all iso code available
  505. if ($lang_packs = Tools::file_get_contents('http://www.prestashop.com/download/lang_packs/get_language_pack.php?version='.Tools::getValue('ps_version').'&iso_lang='.Tools::strtolower(Tools::getValue('iso_lang')))) {
  506. $result = Tools::jsonDecode($lang_packs);
  507. if ($lang_packs !== '' && $result && !isset($result->error)) {
  508. $this->status = 'ok';
  509. $this->content = $lang_packs;
  510. } else {
  511. $this->status = 'error';
  512. $this->errors[] = $this->l('Wrong ISO code, or the selected language pack is unavailable.');
  513. }
  514. } else {
  515. $this->status = 'error';
  516. $this->errors[] = $this->l('Technical Error: translation server unreachable.');
  517. }
  518. }
  519. protected function checkEmployeeIdLang($current_id_lang)
  520. {
  521. //update employee lang if current id lang is disabled
  522. Db::getInstance()->execute('UPDATE `'._DB_PREFIX_.'employee` set `id_lang`='.(int)Configuration::get('PS_LANG_DEFAULT').' WHERE `id_lang`='.(int)$current_id_lang);
  523. }
  524. protected function afterImageUpload()
  525. {
  526. parent::afterImageUpload();
  527. if (($id_lang = (int)Tools::getValue('id_lang')) &&
  528. isset($_FILES) && count($_FILES) && file_exists(_PS_LANG_IMG_DIR_.$id_lang.'.jpg')) {
  529. $current_file = _PS_TMP_IMG_DIR_.'lang_mini_'.$id_lang.'_'.$this->context->shop->id.'.jpg';
  530. if (file_exists($current_file)) {
  531. unlink($current_file);
  532. }
  533. }
  534. return true;
  535. }
  536. }