Advertisement
Guest User

Untitled

a guest
Nov 22nd, 2015
154
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 105.83 KB | None | 0 0
  1. <?php
  2. /*
  3. * 2007-2013 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-2013 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. class AdminControllerCore extends Controller
  28. {
  29. public $path;
  30. public static $currentIndex;
  31. public $content;
  32. public $warnings = array();
  33. public $informations = array();
  34. public $confirmations = array();
  35. public $shopShareDatas = false;
  36.  
  37. public $_languages = array();
  38. public $default_form_language;
  39. public $allow_employee_form_lang;
  40.  
  41. public $layout = 'layout.tpl';
  42.  
  43. protected $meta_title;
  44.  
  45. public $template = 'content.tpl';
  46.  
  47. /** @var string Associated table name */
  48. public $table = 'configuration';
  49.  
  50. public $list_id;
  51.  
  52. /** @var string Object identifier inside the associated table */
  53. protected $identifier = false;
  54.  
  55. /** @var string Tab name */
  56. public $className;
  57.  
  58. /** @var array tabAccess */
  59. public $tabAccess;
  60.  
  61. /** @var integer Tab id */
  62. public $id = -1;
  63.  
  64. public $required_database = false;
  65.  
  66. /** @var string Security token */
  67. public $token;
  68.  
  69. /** @var string shop | group_shop */
  70. public $shopLinkType;
  71.  
  72. /** @var string Default ORDER BY clause when $_orderBy is not defined */
  73. protected $_defaultOrderBy = false;
  74. protected $_defaultOrderWay = 'ASC';
  75.  
  76. public $tpl_form_vars = array();
  77. public $tpl_list_vars = array();
  78. public $tpl_delete_link_vars = array();
  79. public $tpl_option_vars = array();
  80. public $tpl_view_vars = array();
  81. public $tpl_required_fields_vars = array();
  82.  
  83. public $base_tpl_view = null;
  84. public $base_tpl_form = null;
  85.  
  86. /** @var bool if you want more fieldsets in the form */
  87. public $multiple_fieldsets = false;
  88.  
  89. public $fields_value = false;
  90.  
  91. /** @var array Errors displayed after post processing */
  92. public $errors = array();
  93.  
  94. /** @var define if the header of the list contains filter and sorting links or not */
  95. protected $list_simple_header;
  96.  
  97. /** @var array list to be generated */
  98. protected $fields_list;
  99.  
  100. /** @var array modules list filters */
  101. protected $filter_modules_list = null;
  102.  
  103. /** @var array modules list filters */
  104. protected $modules_list = array();
  105.  
  106. /** @var array edit form to be generated */
  107. protected $fields_form;
  108.  
  109. /** @var override of $fields_form */
  110. protected $fields_form_override;
  111.  
  112. /** @var array list of option forms to be generated */
  113. protected $fields_options;
  114.  
  115. protected $shopLink;
  116.  
  117. /** @var string SQL query */
  118. protected $_listsql = '';
  119.  
  120. /** @var array Cache for query results */
  121. protected $_list = array();
  122.  
  123. /** @var define if the header of the list contains filter and sorting links or not */
  124. protected $toolbar_title;
  125.  
  126. /** @var array list of toolbar buttons */
  127. protected $toolbar_btn = null;
  128.  
  129. /** @var boolean scrolling toolbar */
  130. protected $toolbar_scroll = true;
  131.  
  132. /** @var boolean set to false to hide toolbar and page title */
  133. protected $show_toolbar = true;
  134.  
  135. /** @var boolean set to true to show toolbar and page title for options */
  136. protected $show_toolbar_options = false;
  137.  
  138. /** @var integer Number of results in list */
  139. protected $_listTotal = 0;
  140.  
  141. /** @var boolean Automatically join language table if true */
  142. public $lang = false;
  143.  
  144. /** @var array WHERE clause determined by filter fields */
  145. protected $_filter;
  146.  
  147. /** @var array Temporary SQL table WHERE clause determinated by filter fields */
  148. protected $_tmpTableFilter = '';
  149.  
  150. /** @var array Number of results in list per page (used in select field) */
  151. protected $_pagination = array(20, 50, 100, 300);
  152.  
  153. /** @var string ORDER BY clause determined by field/arrows in list header */
  154. protected $_orderBy;
  155.  
  156. /** @var string Order way (ASC, DESC) determined by arrows in list header */
  157. protected $_orderWay;
  158.  
  159. /** @var array list of available actions for each list row - default actions are view, edit, delete, duplicate */
  160. protected $actions_available = array('view', 'edit', 'delete', 'duplicate');
  161.  
  162. /** @var array list of required actions for each list row */
  163. protected $actions = array();
  164.  
  165. /** @var array list of row ids associated with a given action for witch this action have to not be available */
  166. protected $list_skip_actions = array();
  167.  
  168. /* @var boolean don't show header & footer */
  169. protected $lite_display = false;
  170. /** @var bool boolean List content lines are clickable if true */
  171. protected $list_no_link = false;
  172.  
  173. protected $allow_export = false;
  174.  
  175. /** @var array $cache_lang cache for traduction */
  176. public static $cache_lang = array();
  177.  
  178. /** @var array required_fields to display in the Required Fields form */
  179. public $required_fields = array();
  180.  
  181. /** @var Helper */
  182. protected $helper;
  183.  
  184. /**
  185. * @var array actions to execute on multiple selections
  186. * Usage:
  187. * array(
  188. * 'actionName' => array(
  189. * 'text' => $this->l('Message displayed on the submit button (mandatory)'),
  190. * 'confirm' => $this->l('If set, this confirmation message will pop-up (optional)')),
  191. * 'anotherAction' => array(...)
  192. * );
  193. *
  194. * If your action is named 'actionName', you need to have a method named bulkactionName() that will be executed when the button is clicked.
  195. */
  196. protected $bulk_actions;
  197.  
  198. /**
  199. * @var array ids of the rows selected
  200. */
  201. protected $boxes;
  202.  
  203. /** @var string Do not automatically select * anymore but select only what is necessary */
  204. protected $explicitSelect = false;
  205.  
  206. /** @var string Add fields into data query to display list */
  207. protected $_select;
  208.  
  209. /** @var string Join tables into data query to display list */
  210. protected $_join;
  211.  
  212. /** @var string Add conditions into data query to display list */
  213. protected $_where;
  214.  
  215. /** @var string Group rows into data query to display list */
  216. protected $_group;
  217.  
  218. /** @var string Having rows into data query to display list */
  219. protected $_having;
  220.  
  221. protected $is_cms = false;
  222.  
  223. /** @var string identifier to use for changing positions in lists (can be omitted if positions cannot be changed) */
  224. protected $position_identifier;
  225.  
  226. /** @var boolean Table records are not deleted but marked as deleted if set to true */
  227. protected $deleted = false;
  228. /**
  229. * @var bool is a list filter set
  230. */
  231. protected $filter;
  232. protected $noLink;
  233. protected $specificConfirmDelete = null;
  234. protected $colorOnBackground;
  235. /** @var bool If true, activates color on hover */
  236. protected $row_hover = true;
  237. /** @string Action to perform : 'edit', 'view', 'add', ... */
  238. protected $action;
  239. protected $display;
  240. protected $_includeContainer = true;
  241. protected $tab_modules_list = array('default_list' => array(), 'slider_list' => array());
  242.  
  243. public $tpl_folder;
  244.  
  245. protected $bo_theme;
  246.  
  247. /** @var bool Redirect or not ater a creation */
  248. protected $_redirect = true;
  249.  
  250. /** @var array Name and directory where class image are located */
  251. public $fieldImageSettings = array();
  252.  
  253. /** @var string Image type */
  254. public $imageType = 'jpg';
  255.  
  256. /** @var instanciation of the class associated with the AdminController */
  257. protected $object;
  258.  
  259. /** @var current object ID */
  260. protected $id_object;
  261.  
  262. /**
  263. * @var current controller name without suffix
  264. */
  265. public $controller_name;
  266.  
  267. public $multishop_context = -1;
  268. public $multishop_context_group = true;
  269.  
  270. /**
  271. * Current breadcrumb position as an array of tab names
  272. */
  273. protected $breadcrumbs;
  274.  
  275. public function __construct()
  276. {
  277. global $timer_start;
  278. $this->timer_start = $timer_start;
  279. // Has to be remove for the next Prestashop version
  280. global $token;
  281.  
  282. $this->controller_type = 'admin';
  283. $this->controller_name = get_class($this);
  284. if (strpos($this->controller_name, 'Controller'))
  285. $this->controller_name = substr($this->controller_name, 0, -10);
  286. parent::__construct();
  287.  
  288. if ($this->multishop_context == -1)
  289. $this->multishop_context = Shop::CONTEXT_ALL | Shop::CONTEXT_GROUP | Shop::CONTEXT_SHOP;
  290.  
  291. $this->bo_theme = ((Validate::isLoadedObject($this->context->employee) && $this->context->employee->bo_theme) ? $this->context->employee->bo_theme : 'default');
  292. if (!file_exists(_PS_BO_ALL_THEMES_DIR_.$this->bo_theme.DIRECTORY_SEPARATOR.'template'))
  293. $this->bo_theme = 'default';
  294.  
  295. $this->context->smarty->setTemplateDir(array(
  296. _PS_BO_ALL_THEMES_DIR_.$this->bo_theme.DIRECTORY_SEPARATOR.'template',
  297. _PS_OVERRIDE_DIR_.'controllers'.DIRECTORY_SEPARATOR.'admin'.DIRECTORY_SEPARATOR.'templates'
  298. ));
  299.  
  300. $this->id = Tab::getIdFromClassName($this->controller_name);
  301. $this->token = Tools::getAdminToken($this->controller_name.(int)$this->id.(int)$this->context->employee->id);
  302.  
  303. $token = $this->token;
  304.  
  305. $this->_conf = array(
  306. 1 => $this->l('Deletion successful'), 2 => $this->l('The selection has been successfully deleted.'),
  307. 3 => $this->l('Creation successful'), 4 => $this->l('Update successful'),
  308. 5 => $this->l('The status has been updated successfully.'), 6 => $this->l('The settings have been updated successfully.'),
  309. 7 => $this->l('The image was successfully deleted.'), 8 => $this->l('The module was downloaded successfully.'),
  310. 9 => $this->l('The thumbnails were successfully regenerated.'), 10 => $this->l('Message sent to the customer.'),
  311. 11 => $this->l('Comment added'), 12 => $this->l('Module(s) installed successfully.'),
  312. 13 => $this->l('Module(s) uninstalled successfully.'), 14 => $this->l('The translation was successfully copied.'),
  313. 15 => $this->l('The translations have been successfully added.'), 16 => $this->l('The module transplanted successfully to the hook.'),
  314. 17 => $this->l('The module was successfully removed from the hook.'), 18 => $this->l('Upload successful'),
  315. 19 => $this->l('Duplication was completed successfully.'), 20 => $this->l('The translation was added successfully, but the language has not been created.'),
  316. 21 => $this->l('Module reset successfully.'), 22 => $this->l('Module deleted successfully.'),
  317. 23 => $this->l('Localization pack imported successfully.'), 24 => $this->l('Localization pack imported successfully.'),
  318. 25 => $this->l('The selected images have successfully been moved.'),
  319. 26 => $this->l('Your cover selection has been saved.'),
  320. 27 => $this->l('The image shop association has been modified.'),
  321. 28 => $this->l('A zone has been assigned to the selection successfully.'),
  322. 29 => $this->l('Upgrade successful'),
  323. 30 => $this->l('A partial refund was successfully created.'),
  324. 31 => $this->l('The discount was successfully generated.')
  325. );
  326.  
  327. if (!$this->identifier) $this->identifier = 'id_'.$this->table;
  328. if (!$this->_defaultOrderBy) $this->_defaultOrderBy = $this->identifier;
  329. $this->tabAccess = Profile::getProfileAccess($this->context->employee->id_profile, $this->id);
  330.  
  331. // Fix for AdminHome
  332. if ($this->controller_name == 'AdminHome')
  333. $_POST['token'] = $this->token;
  334.  
  335. if (!Shop::isFeatureActive())
  336. $this->shopLinkType = '';
  337.  
  338. //$this->base_template_folder = _PS_BO_ALL_THEMES_DIR_.$this->bo_theme.'/template';
  339. $this->override_folder = Tools::toUnderscoreCase(substr($this->controller_name, 5)).'/';
  340. // Get the name of the folder containing the custom tpl files
  341. $this->tpl_folder = Tools::toUnderscoreCase(substr($this->controller_name, 5)).'/';
  342.  
  343. $this->initShopContext();
  344.  
  345. $this->context->currency = new Currency(Configuration::get('PS_CURRENCY_DEFAULT'));
  346. }
  347.  
  348. /**
  349. * Set breadcrumbs array for the controller page
  350. */
  351. public function initBreadcrumbs()
  352. {
  353. $tabs = array();
  354. $tabs = Tab::recursiveTab($this->id, $tabs);
  355. $tabs = array_reverse($tabs);
  356. foreach ($tabs as $tab)
  357. $this->breadcrumbs[] = $tab['name'];
  358. }
  359.  
  360. /**
  361. * set default toolbar_title to admin breadcrumb
  362. *
  363. * @return void
  364. */
  365. public function initToolbarTitle()
  366. {
  367. $bread_extended = array_unique($this->breadcrumbs);
  368.  
  369. switch ($this->display)
  370. {
  371. case 'edit':
  372. $bread_extended[] = $this->l('Edit');
  373. break;
  374.  
  375. case 'add':
  376. $bread_extended[] = $this->l('Add new');
  377. break;
  378.  
  379. case 'view':
  380. $bread_extended[] = $this->l('View');
  381. break;
  382. }
  383. $this->toolbar_title = $bread_extended;
  384.  
  385. if (Tools::isSubmit('submitFilter'))
  386. {
  387. $filter = '';
  388. foreach ($this->fields_list AS $field => $t)
  389. {
  390. if (isset($t['filter_key']))
  391. $field = $t['filter_key'];
  392. if ($val = Tools::getValue($this->table.'Filter_'.$field))
  393. {
  394. if(!is_array($val) && !empty($val))
  395. $filter .= ($filter ? ', ' : $this->l(' filter by ')).$t['title'].' : ';
  396.  
  397. if (isset($t['type']) && $t['type'] == 'bool')
  398. $filter .= ((bool)$val) ? $this->l('yes') : $this->l('no');
  399. elseif(is_string($val))
  400. $filter .= htmlspecialchars($val, ENT_QUOTES, 'UTF-8');
  401. elseif(is_array($val))
  402. {
  403. $tmp = '';
  404. foreach($val as $v)
  405. if(is_string($v) && !empty($v))
  406. $tmp .= ' - '.htmlspecialchars($v, ENT_QUOTES, 'UTF-8');
  407. if(Tools::strlen($tmp))
  408. {
  409. $tmp = ltrim($tmp, ' - ');
  410. $filter .= ($filter ? ', ' : $this->l(' filter by ')).$t['title'].' : ';
  411. $filter .= $tmp;
  412. }
  413. }
  414. }
  415. }
  416. if ($filter)
  417. $this->toolbar_title[] = $filter;
  418. }
  419. }
  420.  
  421. /**
  422. * Check rights to view the current tab
  423. *
  424. * @param bool $disable
  425. * @return boolean
  426. */
  427. public function viewAccess($disable = false)
  428. {
  429. if ($disable)
  430. return true;
  431.  
  432. if ($this->tabAccess['view'] === '1')
  433. return true;
  434. return false;
  435. }
  436.  
  437. /**
  438. * Check for security token
  439. */
  440. public function checkToken()
  441. {
  442. $token = Tools::getValue('token');
  443. return (!empty($token) && $token === $this->token);
  444. }
  445.  
  446. public function ajaxProcessHelpAccess()
  447. {
  448. $this->json = true;
  449. $item = Tools::getValue('item');
  450. $iso_user = Tools::getValue('isoUser');
  451. $country = Tools::getValue('country');
  452. $version = Tools::getValue('version');
  453.  
  454. if (isset($item) && isset($iso_user) && isset($country))
  455. {
  456. $helper = new HelperHelpAccess($item, $iso_user, $country, $version);
  457. $this->content = $helper->generate();
  458. }
  459. else
  460. $this->content = 'none';
  461. $this->display = 'content';
  462. }
  463.  
  464. /**
  465. * Set the filters used for the list display
  466. */
  467. public function processFilter()
  468. {
  469. if (!isset($this->list_id))
  470. $this->list_id = $this->table;
  471.  
  472. $prefix = str_replace(array('admin', 'controller'), '', Tools::strtolower(get_class($this)));
  473. // Filter memorization
  474. if (isset($_POST) && !empty($_POST) && isset($this->list_id))
  475. foreach ($_POST as $key => $value)
  476. {
  477. if (stripos($key, $this->list_id.'Filter_') === 0)
  478. $this->context->cookie->{$prefix.$key} = !is_array($value) ? $value : serialize($value);
  479. elseif(stripos($key, 'submitFilter') === 0)
  480. $this->context->cookie->$key = !is_array($value) ? $value : serialize($value);
  481. }
  482.  
  483. if (isset($_GET) && !empty($_GET) && isset($this->list_id))
  484. foreach ($_GET as $key => $value)
  485. if (stripos($key, $this->list_id.'OrderBy') === 0 || stripos($key, $this->list_id.'Orderway') === 0)
  486. $this->context->cookie->{$prefix.$key} = $value;
  487.  
  488. $filters = $this->context->cookie->getFamily($prefix.$this->list_id.'Filter_');
  489.  
  490. foreach ($filters as $key => $value)
  491. {
  492. /* Extracting filters from $_POST on key filter_ */
  493. if ($value != null && !strncmp($key, $prefix.$this->list_id.'Filter_', 7 + Tools::strlen($prefix.$this->list_id)))
  494. {
  495. $key = Tools::substr($key, 7 + Tools::strlen($prefix.$this->list_id));
  496. /* Table alias could be specified using a ! eg. alias!field */
  497. $tmp_tab = explode('!', $key);
  498. $filter = count($tmp_tab) > 1 ? $tmp_tab[1] : $tmp_tab[0];
  499.  
  500. if ($field = $this->filterToField($key, $filter))
  501. {
  502. $type = (array_key_exists('filter_type', $field) ? $field['filter_type'] : (array_key_exists('type', $field) ? $field['type'] : false)); if (($type == 'date' || $type == 'datetime') && is_string($value))
  503. $value = Tools::unSerialize($value);
  504. $key = isset($tmp_tab[1]) ? $tmp_tab[0].'.`'.$tmp_tab[1].'`' : '`'.$tmp_tab[0].'`';
  505.  
  506. // Assignement by reference
  507. if (array_key_exists('tmpTableFilter', $field))
  508. $sql_filter = & $this->_tmpTableFilter;
  509. elseif (array_key_exists('havingFilter', $field))
  510. $sql_filter = & $this->_filterHaving;
  511. else
  512. $sql_filter = & $this->_filter;
  513.  
  514. /* Only for date filtering (from, to) */
  515. if (is_array($value))
  516. {
  517. if (isset($value[0]) && !empty($value[0]))
  518. {
  519. if (!Validate::isDate($value[0]))
  520. $this->errors[] = Tools::displayError('The \'From\' date format is invalid (YYYY-MM-DD)');
  521. else
  522. $sql_filter .= ' AND '.pSQL($key).' >= \''.pSQL(Tools::dateFrom($value[0])).'\'';
  523. }
  524.  
  525. if (isset($value[1]) && !empty($value[1]))
  526. {
  527. if (!Validate::isDate($value[1]))
  528. $this->errors[] = Tools::displayError('The \'To\' date format is invalid (YYYY-MM-DD)');
  529. else
  530. $sql_filter .= ' AND '.pSQL($key).' <= \''.pSQL(Tools::dateTo($value[1])).'\'';
  531. }
  532. }
  533. else
  534. {
  535. $sql_filter .= ' AND ';
  536. $check_key = ($key == $this->identifier || $key == '`'.$this->identifier.'`');
  537.  
  538. if ($type == 'int' || $type == 'bool')
  539. $sql_filter .= (($check_key || $key == '`active`') ? 'a.' : '').pSQL($key).' = '.(int)$value.' ';
  540. elseif ($type == 'decimal')
  541. $sql_filter .= ($check_key ? 'a.' : '').pSQL($key).' = '.(float)$value.' ';
  542. elseif ($type == 'select')
  543. $sql_filter .= ($check_key ? 'a.' : '').pSQL($key).' = \''.pSQL($value).'\' ';
  544. else
  545. $sql_filter .= ($check_key ? 'a.' : '').pSQL($key).' LIKE \'%'.pSQL($value).'%\' ';
  546. }
  547. }
  548. }
  549. }
  550. }
  551.  
  552. /**
  553. * @todo uses redirectAdmin only if !$this->ajax
  554. */
  555. public function postProcess()
  556. {
  557. try {
  558. if ($this->ajax)
  559. {
  560. // from ajax-tab.php
  561. $action = Tools::getValue('action');
  562. // no need to use displayConf() here
  563. if (!empty($action) && method_exists($this, 'ajaxProcess'.Tools::toCamelCase($action)))
  564. return $this->{'ajaxProcess'.Tools::toCamelCase($action)}();
  565. elseif (method_exists($this, 'ajaxProcess'))
  566. return $this->ajaxProcess();
  567. }
  568. else
  569. {
  570. // Process list filtering
  571. if ($this->filter)
  572. $this->processFilter();
  573.  
  574. // If the method named after the action exists, call "before" hooks, then call action method, then call "after" hooks
  575. if (!empty($this->action) && method_exists($this, 'process'.ucfirst(Tools::toCamelCase($this->action))))
  576. {
  577. // Hook before action
  578. Hook::exec('actionAdmin'.ucfirst($this->action).'Before', array('controller' => $this));
  579. Hook::exec('action'.get_class($this).ucfirst($this->action).'Before', array('controller' => $this));
  580. // Call process
  581. $return = $this->{'process'.Tools::toCamelCase($this->action)}();
  582. // Hook After Action
  583. Hook::exec('actionAdmin'.ucfirst($this->action).'After', array('controller' => $this, 'return' => $return));
  584. Hook::exec('action'.get_class($this).ucfirst($this->action).'After', array('controller' => $this, 'return' => $return));
  585.  
  586. return $return;
  587. }
  588. }
  589. } catch (PrestaShopException $e) {
  590. $this->errors[] = $e->getMessage();
  591. };
  592. return false;
  593. }
  594.  
  595. /**
  596. * Object Delete images
  597. */
  598. public function processDeleteImage()
  599. {
  600. if (Validate::isLoadedObject($object = $this->loadObject()))
  601. {
  602. if (($object->deleteImage()))
  603. {
  604. $redirect = self::$currentIndex.'&add'.$this->table.'&'.$this->identifier.'='.Tools::getValue($this->identifier).'&conf=7&token='.$this->token;
  605. if (!$this->ajax)
  606. $this->redirect_after = $redirect;
  607. else
  608. $this->content = 'ok';
  609. }
  610. }
  611. $this->errors[] = Tools::displayError('An error occurred while attempting to delet the image. (cannot load object).');
  612. return $object;
  613. }
  614.  
  615. public function processExport()
  616. {
  617. // clean buffer
  618. if (ob_get_level() && ob_get_length() > 0)
  619. ob_clean();
  620. $this->getList($this->context->language->id);
  621. if (!count($this->_list))
  622. return;
  623.  
  624. header('Content-type: text/csv');
  625. header('Content-Type: application/force-download; charset=UTF-8');
  626. header('Cache-Control: no-store, no-cache');
  627. header('Content-disposition: attachment; filename="'.$this->table.'_'.date('Y-m-d_His').'.csv"');
  628.  
  629. $headers = array();
  630. foreach ($this->fields_list as $datas)
  631. $headers[] = Tools::htmlentitiesDecodeUTF8($datas['title']);
  632. $content = array();
  633. foreach ($this->_list as $i => $row)
  634. {
  635. $content[$i] = array();
  636. $path_to_image = false;
  637. foreach ($this->fields_list as $key => $params)
  638. {
  639. $field_value = isset($row[$key]) ? Tools::htmlentitiesDecodeUTF8($row[$key]) : '';
  640. if ($key == 'image')
  641. {
  642. if ($params['image'] != 'p' || Configuration::get('PS_LEGACY_IMAGES'))
  643. $path_to_image = Tools::getShopDomain(true)._PS_IMG_.$params['image'].'/'.$row['id_'.$this->table].(isset($row['id_image']) ? '-'.(int)$row['id_image'] : '').'.'.$this->imageType;
  644. else
  645. $path_to_image = Tools::getShopDomain(true)._PS_IMG_.$params['image'].'/'.Image::getImgFolderStatic($row['id_image']).(int)$row['id_image'].'.'.$this->imageType;
  646. if ($path_to_image)
  647. $field_value = $path_to_image;
  648. }
  649. $content[$i][] = $field_value;
  650. }
  651. }
  652.  
  653. $this->context->smarty->assign(array(
  654. 'export_precontent' => "\xEF\xBB\xBF",
  655. 'export_headers' => $headers,
  656. 'export_content' => $content
  657. )
  658. );
  659.  
  660. $this->layout = 'layout-export.tpl';
  661. }
  662.  
  663. /**
  664. * Object Delete
  665. */
  666. public function processDelete()
  667. {
  668. if (Validate::isLoadedObject($object = $this->loadObject()))
  669. {
  670. $res = true;
  671. // check if request at least one object with noZeroObject
  672. if (isset($object->noZeroObject) && count(call_user_func(array($this->className, $object->noZeroObject))) <= 1)
  673. {
  674. $this->errors[] = Tools::displayError('You need at least one object.').
  675. ' <b>'.$this->table.'</b><br />'.
  676. Tools::displayError('You cannot delete all of the items.');
  677. }
  678. elseif (array_key_exists('delete', $this->list_skip_actions) && in_array($object->id, $this->list_skip_actions['delete'])) //check if some ids are in list_skip_actions and forbid deletion
  679. $this->errors[] = Tools::displayError('You cannot delete this item.');
  680. else
  681. {
  682. if ($this->deleted)
  683. {
  684. if (!empty($this->fieldImageSettings))
  685. $res = $object->deleteImage();
  686.  
  687. if (!$res)
  688. $this->errors[] = Tools::displayError('Unable to delete associated images.');
  689.  
  690. $object->deleted = 1;
  691. if ($res = $object->update())
  692. $this->redirect_after = self::$currentIndex.'&conf=1&token='.$this->token;
  693. }
  694. elseif ($res = $object->delete())
  695. $this->redirect_after = self::$currentIndex.'&conf=1&token='.$this->token;
  696. $this->errors[] = Tools::displayError('An error occurred during deletion.');
  697. if ($res)
  698. Logger::addLog(sprintf($this->l('%s deletion', 'AdminTab', false, false), $this->className), 1, null, $this->className, (int)$this->object->id, true, (int)$this->context->employee->id);
  699. }
  700. }
  701. else
  702. {
  703. $this->errors[] = Tools::displayError('An error occurred while deleting the object.').
  704. ' <b>'.$this->table.'</b> '.
  705. Tools::displayError('(cannot load object)');
  706. }
  707. return $object;
  708. }
  709.  
  710. /**
  711. * Call the right method for creating or updating object
  712. *
  713. * @return mixed
  714. */
  715. public function processSave()
  716. {
  717. if ($this->id_object)
  718. {
  719. $this->object = $this->loadObject();
  720. return $this->processUpdate();
  721. }
  722. else
  723. return $this->processAdd();
  724. }
  725.  
  726. /**
  727. * Object creation
  728. */
  729. public function processAdd()
  730. {
  731. if (!isset($this->className) || empty($this->className))
  732. return false;
  733. /* Checking fields validity */
  734. $this->validateRules();
  735. if (count($this->errors) <= 0)
  736. {
  737. $this->object = new $this->className();
  738.  
  739. $this->copyFromPost($this->object, $this->table);
  740. $this->beforeAdd($this->object);
  741. if (method_exists($this->object, 'add') && !$this->object->add())
  742. {
  743. $this->errors[] = Tools::displayError('An error occurred while creating an object.').
  744. ' <b>'.$this->table.' ('.Db::getInstance()->getMsgError().')</b>';
  745. }
  746. /* voluntary do affectation here */
  747. elseif (($_POST[$this->identifier] = $this->object->id) && $this->postImage($this->object->id) && !count($this->errors) && $this->_redirect)
  748. {
  749. Logger::addLog(sprintf($this->l('%s addition', 'AdminTab', false, false), $this->className), 1, null, $this->className, (int)$this->object->id, true, (int)$this->context->employee->id);
  750. $parent_id = (int)Tools::getValue('id_parent', 1);
  751. $this->afterAdd($this->object);
  752. $this->updateAssoShop($this->object->id);
  753. // Save and stay on same form
  754. if (empty($this->redirect_after) && $this->redirect_after !== false && Tools::isSubmit('submitAdd'.$this->table.'AndStay'))
  755. $this->redirect_after = self::$currentIndex.'&'.$this->identifier.'='.$this->object->id.'&conf=3&update'.$this->table.'&token='.$this->token;
  756. // Save and back to parent
  757. if (empty($this->redirect_after) && $this->redirect_after !== false && Tools::isSubmit('submitAdd'.$this->table.'AndBackToParent'))
  758. $this->redirect_after = self::$currentIndex.'&'.$this->identifier.'='.$parent_id.'&conf=3&token='.$this->token;
  759. // Default behavior (save and back)
  760. if (empty($this->redirect_after) && $this->redirect_after !== false)
  761. $this->redirect_after = self::$currentIndex.($parent_id ? '&'.$this->identifier.'='.$this->object->id : '').'&conf=3&token='.$this->token;
  762. }
  763. }
  764.  
  765. $this->errors = array_unique($this->errors);
  766. if (!empty($this->errors))
  767. {
  768. // if we have errors, we stay on the form instead of going back to the list
  769. $this->display = 'edit';
  770. return false;
  771. }
  772.  
  773. return $this->object;
  774. }
  775.  
  776.  
  777. /**
  778. * Object update
  779. */
  780. public function processUpdate()
  781. {
  782. /* Checking fields validity */
  783. $this->validateRules();
  784. if (empty($this->errors))
  785. {
  786. $id = (int)Tools::getValue($this->identifier);
  787.  
  788. /* Object update */
  789. if (isset($id) && !empty($id))
  790. {
  791. $object = new $this->className($id);
  792. if (Validate::isLoadedObject($object))
  793. {
  794. /* Specific to objects which must not be deleted */
  795. if ($this->deleted && $this->beforeDelete($object))
  796. {
  797. // Create new one with old objet values
  798. $object_new = $object->duplicateObject();
  799. if (Validate::isLoadedObject($object_new))
  800. {
  801. // Update old object to deleted
  802. $object->deleted = 1;
  803. $object->update();
  804.  
  805. // Update new object with post values
  806. $this->copyFromPost($object_new, $this->table);
  807. $result = $object_new->update();
  808. if (Validate::isLoadedObject($object_new))
  809. $this->afterDelete($object_new, $object->id);
  810. }
  811. }
  812. else
  813. {
  814. $this->copyFromPost($object, $this->table);
  815. $result = $object->update();
  816. $this->afterUpdate($object);
  817. }
  818.  
  819. if ($object->id)
  820. $this->updateAssoShop($object->id);
  821.  
  822. if (!$result)
  823. {
  824. $this->errors[] = Tools::displayError('An error occurred while updating an object.').
  825. ' <b>'.$this->table.'</b> ('.Db::getInstance()->getMsgError().')';
  826. }
  827. elseif ($this->postImage($object->id) && !count($this->errors) && $this->_redirect)
  828. {
  829. $parent_id = (int)Tools::getValue('id_parent', 1);
  830. // Specific back redirect
  831. if ($back = Tools::getValue('back'))
  832. $this->redirect_after = urldecode($back).'&conf=4';
  833. // Specific scene feature
  834. // @todo change stay_here submit name (not clear for redirect to scene ... )
  835. if (Tools::getValue('stay_here') == 'on' || Tools::getValue('stay_here') == 'true' || Tools::getValue('stay_here') == '1')
  836. $this->redirect_after = self::$currentIndex.'&'.$this->identifier.'='.$object->id.'&conf=4&updatescene&token='.$this->token;
  837. // Save and stay on same form
  838. // @todo on the to following if, we may prefer to avoid override redirect_after previous value
  839. if (Tools::isSubmit('submitAdd'.$this->table.'AndStay'))
  840. $this->redirect_after = self::$currentIndex.'&'.$this->identifier.'='.$object->id.'&conf=4&update'.$this->table.'&token='.$this->token;
  841. // Save and back to parent
  842. if (Tools::isSubmit('submitAdd'.$this->table.'AndBackToParent'))
  843. $this->redirect_after = self::$currentIndex.'&'.$this->identifier.'='.$parent_id.'&conf=4&token='.$this->token;
  844.  
  845. // Default behavior (save and back)
  846. if (empty($this->redirect_after) && $this->redirect_after !== false)
  847. $this->redirect_after = self::$currentIndex.($parent_id ? '&'.$this->identifier.'='.$object->id : '').'&conf=4&token='.$this->token;
  848. }
  849. Logger::addLog(sprintf($this->l('%s edition', 'AdminTab', false, false), $this->className), 1, null, $this->className, (int)$object->id, true, (int)$this->context->employee->id);
  850. }
  851. else
  852. $this->errors[] = Tools::displayError('An error occurred while updating an object.').
  853. ' <b>'.$this->table.'</b> '.Tools::displayError('(cannot load object)');
  854. }
  855. }
  856. $this->errors = array_unique($this->errors);
  857. if (!empty($this->errors))
  858. {
  859. // if we have errors, we stay on the form instead of going back to the list
  860. $this->display = 'edit';
  861. return false;
  862. }
  863.  
  864. if (isset($object))
  865. return $object;
  866. return;
  867. }
  868.  
  869. /**
  870. * Change object required fields
  871. */
  872. public function processUpdateFields()
  873. {
  874. if (!is_array($fields = Tools::getValue('fieldsBox')))
  875. $fields = array();
  876.  
  877. $object = new $this->className();
  878. if (!$object->addFieldsRequiredDatabase($fields))
  879. $this->errors[] = Tools::displayError('An error occurred when attempting to update the required fields.');
  880. else
  881. $this->redirect_after = self::$currentIndex.'&conf=4&token='.$this->token;
  882.  
  883. return $object;
  884. }
  885.  
  886. /**
  887. * Change object status (active, inactive)
  888. */
  889. public function processStatus()
  890. {
  891. if (Validate::isLoadedObject($object = $this->loadObject()))
  892. {
  893. if ($object->toggleStatus())
  894. {
  895. $id_category = (($id_category = (int)Tools::getValue('id_category')) && Tools::getValue('id_product')) ? '&id_category='.$id_category : '';
  896. $this->redirect_after = self::$currentIndex.'&conf=5'.$id_category.'&token='.$this->token;
  897. }
  898. else
  899. $this->errors[] = Tools::displayError('An error occurred while updating the status.');
  900. }
  901. else
  902. $this->errors[] = Tools::displayError('An error occurred while updating the status for an object.').
  903. ' <b>'.$this->table.'</b> '.
  904. Tools::displayError('(cannot load object)');
  905.  
  906. return $object;
  907. }
  908.  
  909. /**
  910. * Change object position
  911. */
  912. public function processPosition()
  913. {
  914. if (!Validate::isLoadedObject($object = $this->loadObject()))
  915. {
  916. $this->errors[] = Tools::displayError('An error occurred while updating the status for an object.').
  917. ' <b>'.$this->table.'</b> '.Tools::displayError('(cannot load object)');
  918. }
  919. elseif (!$object->updatePosition((int)Tools::getValue('way'), (int)Tools::getValue('position')))
  920. $this->errors[] = Tools::displayError('Failed to update the position.');
  921. else
  922. {
  923. $id_identifier_str = ($id_identifier = (int)Tools::getValue($this->identifier)) ? '&'.$this->identifier.'='.$id_identifier : '';
  924. $redirect = self::$currentIndex.'&'.$this->table.'Orderby=position&'.$this->table.'Orderway=asc&conf=5'.$id_identifier_str.'&token='.$this->token;
  925. $this->redirect_after = $redirect;
  926. }
  927. return $object;
  928. }
  929.  
  930. /**
  931. * Cancel all filters for this tab
  932. */
  933. public function processResetFilters($list_id = null)
  934. {
  935. if (!isset($list_id))
  936. $list_id = isset($this->list_id) ? $this->list_id : $this->table;
  937.  
  938. $prefix = str_replace(array('admin', 'controller'), '', Tools::strtolower(get_class($this)));
  939. $filters = $this->context->cookie->getFamily($prefix.$list_id.'Filter_');
  940.  
  941. foreach ($filters as $cookie_key => $filter)
  942. if (strncmp($cookie_key, $prefix.$list_id.'Filter_', 7 + Tools::strlen($prefix.$list_id)) == 0)
  943. {
  944. $key = substr($cookie_key, 7 + Tools::strlen($prefix.$list_id));
  945.  
  946. if (is_array($this->fields_list) && array_key_exists($key, $this->fields_list))
  947. $this->context->cookie->$cookie_key = null;
  948. unset($this->context->cookie->$cookie_key);
  949. }
  950.  
  951. if (isset($this->context->cookie->{'submitFilter'.$list_id}))
  952. unset($this->context->cookie->{'submitFilter'.$list_id});
  953.  
  954. if (isset($this->context->cookie->{$prefix.$list_id.'Orderby'}))
  955. unset($this->context->cookie->{$prefix.$list_id.'Orderby'});
  956.  
  957. if (isset($this->context->cookie->{$prefix.$list_id.'Orderway'}))
  958. unset($this->context->cookie->{$prefix.$list_id.'Orderway'});
  959.  
  960. unset($_POST);
  961. $this->_filter = false;
  962. unset($this->_filterHaving);
  963. unset($this->_having);
  964. }
  965.  
  966. /**
  967. * Update options and preferences
  968. */
  969. protected function processUpdateOptions()
  970. {
  971. $this->beforeUpdateOptions();
  972.  
  973. $languages = Language::getLanguages(false);
  974.  
  975. $hide_multishop_checkbox = (Shop::getTotalShops(false, null) < 2) ? true : false;
  976. foreach ($this->fields_options as $category_data)
  977. {
  978. if (!isset($category_data['fields']))
  979. continue;
  980.  
  981. $fields = $category_data['fields'];
  982.  
  983. foreach ($fields as $field => $values)
  984. {
  985. if (isset($values['type']) && $values['type'] == 'selectLang')
  986. {
  987. foreach ($languages as $lang)
  988. if (Tools::getValue($field.'_'.strtoupper($lang['iso_code'])))
  989. $fields[$field.'_'.strtoupper($lang['iso_code'])] = array(
  990. 'type' => 'select',
  991. 'cast' => 'strval',
  992. 'identifier' => 'mode',
  993. 'list' => $values['list']
  994. );
  995. }
  996. }
  997.  
  998. // Validate fields
  999. foreach ($fields as $field => $values)
  1000. {
  1001. // We don't validate fields with no visibility
  1002. if (!$hide_multishop_checkbox && Shop::isFeatureActive() && isset($values['visibility']) && $values['visibility'] > Shop::getContext())
  1003. continue;
  1004.  
  1005. // Check if field is required
  1006. if ((!Shop::isFeatureActive() && isset($values['required']) && $values['required'])
  1007. || (Shop::isFeatureActive() && isset($_POST['multishopOverrideOption'][$field]) && isset($values['required']) && $values['required']))
  1008. if (isset($values['type']) && $values['type'] == 'textLang')
  1009. {
  1010. foreach ($languages as $language)
  1011. if (($value = Tools::getValue($field.'_'.$language['id_lang'])) == false && (string)$value != '0')
  1012. $this->errors[] = sprintf(Tools::displayError('field %s is required.'), $values['title']);
  1013. }
  1014. elseif (($value = Tools::getValue($field)) == false && (string)$value != '0')
  1015. $this->errors[] = sprintf(Tools::displayError('field %s is required.'), $values['title']);
  1016.  
  1017. // Check field validator
  1018. if (isset($values['type']) && $values['type'] == 'textLang')
  1019. {
  1020. foreach ($languages as $language)
  1021. if (Tools::getValue($field.'_'.$language['id_lang']) && isset($values['validation']))
  1022. if (!Validate::$values['validation'](Tools::getValue($field.'_'.$language['id_lang'])))
  1023. $this->errors[] = sprintf(Tools::displayError('field %s is invalid.'), $values['title']);
  1024. }
  1025. elseif (Tools::getValue($field) && isset($values['validation']))
  1026. if (!Validate::$values['validation'](Tools::getValue($field)))
  1027. $this->errors[] = sprintf(Tools::displayError('field %s is invalid.'), $values['title']);
  1028.  
  1029. // Set default value
  1030. if (Tools::getValue($field) === false && isset($values['default']))
  1031. $_POST[$field] = $values['default'];
  1032. }
  1033.  
  1034. if (!count($this->errors))
  1035. {
  1036. foreach ($fields as $key => $options)
  1037. {
  1038. if (!$hide_multishop_checkbox && Shop::isFeatureActive() && isset($options['visibility']) && $options['visibility'] > Shop::getContext())
  1039. continue;
  1040.  
  1041. if (!$hide_multishop_checkbox && Shop::isFeatureActive() && Shop::getContext() != Shop::CONTEXT_ALL && empty($options['no_multishop_checkbox']) && empty($_POST['multishopOverrideOption'][$key]))
  1042. {
  1043. Configuration::deleteFromContext($key);
  1044. continue;
  1045. }
  1046.  
  1047. // check if a method updateOptionFieldName is available
  1048. $method_name = 'updateOption'.Tools::toCamelCase($key, true);
  1049. if (method_exists($this, $method_name))
  1050. $this->$method_name(Tools::getValue($key));
  1051. elseif (isset($options['type']) && in_array($options['type'], array('textLang', 'textareaLang')))
  1052. {
  1053. $list = array();
  1054. foreach ($languages as $language)
  1055. {
  1056. $key_lang = Tools::getValue($key.'_'.$language['id_lang']);
  1057. $val = (isset($options['cast']) ? $options['cast']($key_lang) : $key_lang);
  1058. if ($this->validateField($val, $options))
  1059. {
  1060. if (Validate::isCleanHtml($val))
  1061. $list[$language['id_lang']] = $val;
  1062. else
  1063. $this->errors[] = Tools::displayError('Can not add configuration '.$key.' for lang '.Language::getIsoById((int)$language['id_lang']));
  1064. }
  1065. }
  1066. Configuration::updateValue($key, $list);
  1067. }
  1068. else
  1069. {
  1070. $val = (isset($options['cast']) ? $options['cast'](Tools::getValue($key)) : Tools::getValue($key));
  1071. if ($this->validateField($val, $options))
  1072. {
  1073. if (Validate::isCleanHtml($val))
  1074. Configuration::updateValue($key, $val);
  1075. else
  1076. $this->errors[] = Tools::displayError('Can not add configuration '.$key);
  1077. }
  1078. }
  1079. }
  1080. }
  1081. }
  1082.  
  1083. $this->display = 'list';
  1084. if (empty($this->errors))
  1085. $this->confirmations[] = $this->_conf[6];
  1086. }
  1087.  
  1088. /**
  1089. * assign default action in toolbar_btn smarty var, if they are not set.
  1090. * uses override to specifically add, modify or remove items
  1091. *
  1092. */
  1093. public function initToolbar()
  1094. {
  1095. switch ($this->display)
  1096. {
  1097. case 'add':
  1098. case 'edit':
  1099. // Default save button - action dynamically handled in javascript
  1100. $this->toolbar_btn['save'] = array(
  1101. 'href' => '#',
  1102. 'desc' => $this->l('Save')
  1103. );
  1104. //no break
  1105. case 'view':
  1106. // Default cancel button - like old back link
  1107. $back = Tools::safeOutput(Tools::getValue('back', ''));
  1108. if (empty($back))
  1109. $back = self::$currentIndex.'&token='.$this->token;
  1110. if (!Validate::isCleanHtml($back))
  1111. die(Tools::displayError());
  1112. if (!$this->lite_display)
  1113. $this->toolbar_btn['back'] = array(
  1114. 'href' => $back,
  1115. 'desc' => $this->l('Back to list')
  1116. );
  1117. break;
  1118. case 'options':
  1119. $this->toolbar_btn['save'] = array(
  1120. 'href' => '#',
  1121. 'desc' => $this->l('Save')
  1122. );
  1123. break;
  1124. case 'view':
  1125. break;
  1126. default: // list
  1127. $this->toolbar_btn['new'] = array(
  1128. 'href' => self::$currentIndex.'&amp;add'.$this->table.'&amp;token='.$this->token,
  1129. 'desc' => $this->l('Add new')
  1130. );
  1131. if ($this->allow_export)
  1132. $this->toolbar_btn['export'] = array(
  1133. 'href' => self::$currentIndex.'&amp;export'.$this->table.'&amp;token='.$this->token,
  1134. 'desc' => $this->l('Export')
  1135. );
  1136. }
  1137. $this->addToolBarModulesListButton();
  1138. }
  1139.  
  1140. /**
  1141. * Load class object using identifier in $_GET (if possible)
  1142. * otherwise return an empty object, or die
  1143. *
  1144. * @param boolean $opt Return an empty object if load fail
  1145. * @return object
  1146. */
  1147. protected function loadObject($opt = false)
  1148. {
  1149. if (!isset($this->className) || empty($this->className))
  1150. return true;
  1151. $id = (int)Tools::getValue($this->identifier);
  1152. if ($id && Validate::isUnsignedId($id))
  1153. {
  1154. if (!$this->object)
  1155. $this->object = new $this->className($id);
  1156. if (Validate::isLoadedObject($this->object))
  1157. return $this->object;
  1158. // throw exception
  1159. $this->errors[] = Tools::displayError('The object cannot be loaded (or found)');
  1160. return false;
  1161. }
  1162. elseif ($opt)
  1163. {
  1164. if (!$this->object)
  1165. $this->object = new $this->className();
  1166. return $this->object;
  1167. }
  1168. else
  1169. {
  1170. $this->errors[] = Tools::displayError('The object cannot be loaded (the dentifier is missing or invalid)');
  1171. return false;
  1172. }
  1173.  
  1174. return $this->object;
  1175. }
  1176.  
  1177. /**
  1178. * Check if the token is valid, else display a warning page
  1179. */
  1180. public function checkAccess()
  1181. {
  1182. if (!$this->checkToken())
  1183. {
  1184. // If this is an XSS attempt, then we should only display a simple, secure page
  1185. // ${1} in the replacement string of the regexp is required,
  1186. // because the token may begin with a number and mix up with it (e.g. $17)
  1187. $url = preg_replace('/([&?]token=)[^&]*(&.*)?$/', '${1}'.$this->token.'$2', $_SERVER['REQUEST_URI']);
  1188. if (false === strpos($url, '?token=') && false === strpos($url, '&token='))
  1189. $url .= '&token='.$this->token;
  1190. if (strpos($url, '?') === false)
  1191. $url = str_replace('&token', '?controller=AdminHome&token', $url);
  1192.  
  1193. $this->context->smarty->assign('url', htmlentities($url));
  1194. return false;
  1195. }
  1196. return true;
  1197. }
  1198.  
  1199. protected function filterToField($key, $filter)
  1200. {
  1201. if (!isset($this->fields_list))
  1202. return false;
  1203.  
  1204. foreach ($this->fields_list as $field)
  1205. if (array_key_exists('filter_key', $field) && $field['filter_key'] == $key)
  1206. return $field;
  1207. if (array_key_exists($filter, $this->fields_list))
  1208. return $this->fields_list[$filter];
  1209. return false;
  1210. }
  1211.  
  1212. public function displayNoSmarty()
  1213. {
  1214. }
  1215.  
  1216. public function displayAjax()
  1217. {
  1218. if ($this->json)
  1219. {
  1220. $this->context->smarty->assign(array(
  1221. 'json' => true,
  1222. 'status' => $this->status,
  1223. ));
  1224. }
  1225. $this->layout = 'layout-ajax.tpl';
  1226. return $this->display();
  1227. }
  1228.  
  1229. protected function redirect()
  1230. {
  1231. header('Location: '.$this->redirect_after);
  1232. exit;
  1233. }
  1234.  
  1235. public function display()
  1236. {
  1237. $this->context->smarty->assign(array(
  1238. 'display_header' => $this->display_header,
  1239. 'display_footer' => $this->display_footer,
  1240. )
  1241. );
  1242.  
  1243. // Use page title from meta_title if it has been set else from the breadcrumbs array
  1244. if (!$this->meta_title)
  1245. $this->meta_title = isset($this->breadcrumbs[1]) ? $this->breadcrumbs[1] : $this->breadcrumbs[0];
  1246. $this->context->smarty->assign('meta_title', $this->meta_title);
  1247.  
  1248. $tpl_action = $this->tpl_folder.$this->display.'.tpl';
  1249.  
  1250. // Check if action template has been overriden
  1251. foreach ($this->context->smarty->getTemplateDir() as $template_dir)
  1252. if (file_exists($template_dir.DIRECTORY_SEPARATOR.$tpl_action) && $this->display != 'view' && $this->display != 'options')
  1253. {
  1254. if (method_exists($this, $this->display.Tools::toCamelCase($this->className)))
  1255. $this->{$this->display.Tools::toCamelCase($this->className)}();
  1256. $this->context->smarty->assign('content', $this->context->smarty->fetch($tpl_action));
  1257. break;
  1258. }
  1259.  
  1260. if (!$this->ajax)
  1261. {
  1262. $template = $this->createTemplate($this->template);
  1263. $page = $template->fetch();
  1264. }
  1265. else
  1266. $page = $this->content;
  1267.  
  1268. if ($conf = Tools::getValue('conf'))
  1269. $this->context->smarty->assign('conf', $this->json ? Tools::jsonEncode($this->_conf[(int)$conf]) : $this->_conf[(int)$conf]);
  1270.  
  1271. foreach (array('errors', 'warnings', 'informations', 'confirmations') as $type)
  1272. $this->context->smarty->assign($type, $this->json ? Tools::jsonEncode(array_unique($this->$type)) : array_unique($this->$type));
  1273.  
  1274. $this->context->smarty->assign('page', $this->json ? Tools::jsonEncode($page) : $page);
  1275. $this->smartyOutputContent($this->layout);
  1276. }
  1277.  
  1278. /**
  1279. * add a warning message to display at the top of the page
  1280. *
  1281. * @param string $msg
  1282. */
  1283. protected function displayWarning($msg)
  1284. {
  1285. $this->warnings[] = $msg;
  1286. }
  1287.  
  1288. /**
  1289. * add a info message to display at the top of the page
  1290. *
  1291. * @param string $msg
  1292. */
  1293. protected function displayInformation($msg)
  1294. {
  1295. $this->informations[] = $msg;
  1296. }
  1297.  
  1298. /**
  1299. * Assign smarty variables for the header
  1300. */
  1301. public function initHeader()
  1302. {
  1303. // Multishop
  1304. $is_multishop = Shop::isFeatureActive();
  1305.  
  1306. // Quick access
  1307. $quick_access = QuickAccess::getQuickAccesses($this->context->language->id);
  1308. foreach ($quick_access as $index => $quick)
  1309. {
  1310. if ($quick['link'] == '../' && Shop::getContext() == Shop::CONTEXT_SHOP)
  1311. {
  1312. $url = $this->context->shop->getBaseURL();
  1313. if (!$url)
  1314. {
  1315. unset($quick_access[$index]);
  1316. continue;
  1317. }
  1318. $quick_access[$index]['link'] = $url;
  1319. }
  1320. else
  1321. {
  1322. preg_match('/controller=(.+)(&.+)?$/', $quick['link'], $admin_tab);
  1323. if (isset($admin_tab[1]))
  1324. {
  1325. if (strpos($admin_tab[1], '&'))
  1326. $admin_tab[1] = substr($admin_tab[1], 0, strpos($admin_tab[1], '&'));
  1327.  
  1328. $token = Tools::getAdminToken($admin_tab[1].(int)Tab::getIdFromClassName($admin_tab[1]).(int)$this->context->employee->id);
  1329. $quick_access[$index]['link'] .= '&token='.$token;
  1330. }
  1331. }
  1332. }
  1333.  
  1334. // Tab list
  1335. $tabs = Tab::getTabs($this->context->language->id, 0);
  1336. $current_id = Tab::getCurrentParentId();
  1337. foreach ($tabs as $index => $tab)
  1338. {
  1339. if (($tab['class_name'] == 'AdminStock' && Configuration::get('PS_ADVANCED_STOCK_MANAGEMENT') == 0) || $tab['class_name'] == 'AdminCarrierWizard')
  1340. {
  1341. unset($tabs[$index]);
  1342. continue;
  1343. }
  1344.  
  1345. $img_cache_url = 'themes/'.$this->context->employee->bo_theme.'/img/t/'.$tab['class_name'].'.png';
  1346. $img_exists_cache = Tools::file_exists_cache(_PS_ADMIN_DIR_.$img_cache_url);
  1347. // retrocompatibility : change png to gif if icon not exists
  1348. if (!$img_exists_cache)
  1349. $img_exists_cache = Tools::file_exists_cache(_PS_ADMIN_DIR_.str_replace('.png', '.gif', $img_cache_url));
  1350.  
  1351. if ($img_exists_cache)
  1352. $path_img = $img = $img_exists_cache;
  1353. else
  1354. {
  1355. $path_img = _PS_IMG_DIR_.'t/'.$tab['class_name'].'.png';
  1356. // Relative link will always work, whatever the base uri set in the admin
  1357. $img = '../img/t/'.$tab['class_name'].'.png';
  1358. }
  1359.  
  1360. if (trim($tab['module']) != '')
  1361. {
  1362. $path_img = _PS_MODULE_DIR_.$tab['module'].'/'.$tab['class_name'].'.png';
  1363. // Relative link will always work, whatever the base uri set in the admin
  1364. $img = '../modules/'.$tab['module'].'/'.$tab['class_name'].'.png';
  1365. }
  1366.  
  1367. // retrocompatibility
  1368. if (!file_exists($path_img))
  1369. $img = str_replace('png', 'gif', $img);
  1370. // tab[class_name] does not contains the "Controller" suffix
  1371. $tabs[$index]['current'] = ($tab['class_name'].'Controller' == get_class($this)) || ($current_id == $tab['id_tab']);
  1372. $tabs[$index]['img'] = $img;
  1373. $tabs[$index]['href'] = $this->context->link->getAdminLink($tab['class_name']);
  1374.  
  1375. $sub_tabs = Tab::getTabs($this->context->language->id, $tab['id_tab']);
  1376. foreach ($sub_tabs as $index2 => $sub_tab)
  1377. {
  1378. // class_name is the name of the class controller
  1379. if (Tab::checkTabRights($sub_tab['id_tab']) === true && (bool)$sub_tab['active'] && $sub_tab['class_name'] != 'AdminCarrierWizard')
  1380. {
  1381. $sub_tabs[$index2]['href'] = $this->context->link->getAdminLink($sub_tab['class_name']);
  1382. $sub_tabs[$index2]['current'] = ($sub_tab['class_name'].'Controller' == get_class($this));
  1383. }
  1384. else
  1385. unset($sub_tabs[$index2]);
  1386. }
  1387. $tabs[$index]['sub_tabs'] = $sub_tabs;
  1388.  
  1389. // If there are no subtabs, we don't want to display the parent tab in menu
  1390. if (empty($sub_tabs))
  1391. unset($tabs[$index]);
  1392. }
  1393.  
  1394. if (Validate::isLoadedObject($this->context->employee))
  1395. {
  1396. $accesses = Profile::getProfileAccesses($this->context->employee->id_profile, 'class_name');
  1397.  
  1398. /* Hooks are volontary out the initialize array (need those variables already assigned) */
  1399. $bo_color = empty($this->context->employee->bo_color) ? '#FFFFFF' : $this->context->employee->bo_color;
  1400. $this->context->smarty->assign(array(
  1401. 'autorefresh_notifications' => Configuration::get('PS_ADMIN_REFRESH_NOTIFICATION'),
  1402. 'help_box' => Configuration::get('PS_HELPBOX'),
  1403. 'round_mode' => Configuration::get('PS_PRICE_ROUND_MODE'),
  1404. 'brightness' => Tools::getBrightness($bo_color) < 128 ? 'white' : '#383838',
  1405. 'bo_width' => (int)$this->context->employee->bo_width,
  1406. 'bo_color' => isset($this->context->employee->bo_color) ? Tools::htmlentitiesUTF8($this->context->employee->bo_color) : null,
  1407. 'show_new_orders' => Configuration::get('PS_SHOW_NEW_ORDERS') && $accesses['AdminOrders']['view'],
  1408. 'show_new_customers' => Configuration::get('PS_SHOW_NEW_CUSTOMERS') && $accesses['AdminCustomers']['view'],
  1409. 'show_new_messages' => Configuration::get('PS_SHOW_NEW_MESSAGES') && $accesses['AdminCustomerThreads']['view'],
  1410. 'first_name' => Tools::substr($this->context->employee->firstname, 0, 1),
  1411. 'last_name' => htmlentities($this->context->employee->lastname, ENT_COMPAT, 'UTF-8'),
  1412. 'employee' => $this->context->employee,
  1413. 'search_type' => Tools::getValue('bo_search_type'),
  1414. 'bo_query' => Tools::safeOutput(Tools::stripslashes(Tools::getValue('bo_query'))),
  1415. 'quick_access' => $quick_access,
  1416. 'multi_shop' => Shop::isFeatureActive(),
  1417. 'shop_list' => Helper::renderShopList(),
  1418. 'shop' => $this->context->shop,
  1419. 'shop_group' => new ShopGroup((int)Shop::getContextShopGroupID()),
  1420. 'current_parent_id' => (int)Tab::getCurrentParentId(),
  1421. 'tabs' => $tabs,
  1422. 'is_multishop' => $is_multishop,
  1423. 'multishop_context' => $this->multishop_context,
  1424. ));
  1425. }
  1426. $this->context->smarty->assign(array(
  1427. 'img_dir' => _PS_IMG_,
  1428. 'iso' => $this->context->language->iso_code,
  1429. 'class_name' => $this->className,
  1430. 'iso_user' => $this->context->language->iso_code,
  1431. 'country_iso_code' => $this->context->country->iso_code,
  1432. 'version' => _PS_VERSION_,
  1433. 'lang_iso' => $this->context->language->iso_code,
  1434. 'link' => $this->context->link,
  1435. 'shop_name' => Configuration::get('PS_SHOP_NAME'),
  1436. 'base_url' => $this->context->shop->getBaseURL(),
  1437. 'tab' => $tab, // Deprecated, this tab is declared in the foreach, so it's the last tab in the foreach
  1438. 'current_parent_id' => (int)Tab::getCurrentParentId(),
  1439. 'tabs' => $tabs,
  1440. 'install_dir_exists' => file_exists(_PS_ADMIN_DIR_.'/../install'),
  1441. 'pic_dir' => _THEME_PROD_PIC_DIR_,
  1442. 'controller_name' => htmlentities(Tools::getValue('controller')),
  1443. 'currentIndex' => self::$currentIndex
  1444. ));
  1445. }
  1446.  
  1447. /**
  1448. * Declare an action to use for each row in the list
  1449. */
  1450. public function addRowAction($action)
  1451. {
  1452. $action = strtolower($action);
  1453. $this->actions[] = $action;
  1454. }
  1455.  
  1456. /**
  1457. * Add an action to use for each row in the list
  1458. */
  1459. public function addRowActionSkipList($action, $list)
  1460. {
  1461. $action = strtolower($action);
  1462. $list = (array)$list;
  1463.  
  1464. if (array_key_exists($action, $this->list_skip_actions))
  1465. $this->list_skip_actions[$action] = array_merge($this->list_skip_actions[$action], $list);
  1466. else
  1467. $this->list_skip_actions[$action] = $list;
  1468. }
  1469.  
  1470. /**
  1471. * Assign smarty variables for all default views, list and form, then call other init functions
  1472. */
  1473. public function initContent()
  1474. {
  1475. if (!$this->viewAccess())
  1476. {
  1477. $this->errors[] = Tools::displayError('You do not have permission to view this.');
  1478. return;
  1479. }
  1480.  
  1481. $this->getLanguages();
  1482. // toolbar (save, cancel, new, ..)
  1483. $this->initToolbar();
  1484. $this->initTabModuleList();
  1485. if ($this->display == 'edit' || $this->display == 'add')
  1486. {
  1487. if (!$this->loadObject(true))
  1488. return;
  1489.  
  1490. $this->content .= $this->renderForm();
  1491. }
  1492. elseif ($this->display == 'view')
  1493. {
  1494. // Some controllers use the view action without an object
  1495. if ($this->className)
  1496. $this->loadObject(true);
  1497. $this->content .= $this->renderView();
  1498. }
  1499. elseif (!$this->ajax)
  1500. {
  1501. $this->content .= $this->renderModulesList();
  1502. $this->content .= $this->renderList();
  1503. $this->content .= $this->renderOptions();
  1504.  
  1505. // if we have to display the required fields form
  1506. if ($this->required_database)
  1507. $this->content .= $this->displayRequiredFields();
  1508. }
  1509.  
  1510. $this->context->smarty->assign(array(
  1511. 'content' => $this->content,
  1512. 'url_post' => self::$currentIndex.'&token='.$this->token,
  1513. ));
  1514. }
  1515.  
  1516. /**
  1517. * init tab modules list and add button in toolbar
  1518. */
  1519. protected function initTabModuleList()
  1520. {
  1521. if (!$this->isFresh(Module::CACHE_FILE_MUST_HAVE_MODULES_LIST, 86400))
  1522. @file_put_contents(_PS_ROOT_DIR_.Module::CACHE_FILE_MUST_HAVE_MODULES_LIST, Tools::addonsRequest('must-have'));
  1523. if (!$this->isFresh(Module::CACHE_FILE_TAB_MODULES_LIST, 604800))
  1524. $this->refresh(Module::CACHE_FILE_TAB_MODULES_LIST, 'http://'.Tab::TAB_MODULE_LIST_URL);
  1525.  
  1526. $this->tab_modules_list = Tab::getTabModulesList($this->id);
  1527.  
  1528. if (is_array($this->tab_modules_list['default_list']) && count($this->tab_modules_list['default_list']))
  1529. $this->filter_modules_list = $this->tab_modules_list['default_list'];
  1530. elseif (is_array($this->tab_modules_list['slider_list']) && count($this->tab_modules_list['slider_list']))
  1531. {
  1532. $this->addToolBarModulesListButton();
  1533. $this->context->smarty->assign(array(
  1534. 'tab_modules_list' => implode(',', $this->tab_modules_list['slider_list']),
  1535. 'admin_module_ajax_url' => $this->context->link->getAdminLink('AdminModules'),
  1536. 'back_tab_modules_list' => $this->context->link->getAdminLink(Tools::getValue('controller')),
  1537. 'tab_modules_open' => (int)Tools::getValue('tab_modules_open')
  1538. ));
  1539. }
  1540. }
  1541.  
  1542. protected function addToolBarModulesListButton()
  1543. {
  1544. if (!$this->isFresh(Module::CACHE_FILE_DEFAULT_COUNTRY_MODULES_LIST, 86400))
  1545. file_put_contents(_PS_ROOT_DIR_.Module::CACHE_FILE_DEFAULT_COUNTRY_MODULES_LIST, Tools::addonsRequest('native'));
  1546.  
  1547. libxml_use_internal_errors(true);
  1548. $country_module_list = file_get_contents(_PS_ROOT_DIR_.Module::CACHE_FILE_DEFAULT_COUNTRY_MODULES_LIST);
  1549. if (!empty($country_module_list) && is_string($country_module_list) && $country_module_list_xml = simplexml_load_string($country_module_list))
  1550. {
  1551. $country_module_list_array = array();
  1552. if (isset($country_module_list_xml->module))
  1553. foreach ($country_module_list_xml->module as $k => $m)
  1554. $country_module_list_array[] = (string)$m->name;
  1555. $this->tab_modules_list['slider_list'] = array_intersect($this->tab_modules_list['slider_list'], $country_module_list_array);
  1556. }
  1557.  
  1558. if (is_array($this->tab_modules_list['slider_list']) && count($this->tab_modules_list['slider_list']))
  1559. $this->toolbar_btn['modules-list'] = array(
  1560. 'href' => '#',
  1561. 'desc' => $this->l('Modules List')
  1562. );
  1563. }
  1564.  
  1565. /**
  1566. * initialize the invalid doom page of death
  1567. *
  1568. * @return void
  1569. */
  1570. public function initCursedPage()
  1571. {
  1572. $this->layout = 'invalid_token.tpl';
  1573. }
  1574.  
  1575. /**
  1576. * Assign smarty variables for the footer
  1577. */
  1578. public function initFooter()
  1579. {
  1580. // We assign js and css files on the last step before display template, because controller can add many js and css files
  1581. $this->context->smarty->assign('css_files', $this->css_files);
  1582. $this->context->smarty->assign('js_files', array_unique($this->js_files));
  1583.  
  1584. $this->context->smarty->assign(array(
  1585. 'ps_version' => _PS_VERSION_,
  1586. 'timer_start' => $this->timer_start,
  1587. 'iso_is_fr' => strtoupper($this->context->language->iso_code) == 'FR',
  1588. ));
  1589. }
  1590.  
  1591. public function renderModulesList()
  1592. {
  1593. if ($this->getModulesList($this->filter_modules_list))
  1594. {
  1595. $helper = new Helper();
  1596. return $helper->renderModulesList($this->modules_list);
  1597. }
  1598. }
  1599.  
  1600.  
  1601. /**
  1602. * Function used to render the list to display for this controller
  1603. */
  1604. public function renderList()
  1605. {
  1606. if (!($this->fields_list && is_array($this->fields_list)))
  1607. return false;
  1608. $this->getList($this->context->language->id);
  1609.  
  1610. $helper = new HelperList();
  1611.  
  1612. // Empty list is ok
  1613. if (!is_array($this->_list))
  1614. {
  1615. $this->displayWarning($this->l('Bad SQL query', 'Helper').'<br />'.htmlspecialchars($this->_list_error));
  1616. return false;
  1617. }
  1618.  
  1619. $this->setHelperDisplay($helper);
  1620. $helper->tpl_vars = $this->tpl_list_vars;
  1621. $helper->tpl_delete_link_vars = $this->tpl_delete_link_vars;
  1622.  
  1623. // For compatibility reasons, we have to check standard actions in class attributes
  1624. foreach ($this->actions_available as $action)
  1625. {
  1626. if (!in_array($action, $this->actions) && isset($this->$action) && $this->$action)
  1627. $this->actions[] = $action;
  1628. }
  1629. $helper->is_cms = $this->is_cms;
  1630. $list = $helper->generateList($this->_list, $this->fields_list);
  1631.  
  1632. return $list;
  1633. }
  1634.  
  1635. /**
  1636. * Override to render the view page
  1637. */
  1638. public function renderView()
  1639. {
  1640. $helper = new HelperView($this);
  1641. $this->setHelperDisplay($helper);
  1642. $helper->tpl_vars = $this->tpl_view_vars;
  1643. if (!is_null($this->base_tpl_view))
  1644. $helper->base_tpl = $this->base_tpl_view;
  1645. $view = $helper->generateView();
  1646.  
  1647. return $view;
  1648. }
  1649.  
  1650. /**
  1651. * Function used to render the form for this controller
  1652. */
  1653. public function renderForm()
  1654. {
  1655. if (!$this->default_form_language)
  1656. $this->getLanguages();
  1657.  
  1658. if (Tools::getValue('submitFormAjax'))
  1659. $this->content .= $this->context->smarty->fetch('form_submit_ajax.tpl');
  1660. if ($this->fields_form && is_array($this->fields_form))
  1661. {
  1662. if (!$this->multiple_fieldsets)
  1663. $this->fields_form = array(array('form' => $this->fields_form));
  1664.  
  1665. // For add a fields via an override of $fields_form, use $fields_form_override
  1666. if (is_array($this->fields_form_override) && !empty($this->fields_form_override))
  1667. $this->fields_form[0]['form']['input'][] = $this->fields_form_override;
  1668.  
  1669. $helper = new HelperForm($this);
  1670. $this->setHelperDisplay($helper);
  1671. $helper->fields_value = $this->getFieldsValue($this->object);
  1672. $helper->tpl_vars = $this->tpl_form_vars;
  1673. !is_null($this->base_tpl_form) ? $helper->base_tpl = $this->base_tpl_form : '';
  1674. if ($this->tabAccess['view'])
  1675. {
  1676. if (Tools::getValue('back'))
  1677. $helper->tpl_vars['back'] = Tools::safeOutput(Tools::getValue('back'));
  1678. else
  1679. $helper->tpl_vars['back'] = Tools::safeOutput(Tools::getValue(self::$currentIndex.'&token='.$this->token));
  1680. }
  1681. $form = $helper->generateForm($this->fields_form);
  1682.  
  1683. return $form;
  1684. }
  1685. }
  1686.  
  1687. /**
  1688. * Function used to render the options for this controller
  1689. */
  1690. public function renderOptions()
  1691. {
  1692. if ($this->fields_options && is_array($this->fields_options))
  1693. {
  1694. if (isset($this->display) && $this->display != 'options' && $this->display != 'list')
  1695. $this->show_toolbar = false;
  1696. else
  1697. $this->display = 'options';
  1698.  
  1699. unset($this->toolbar_btn);
  1700. $this->initToolbar();
  1701. $helper = new HelperOptions($this);
  1702. $this->setHelperDisplay($helper);
  1703. $helper->id = $this->id;
  1704. $helper->tpl_vars = $this->tpl_option_vars;
  1705. $options = $helper->generateOptions($this->fields_options);
  1706.  
  1707. return $options;
  1708. }
  1709. }
  1710.  
  1711. /**
  1712. * this function set various display option for helper list
  1713. *
  1714. * @param Helper $helper
  1715. * @return void
  1716. */
  1717. public function setHelperDisplay(Helper $helper)
  1718. {
  1719. if (empty($this->toolbar_title))
  1720. $this->initToolbarTitle();
  1721. // tocheck
  1722. if ($this->object && $this->object->id)
  1723. $helper->id = $this->object->id;
  1724.  
  1725. // @todo : move that in Helper
  1726. $helper->title = $this->toolbar_title;
  1727. $helper->toolbar_btn = $this->toolbar_btn;
  1728. $helper->show_toolbar = $this->show_toolbar;
  1729. $helper->toolbar_scroll = $this->toolbar_scroll;
  1730. $helper->override_folder = $this->tpl_folder;
  1731. $helper->actions = $this->actions;
  1732. $helper->simple_header = $this->list_simple_header;
  1733. $helper->bulk_actions = $this->bulk_actions;
  1734. $helper->currentIndex = self::$currentIndex;
  1735. $helper->className = $this->className;
  1736. $helper->table = $this->table;
  1737. $helper->name_controller = Tools::getValue('controller');
  1738. $helper->orderBy = $this->_orderBy;
  1739. $helper->orderWay = $this->_orderWay;
  1740. $helper->listTotal = $this->_listTotal;
  1741. $helper->shopLink = $this->shopLink;
  1742. $helper->shopLinkType = $this->shopLinkType;
  1743. $helper->identifier = $this->identifier;
  1744. $helper->token = $this->token;
  1745. $helper->languages = $this->_languages;
  1746. $helper->specificConfirmDelete = $this->specificConfirmDelete;
  1747. $helper->imageType = $this->imageType;
  1748. $helper->no_link = $this->list_no_link;
  1749. $helper->colorOnBackground = $this->colorOnBackground;
  1750. $helper->ajax_params = (isset($this->ajax_params) ? $this->ajax_params : null);
  1751. $helper->default_form_language = $this->default_form_language;
  1752. $helper->allow_employee_form_lang = $this->allow_employee_form_lang;
  1753. $helper->multiple_fieldsets = $this->multiple_fieldsets;
  1754. $helper->row_hover = $this->row_hover;
  1755. $helper->position_identifier = $this->position_identifier;
  1756. $helper->controller_name = $this->controller_name;
  1757. $helper->list_id = isset($this->list_id) ? $this->list_id : $this->table;
  1758.  
  1759. // For each action, try to add the corresponding skip elements list
  1760. $helper->list_skip_actions = $this->list_skip_actions;
  1761.  
  1762. $this->helper = $helper;
  1763. }
  1764.  
  1765. public function setMedia()
  1766. {
  1767. $this->addCSS(_PS_CSS_DIR_.'admin.css', 'all');
  1768. $admin_webpath = str_ireplace(_PS_ROOT_DIR_, '', _PS_ADMIN_DIR_);
  1769. $admin_webpath = preg_replace('/^'.preg_quote(DIRECTORY_SEPARATOR, '/').'/', '', $admin_webpath);
  1770. $this->addCSS(__PS_BASE_URI__.$admin_webpath.'/themes/'.$this->bo_theme.'/css/admin.css', 'all');
  1771. if ($this->context->language->is_rtl)
  1772. $this->addCSS(_THEME_CSS_DIR_.'rtl.css');
  1773.  
  1774. $this->addJquery();
  1775. $this->addjQueryPlugin(array('cluetip', 'hoverIntent', 'scrollTo', 'alerts', 'chosen'));
  1776.  
  1777. $this->addJS(array(
  1778. _PS_JS_DIR_.'admin.js',
  1779. _PS_JS_DIR_.'toggle.js',
  1780. _PS_JS_DIR_.'tools.js',
  1781. _PS_JS_DIR_.'ajax.js',
  1782. _PS_JS_DIR_.'toolbar.js'
  1783. ));
  1784.  
  1785. if (!Tools::getValue('submitFormAjax'))
  1786. {
  1787. $this->addJs(_PS_JS_DIR_.'notifications.js');
  1788. if (Configuration::get('PS_HELPBOX'))
  1789. $this->addJS(_PS_JS_DIR_.'helpAccess.js');
  1790. }
  1791.  
  1792. // Execute Hook AdminController SetMedia
  1793. Hook::exec('actionAdminControllerSetMedia', array());
  1794. }
  1795.  
  1796. /**
  1797. * non-static method which uses AdminController::translate()
  1798. *
  1799. * @param mixed $string term or expression in english
  1800. * @param string $class name of the class
  1801. * @param boolan $addslashes if set to true, the return value will pass through addslashes(). Otherwise, stripslashes().
  1802. * @param boolean $htmlentities if set to true(default), the return value will pass through htmlentities($string, ENT_QUOTES, 'utf-8')
  1803. * @return string the translation if available, or the english default text.
  1804. */
  1805. protected function l($string, $class = 'AdminTab', $addslashes = false, $htmlentities = true)
  1806. {
  1807. // classname has changed, from AdminXXX to AdminXXXController
  1808. // So we remove 10 characters and we keep same keys
  1809. if (strtolower(substr($class, -10)) == 'controller')
  1810. $class = substr($class, 0, -10);
  1811. elseif ($class == 'AdminTab')
  1812. $class = substr(get_class($this), 0, -10);
  1813. return Translate::getAdminTranslation($string, $class, $addslashes, $htmlentities);
  1814. }
  1815.  
  1816. /**
  1817. * Init context and dependencies, handles POST and GET
  1818. */
  1819. public function init()
  1820. {
  1821. // Has to be removed for the next Prestashop version
  1822. global $currentIndex;
  1823.  
  1824. parent::init();
  1825.  
  1826. if (Tools::getValue('ajax'))
  1827. $this->ajax = '1';
  1828.  
  1829. /* Server Params */
  1830. $protocol_link = (Tools::usingSecureMode() && Configuration::get('PS_SSL_ENABLED')) ? 'https://' : 'http://';
  1831. $protocol_content = (Tools::usingSecureMode() && Configuration::get('PS_SSL_ENABLED')) ? 'https://' : 'http://';
  1832.  
  1833. $this->context->link = new Link($protocol_link, $protocol_content);
  1834.  
  1835. if (isset($_GET['logout'])){
  1836. Logger::addLog(sprintf($this->l('Back Office desconnection from %s', 'AdminTab', false, false), Tools::getRemoteAddr()), 1, null, '', 0, true, (int)$this->context->employee->id);
  1837. $this->context->employee->logout();
  1838. }
  1839.  
  1840. if ($this->controller_name != 'AdminLogin' && (!isset($this->context->employee) || !$this->context->employee->isLoggedBack()))
  1841. {
  1842. if (isset($this->context->employee)){
  1843. $this->context->employee->logout();
  1844. }
  1845. Tools::redirectAdmin($this->context->link->getAdminLink('AdminLogin').((!isset($_GET['logout']) && $this->controller_name != 'AdminNotFound') ? '&redirect='.$this->controller_name : ''));
  1846. }
  1847.  
  1848. // Set current index
  1849. $current_index = 'index.php'.(($controller = Tools::getValue('controller')) ? '?controller='.$controller : '');
  1850. if ($back = Tools::getValue('back'))
  1851. $current_index .= '&back='.urlencode($back);
  1852. self::$currentIndex = $current_index;
  1853. $currentIndex = $current_index;
  1854.  
  1855. if ((int)Tools::getValue('liteDisplaying'))
  1856. {
  1857. $this->display_header = false;
  1858. $this->display_footer = false;
  1859. $this->content_only = false;
  1860. $this->lite_display = true;
  1861. }
  1862.  
  1863. if ($this->ajax && method_exists($this, 'ajaxPreprocess'))
  1864. $this->ajaxPreProcess();
  1865.  
  1866. $this->context->smarty->assign(array(
  1867. 'table' => $this->table,
  1868. 'current' => self::$currentIndex,
  1869. 'token' => $this->token,
  1870. 'stock_management' => (int)Configuration::get('PS_STOCK_MANAGEMENT')
  1871. ));
  1872.  
  1873. if ($this->display_header)
  1874. $this->context->smarty->assign('displayBackOfficeHeader', Hook::exec('displayBackOfficeHeader', array()));
  1875.  
  1876. $this->context->smarty->assign(
  1877. array(
  1878. 'displayBackOfficeTop' => Hook::exec('displayBackOfficeTop', array()),
  1879. 'submit_form_ajax' => (int)Tools::getValue('submitFormAjax')
  1880. )
  1881. );
  1882.  
  1883. $this->initProcess();
  1884. }
  1885.  
  1886. public function initShopContext()
  1887. {
  1888. if (!$this->context->employee->isLoggedBack())
  1889. return;
  1890.  
  1891. // Change shop context ?
  1892. if (Shop::isFeatureActive() && Tools::getValue('setShopContext') !== false)
  1893. {
  1894. $this->context->cookie->shopContext = Tools::getValue('setShopContext');
  1895. $url = parse_url($_SERVER['REQUEST_URI']);
  1896. $query = (isset($url['query'])) ? $url['query'] : '';
  1897. parse_str($query, $parse_query);
  1898. unset($parse_query['setShopContext'], $parse_query['conf']);
  1899. $this->redirect_after = $url['path'].'?'.http_build_query($parse_query, '', '&');
  1900. }
  1901. elseif (!Shop::isFeatureActive())
  1902. $this->context->cookie->shopContext = 's-'.Configuration::get('PS_SHOP_DEFAULT');
  1903. else if (Shop::getTotalShops(false, null) < 2)
  1904. $this->context->cookie->shopContext = 's-'.$this->context->employee->getDefaultShopID();
  1905.  
  1906. $shop_id = '';
  1907. Shop::setContext(Shop::CONTEXT_ALL);
  1908. if ($this->context->cookie->shopContext)
  1909. {
  1910. $split = explode('-', $this->context->cookie->shopContext);
  1911. if (count($split) == 2)
  1912. {
  1913. if ($split[0] == 'g')
  1914. {
  1915. if ($this->context->employee->hasAuthOnShopGroup($split[1]))
  1916. Shop::setContext(Shop::CONTEXT_GROUP, $split[1]);
  1917. else
  1918. {
  1919. $shop_id = $this->context->employee->getDefaultShopID();
  1920. Shop::setContext(Shop::CONTEXT_SHOP, $shop_id);
  1921. }
  1922. }
  1923. else if (Shop::getShop($split[1]) && $this->context->employee->hasAuthOnShop($split[1]))
  1924. {
  1925. $shop_id = $split[1];
  1926. Shop::setContext(Shop::CONTEXT_SHOP, $shop_id);
  1927. }
  1928. else
  1929. {
  1930. $shop_id = $this->context->employee->getDefaultShopID();
  1931. Shop::setContext(Shop::CONTEXT_SHOP, $shop_id);
  1932. }
  1933. }
  1934. }
  1935.  
  1936. // Check multishop context and set right context if need
  1937. if (!($this->multishop_context & Shop::getContext()))
  1938. {
  1939. if (Shop::getContext() == Shop::CONTEXT_SHOP && !($this->multishop_context & Shop::CONTEXT_SHOP))
  1940. Shop::setContext(Shop::CONTEXT_GROUP, Shop::getContextShopGroupID());
  1941. if (Shop::getContext() == Shop::CONTEXT_GROUP && !($this->multishop_context & Shop::CONTEXT_GROUP))
  1942. Shop::setContext(Shop::CONTEXT_ALL);
  1943. }
  1944.  
  1945. // Replace existing shop if necessary
  1946. if (!$shop_id)
  1947. $this->context->shop = new Shop(Configuration::get('PS_SHOP_DEFAULT'));
  1948. elseif ($this->context->shop->id != $shop_id)
  1949. $this->context->shop = new Shop($shop_id);
  1950.  
  1951. // Replace current default country
  1952. $this->context->country = new Country((int)Configuration::get('PS_COUNTRY_DEFAULT'));
  1953.  
  1954. $this->initBreadcrumbs();
  1955. }
  1956.  
  1957. /**
  1958. * Retrieve GET and POST value and translate them to actions
  1959. */
  1960. public function initProcess()
  1961. {
  1962. if (!isset($this->list_id))
  1963. $this->list_id = $this->table;
  1964.  
  1965. // Manage list filtering
  1966. if (Tools::isSubmit('submitFilter'.$this->list_id)
  1967. || $this->context->cookie->{'submitFilter'.$this->list_id} !== false
  1968. || Tools::getValue($this->list_id.'Orderby')
  1969. || Tools::getValue($this->list_id.'Orderway'))
  1970. $this->filter = true;
  1971.  
  1972. $this->id_object = (int)Tools::getValue($this->identifier);
  1973.  
  1974. /* Delete object image */
  1975. if (isset($_GET['deleteImage']))
  1976. {
  1977. if ($this->tabAccess['delete'] === '1')
  1978. $this->action = 'delete_image';
  1979. else
  1980. $this->errors[] = Tools::displayError('You do not have permission to delete this.');
  1981. }
  1982. /* Delete object */
  1983. elseif (isset($_GET['delete'.$this->table]))
  1984. {
  1985. if ($this->tabAccess['delete'] === '1')
  1986. $this->action = 'delete';
  1987. else
  1988. $this->errors[] = Tools::displayError('You do not have permission to delete this.');
  1989. }
  1990. /* Change object statuts (active, inactive) */
  1991. elseif ((isset($_GET['status'.$this->table]) || isset($_GET['status'])) && Tools::getValue($this->identifier))
  1992. {
  1993. if ($this->tabAccess['edit'] === '1')
  1994. $this->action = 'status';
  1995. else
  1996. $this->errors[] = Tools::displayError('You do not have permission to edit this.');
  1997. }
  1998. /* Move an object */
  1999. elseif (isset($_GET['position']))
  2000. {
  2001. if ($this->tabAccess['edit'] == '1')
  2002. $this->action = 'position';
  2003. else
  2004. $this->errors[] = Tools::displayError('You do not have permission to edit this.');
  2005. }
  2006. elseif (Tools::getValue('submitAdd'.$this->table)
  2007. || Tools::getValue('submitAdd'.$this->table.'AndStay')
  2008. || Tools::getValue('submitAdd'.$this->table.'AndPreview'))
  2009. {
  2010. // case 1: updating existing entry
  2011. if ($this->id_object)
  2012. {
  2013. if ($this->tabAccess['edit'] === '1')
  2014. {
  2015. $this->action = 'save';
  2016. if (Tools::getValue('submitAdd'.$this->table.'AndStay'))
  2017. $this->display = 'edit';
  2018. else
  2019. $this->display = 'list';
  2020. }
  2021. else
  2022. $this->errors[] = Tools::displayError('You do not have permission to edit this.');
  2023. }
  2024. // case 2: creating new entry
  2025. else
  2026. {
  2027. if ($this->tabAccess['add'] === '1')
  2028. {
  2029. $this->action = 'save';
  2030. if (Tools::getValue('submitAdd'.$this->table.'AndStay'))
  2031. $this->display = 'edit';
  2032. else
  2033. $this->display = 'list';
  2034. }
  2035. else
  2036. $this->errors[] = Tools::displayError('You do not have permission to add this.');
  2037. }
  2038. }
  2039. elseif (isset($_GET['add'.$this->table]))
  2040. {
  2041. if ($this->tabAccess['add'] === '1')
  2042. {
  2043. $this->action = 'new';
  2044. $this->display = 'add';
  2045. }
  2046. else
  2047. $this->errors[] = Tools::displayError('You do not have permission to add this.');
  2048. }
  2049. elseif (isset($_GET['update'.$this->table]) && isset($_GET[$this->identifier]))
  2050. {
  2051. $this->display = 'edit';
  2052. if ($this->tabAccess['edit'] !== '1')
  2053. $this->errors[] = Tools::displayError('You do not have permission to edit this.');
  2054. }
  2055. elseif (isset($_GET['view'.$this->table]))
  2056. {
  2057. if ($this->tabAccess['view'] === '1')
  2058. {
  2059. $this->display = 'view';
  2060. $this->action = 'view';
  2061. }
  2062. else
  2063. $this->errors[] = Tools::displayError('You do not have permission to view this.');
  2064. }
  2065. elseif (isset($_GET['export'.$this->table]))
  2066. {
  2067. if ($this->tabAccess['view'] === '1')
  2068. $this->action = 'export';
  2069. }
  2070. /* Cancel all filters for this tab */
  2071. elseif (isset($_POST['submitReset'.$this->list_id]))
  2072. $this->action = 'reset_filters';
  2073. /* Submit options list */
  2074. elseif (Tools::getValue('submitOptions'.$this->table) || Tools::getValue('submitOptions'))
  2075. {
  2076. $this->display = 'options';
  2077. if ($this->tabAccess['edit'] === '1')
  2078. $this->action = 'update_options';
  2079. else
  2080. $this->errors[] = Tools::displayError('You do not have permission to edit this.');
  2081. }
  2082. elseif (Tools::isSubmit('submitFields') && $this->required_database && $this->tabAccess['add'] === '1' && $this->tabAccess['delete'] === '1')
  2083. $this->action = 'update_fields';
  2084. elseif (is_array($this->bulk_actions))
  2085. foreach ($this->bulk_actions as $bulk_action => $params)
  2086. {
  2087. if (Tools::isSubmit('submitBulk'.$bulk_action.$this->table) || Tools::isSubmit('submitBulk'.$bulk_action))
  2088. {
  2089. if ($this->tabAccess['edit'] === '1')
  2090. {
  2091. $this->action = 'bulk'.$bulk_action;
  2092. $this->boxes = Tools::getValue($this->table.'Box');
  2093. }
  2094. else
  2095. $this->errors[] = Tools::displayError('You do not have permission to edit this.');
  2096. break;
  2097. }
  2098. elseif (Tools::isSubmit('submitBulk'))
  2099. {
  2100. if ($this->tabAccess['edit'] === '1')
  2101. {
  2102. $this->action = 'bulk'.Tools::getValue('select_submitBulk');
  2103. $this->boxes = Tools::getValue($this->table.'Box');
  2104. }
  2105. else
  2106. $this->errors[] = Tools::displayError('You do not have permission to edit this.');
  2107. break;
  2108. }
  2109. }
  2110. elseif (!empty($this->fields_options) && empty($this->fields_list))
  2111. $this->display = 'options';
  2112. }
  2113.  
  2114. /**
  2115. * Get the current objects' list form the database
  2116. *
  2117. * @param integer $id_lang Language used for display
  2118. * @param string $order_by ORDER BY clause
  2119. * @param string $_orderWay Order way (ASC, DESC)
  2120. * @param integer $start Offset in LIMIT clause
  2121. * @param integer $limit Row count in LIMIT clause
  2122. */
  2123. public function getList($id_lang, $order_by = null, $order_way = null, $start = 0, $limit = null, $id_lang_shop = false)
  2124. {
  2125.  
  2126. if (!isset($this->list_id))
  2127. $this->list_id = $this->table;
  2128.  
  2129. /* Manage default params values */
  2130. $use_limit = true;
  2131. if ($limit === false)
  2132. $use_limit = false;
  2133. elseif (empty($limit))
  2134. {
  2135. if (isset($this->context->cookie->{$this->list_id.'_pagination'}) && $this->context->cookie->{$this->list_id.'_pagination'})
  2136. $limit = $this->context->cookie->{$this->list_id.'_pagination'};
  2137. else
  2138. $limit = $this->_pagination[1];
  2139. }
  2140.  
  2141. if (!Validate::isTableOrIdentifier($this->table))
  2142. throw new PrestaShopException(sprintf('Table name %s is invalid:', $this->table));
  2143. $prefix = str_replace(array('admin', 'controller'), '', Tools::strtolower(get_class($this)));
  2144. if (empty($order_by))
  2145. {
  2146. if ($this->context->cookie->{$prefix.$this->list_id.'Orderby'})
  2147. $order_by = $this->context->cookie->{$prefix.$this->list_id.'Orderby'};
  2148. elseif ($this->_orderBy)
  2149. $order_by = $this->_orderBy;
  2150. else
  2151. $order_by = $this->_defaultOrderBy;
  2152. }
  2153.  
  2154. if (empty($order_way))
  2155. {
  2156. if ($this->context->cookie->{$prefix.$this->list_id.'Orderway'})
  2157. $order_way = $this->context->cookie->{$prefix.$this->list_id.'Orderway'};
  2158. elseif ($this->_orderWay)
  2159. $order_way = $this->_orderWay;
  2160. else
  2161. $order_way = $this->_defaultOrderWay;
  2162. }
  2163.  
  2164. $limit = (int)Tools::getValue($this->list_id.'_pagination', $limit);
  2165. $this->context->cookie->{$this->list_id.'_pagination'} = $limit;
  2166.  
  2167. /* Check params validity */
  2168. if (!Validate::isOrderBy($order_by) || !Validate::isOrderWay($order_way)
  2169. || !is_numeric($start) || !is_numeric($limit)
  2170. || !Validate::isUnsignedId($id_lang))
  2171. throw new PrestaShopException('get list params is not valid');
  2172.  
  2173. if (!isset($this->fields_list[$order_by]['order_key']) && isset($this->fields_list[$order_by]['filter_key']))
  2174. $this->fields_list[$order_by]['order_key'] = $this->fields_list[$order_by]['filter_key'];
  2175.  
  2176. if (isset($this->fields_list[$order_by]) && isset($this->fields_list[$order_by]['order_key']))
  2177. $order_by = $this->fields_list[$order_by]['order_key'];
  2178.  
  2179. /* Determine offset from current page */
  2180.  
  2181.  
  2182. if ((isset($_POST['submitFilter'.$this->list_id]) ||
  2183. isset($_POST['submitFilter'.$this->list_id.'_x']) ||
  2184. isset($_POST['submitFilter'.$this->list_id.'_y'])) &&
  2185. !empty($_POST['submitFilter'.$this->list_id]) &&
  2186. is_numeric($_POST['submitFilter'.$this->list_id]))
  2187. $start = ((int)$_POST['submitFilter'.$this->list_id] - 1) * $limit;
  2188. elseif (empty($start) && isset($this->context->cookie->{$this->list_id.'_start'}) && Tools::isSubmit('export'.$this->table))
  2189. $start = $this->context->cookie->{$this->list_id.'_start'};
  2190. else
  2191. $start = 0;
  2192.  
  2193. $this->context->cookie->{$this->list_id.'_start'} = $start;
  2194.  
  2195. /* Cache */
  2196. $this->_lang = (int)$id_lang;
  2197. $this->_orderBy = $order_by;
  2198.  
  2199. if (preg_match('/[.!]/', $order_by))
  2200. {
  2201. $order_by_split = preg_split('/[.!]/', $order_by);
  2202. $order_by = bqSQL($order_by_split[0]).'.`'.bqSQL($order_by_split[1]).'`';
  2203. }
  2204. elseif ($order_by)
  2205. $order_by = '`'.bqSQL($order_by).'`';
  2206.  
  2207. $this->_orderWay = Tools::strtoupper($order_way);
  2208.  
  2209. /* SQL table : orders, but class name is Order */
  2210. $sql_table = $this->table == 'order' ? 'orders' : $this->table;
  2211.  
  2212. // Add SQL shop restriction
  2213. $select_shop = $join_shop = $where_shop = '';
  2214. if ($this->shopLinkType)
  2215. {
  2216. $select_shop = ', shop.name as shop_name ';
  2217. $join_shop = ' LEFT JOIN '._DB_PREFIX_.$this->shopLinkType.' shop
  2218. ON a.id_'.$this->shopLinkType.' = shop.id_'.$this->shopLinkType;
  2219. $where_shop = Shop::addSqlRestriction($this->shopShareDatas, 'a', $this->shopLinkType);
  2220. }
  2221.  
  2222. if ($this->multishop_context && Shop::isTableAssociated($this->table) && !empty($this->className))
  2223. {
  2224. if (Shop::getContext() != Shop::CONTEXT_ALL || !$this->context->employee->isSuperAdmin())
  2225. {
  2226. $test_join = !preg_match('#`?'.preg_quote(_DB_PREFIX_.$this->table.'_shop').'`? *sa#', $this->_join);
  2227. if (Shop::isFeatureActive() && $test_join && Shop::isTableAssociated($this->table))
  2228. {
  2229. $this->_where .= ' AND a.'.$this->identifier.' IN (
  2230. SELECT sa.'.$this->identifier.'
  2231. FROM `'._DB_PREFIX_.$this->table.'_shop` sa
  2232. WHERE sa.id_shop IN ('.implode(', ', Shop::getContextListShopID()).')
  2233. )';
  2234. }
  2235. }
  2236. }
  2237.  
  2238. /* Query in order to get results with all fields */
  2239. $lang_join = '';
  2240. if ($this->lang)
  2241. {
  2242. $lang_join = 'LEFT JOIN `'._DB_PREFIX_.$this->table.'_lang` b ON (b.`'.$this->identifier.'` = a.`'.$this->identifier.'` AND b.`id_lang` = '.(int)$id_lang;
  2243. if ($id_lang_shop)
  2244. {
  2245. if (!Shop::isFeatureActive())
  2246. $lang_join .= ' AND b.`id_shop` = 1';
  2247. elseif (Shop::getContext() == Shop::CONTEXT_SHOP)
  2248. $lang_join .= ' AND b.`id_shop` = '.(int)$id_lang_shop;
  2249. else
  2250. $lang_join .= ' AND b.`id_shop` = a.id_shop_default';
  2251. }
  2252. $lang_join .= ')';
  2253. }
  2254.  
  2255. $having_clause = '';
  2256. if (isset($this->_filterHaving) || isset($this->_having))
  2257. {
  2258. $having_clause = ' HAVING ';
  2259. if (isset($this->_filterHaving))
  2260. $having_clause .= ltrim($this->_filterHaving, ' AND ');
  2261. if (isset($this->_having))
  2262. $having_clause .= $this->_having.' ';
  2263. }
  2264.  
  2265. $this->_listsql = '
  2266. SELECT SQL_CALC_FOUND_ROWS
  2267. '.($this->_tmpTableFilter ? ' * FROM (SELECT ' : '');
  2268.  
  2269. if ($this->explicitSelect)
  2270. {
  2271. foreach ($this->fields_list as $key => $array_value)
  2272. {
  2273. // Add it only if it is not already in $this->_select
  2274. if (isset($this->_select) && preg_match('/[\s]`?'.preg_quote($key, '/').'`?\s*,/', $this->_select))
  2275. continue;
  2276.  
  2277. if (isset($array_value['filter_key']))
  2278. $this->_listsql .= str_replace('!', '.', $array_value['filter_key']).' as '.$key.',';
  2279. elseif ($key == 'id_'.$this->table)
  2280. $this->_listsql .= 'a.`'.bqSQL($key).'`,';
  2281. elseif ($key != 'image' && !preg_match('/'.preg_quote($key, '/').'/i', $this->_select))
  2282. $this->_listsql .= '`'.bqSQL($key).'`,';
  2283. }
  2284. $this->_listsql = rtrim($this->_listsql, ',');
  2285. }
  2286. else
  2287. $this->_listsql .= ($this->lang ? 'b.*,' : '').' a.*';
  2288.  
  2289. $this->_listsql .= '
  2290. '.(isset($this->_select) ? ', '.rtrim($this->_select, ', ') : '').$select_shop.'
  2291. FROM `'._DB_PREFIX_.$sql_table.'` a
  2292. '.$lang_join.'
  2293. '.(isset($this->_join) ? $this->_join.' ' : '').'
  2294. '.$join_shop.'
  2295. WHERE 1 '.(isset($this->_where) ? $this->_where.' ' : '').($this->deleted ? 'AND a.`deleted` = 0 ' : '').
  2296. (isset($this->_filter) ? $this->_filter : '').$where_shop.'
  2297. '.(isset($this->_group) ? $this->_group.' ' : '').'
  2298. '.$having_clause.'
  2299. ORDER BY '.((str_replace('`', '', $order_by) == $this->identifier) ? 'a.' : '').$order_by.' '.pSQL($order_way).
  2300. ($this->_tmpTableFilter ? ') tmpTable WHERE 1'.$this->_tmpTableFilter : '').
  2301. (($use_limit === true) ? ' LIMIT '.(int)$start.','.(int)$limit : '');
  2302.  
  2303. $this->_listTotal = 0;
  2304. if (!($this->_list = Db::getInstance()->executeS($this->_listsql)))
  2305. $this->_list_error = Db::getInstance()->getMsgError();
  2306. else
  2307. $this->_listTotal = Db::getInstance()->getValue('SELECT FOUND_ROWS() AS `'._DB_PREFIX_.$this->table.'`');
  2308. }
  2309.  
  2310. public function getModulesList($filter_modules_list)
  2311. {
  2312. if (!is_array($filter_modules_list) && !is_null($filter_modules_list))
  2313. $filter_modules_list = array($filter_modules_list);
  2314.  
  2315. if (!count($filter_modules_list))
  2316. return false; //if there is no modules to display just return false;
  2317.  
  2318. $all_modules = Module::getModulesOnDisk(true);
  2319. $this->modules_list = array();
  2320. foreach ($all_modules as $module)
  2321. {
  2322. $perm = true;
  2323. if ($module->id)
  2324. $perm &= Module::getPermissionStatic($module->id, 'configure');
  2325. else
  2326. {
  2327. $id_admin_module = Tab::getIdFromClassName('AdminModules');
  2328. $access = Profile::getProfileAccess($this->context->employee->id_profile, $id_admin_module);
  2329. if (!$access['edit'])
  2330. $perm &= false;
  2331. }
  2332.  
  2333. if (in_array($module->name, $filter_modules_list) && $perm)
  2334. {
  2335. $this->fillModuleData($module, 'select');
  2336. $this->modules_list[array_search($module->name, $filter_modules_list)] = $module;
  2337. }
  2338. }
  2339. ksort($this->modules_list);
  2340.  
  2341. if (count($this->modules_list))
  2342. return true;
  2343.  
  2344. return false; //no module found on disk just return false;
  2345.  
  2346. }
  2347.  
  2348. public function getLanguages()
  2349. {
  2350. $cookie = $this->context->cookie;
  2351. $this->allow_employee_form_lang = (int)Configuration::get('PS_BO_ALLOW_EMPLOYEE_FORM_LANG');
  2352. if ($this->allow_employee_form_lang && !$cookie->employee_form_lang)
  2353. $cookie->employee_form_lang = (int)Configuration::get('PS_LANG_DEFAULT');
  2354.  
  2355. $lang_exists = false;
  2356. $this->_languages = Language::getLanguages(false);
  2357. foreach ($this->_languages as $lang)
  2358. if (isset($cookie->employee_form_lang) && $cookie->employee_form_lang == $lang['id_lang'])
  2359. $lang_exists = true;
  2360.  
  2361. $this->default_form_language = $lang_exists ? (int)$cookie->employee_form_lang : (int)Configuration::get('PS_LANG_DEFAULT');
  2362.  
  2363. foreach ($this->_languages as $k => $language)
  2364. $this->_languages[$k]['is_default'] = ((int)($language['id_lang'] == $this->default_form_language));
  2365.  
  2366. return $this->_languages;
  2367. }
  2368.  
  2369.  
  2370. /**
  2371. * Return the list of fields value
  2372. *
  2373. * @param object $obj Object
  2374. * @return array
  2375. */
  2376. public function getFieldsValue($obj)
  2377. {
  2378. foreach ($this->fields_form as $fieldset)
  2379. if (isset($fieldset['form']['input']))
  2380. foreach ($fieldset['form']['input'] as $input)
  2381. if (!isset($this->fields_value[$input['name']]))
  2382. if (isset($input['type']) && $input['type'] == 'shop')
  2383. {
  2384. if ($obj->id)
  2385. {
  2386. $result = Shop::getShopById((int)$obj->id, $this->identifier, $this->table);
  2387. foreach ($result as $row)
  2388. $this->fields_value['shop'][$row['id_'.$input['type']]][] = $row['id_shop'];
  2389. }
  2390. }
  2391. elseif (isset($input['lang']) && $input['lang'])
  2392. foreach ($this->_languages as $language)
  2393. {
  2394. $fieldValue = $this->getFieldValue($obj, $input['name'], $language['id_lang']);
  2395. if (empty($fieldValue))
  2396. {
  2397. if (isset($input['default_value']) && is_array($input['default_value']) && isset($input['default_value'][$language['id_lang']]))
  2398. $fieldValue = $input['default_value'][$language['id_lang']];
  2399. elseif (isset($input['default_value']))
  2400. $fieldValue = $input['default_value'];
  2401. }
  2402. $this->fields_value[$input['name']][$language['id_lang']] = $fieldValue;
  2403. }
  2404. else
  2405. {
  2406. $fieldValue = $this->getFieldValue($obj, $input['name']);
  2407. if ($fieldValue === false && isset($input['default_value']))
  2408. $fieldValue = $input['default_value'];
  2409. $this->fields_value[$input['name']] = $fieldValue;
  2410. }
  2411.  
  2412. return $this->fields_value;
  2413. }
  2414.  
  2415. /**
  2416. * Return field value if possible (both classical and multilingual fields)
  2417. *
  2418. * Case 1 : Return value if present in $_POST / $_GET
  2419. * Case 2 : Return object value
  2420. *
  2421. * @param object $obj Object
  2422. * @param string $key Field name
  2423. * @param integer $id_lang Language id (optional)
  2424. * @return string
  2425. */
  2426. public function getFieldValue($obj, $key, $id_lang = null)
  2427. {
  2428. if ($id_lang)
  2429. $default_value = (isset($obj->id) && $obj->id && isset($obj->{$key}[$id_lang])) ? $obj->{$key}[$id_lang] : false;
  2430. else
  2431. $default_value = isset($obj->{$key}) ? $obj->{$key} : false;
  2432.  
  2433. return Tools::getValue($key.($id_lang ? '_'.$id_lang : ''), $default_value);
  2434. }
  2435.  
  2436. /**
  2437. * Manage page display (form, list...)
  2438. *
  2439. * @param string $className Allow to validate a different class than the current one
  2440. */
  2441. public function validateRules($class_name = false)
  2442. {
  2443. if (!$class_name)
  2444. $class_name = $this->className;
  2445.  
  2446. $object = new $class_name();
  2447.  
  2448. if (method_exists($this, 'getValidationRules'))
  2449. $definition = $this->getValidationRules();
  2450. else
  2451. $definition = ObjectModel::getDefinition($class_name);
  2452.  
  2453. $default_language = new Language((int)Configuration::get('PS_LANG_DEFAULT'));
  2454.  
  2455. foreach ($definition['fields'] as $field => $def)
  2456. {
  2457. $skip = array();
  2458. if (in_array($field, array('passwd', 'no-picture')))
  2459. $skip = array('required');
  2460.  
  2461. if (isset($def['lang']) && $def['lang'] && isset($def['required']) && $def['required'])
  2462. {
  2463. $value = Tools::getValue($field.'_'.$default_language->id);
  2464. if (Tools::isEmpty($value))
  2465. $this->errors[$field.'_'.$default_language->id] = sprintf(
  2466. Tools::displayError('The field %1$s is required at least in %2$s.'),
  2467. $object->displayFieldName($field, $class_name),
  2468. $default_language->name
  2469. );
  2470.  
  2471. foreach (Language::getLanguages(false) as $language)
  2472. {
  2473. $value = Tools::getValue($field.'_'.$language['id_lang']);
  2474. if (!empty($value))
  2475. if (($error = $object->validateField($field, $value, $language['id_lang'], $skip, true)) !== true)
  2476. $this->errors[$field.'_'.$language['id_lang']] = $error;
  2477. }
  2478. }
  2479. else
  2480. if (($error = $object->validateField($field, Tools::getValue($field), null, $skip, true)) !== true)
  2481. $this->errors[$field] = $error;
  2482. }
  2483.  
  2484.  
  2485. /* Overload this method for custom checking */
  2486. $this->_childValidation();
  2487.  
  2488. /* Checking for multilingual fields validity */
  2489. if (isset($rules['validateLang']) && is_array($rules['validateLang']))
  2490. foreach ($rules['validateLang'] as $field_lang => $function)
  2491. foreach ($languages as $language)
  2492. if (($value = Tools::getValue($field_lang.'_'.$language['id_lang'])) !== false && !empty($value))
  2493. {
  2494. if (Tools::strtolower($function) == 'iscleanhtml' && Configuration::get('PS_ALLOW_HTML_IFRAME'))
  2495. $res = Validate::$function($value, true);
  2496. else
  2497. $res = Validate::$function($value);
  2498. if (!$res)
  2499. $this->errors[$field_lang.'_'.$language['id_lang']] = sprintf(
  2500. Tools::displayError('The %1$s field (%2$s) is invalid.'),
  2501. call_user_func(array($class_name, 'displayFieldName'), $field_lang, $class_name),
  2502. $language['name']
  2503. );
  2504. }
  2505. }
  2506.  
  2507. /**
  2508. * Overload this method for custom checking
  2509. */
  2510. protected function _childValidation()
  2511. {
  2512. }
  2513.  
  2514. /**
  2515. * Display object details
  2516. */
  2517. public function viewDetails()
  2518. {
  2519. }
  2520.  
  2521. /**
  2522. * Called before deletion
  2523. *
  2524. * @param object $object Object
  2525. * @return boolean
  2526. */
  2527. protected function beforeDelete($object)
  2528. {
  2529. return false;
  2530. }
  2531.  
  2532. /**
  2533. * Called before deletion
  2534. *
  2535. * @param object $object Object
  2536. * @return boolean
  2537. */
  2538. protected function afterDelete($object, $oldId)
  2539. {
  2540. return true;
  2541. }
  2542.  
  2543. protected function afterAdd($object)
  2544. {
  2545. return true;
  2546. }
  2547.  
  2548. protected function afterUpdate($object)
  2549. {
  2550. return true;
  2551. }
  2552.  
  2553. /**
  2554. * Check rights to view the current tab
  2555. *
  2556. * @return boolean
  2557. */
  2558.  
  2559. protected function afterImageUpload()
  2560. {
  2561. return true;
  2562. }
  2563.  
  2564. /**
  2565. * Copy datas from $_POST to object
  2566. *
  2567. * @param object &$object Object
  2568. * @param string $table Object table
  2569. */
  2570. protected function copyFromPost(&$object, $table)
  2571. {
  2572. /* Classical fields */
  2573. foreach ($_POST as $key => $value)
  2574. if (key_exists($key, $object) && $key != 'id_'.$table)
  2575. {
  2576. /* Do not take care of password field if empty */
  2577. if ($key == 'passwd' && Tools::getValue('id_'.$table) && empty($value))
  2578. continue;
  2579. /* Automatically encrypt password in MD5 */
  2580. if ($key == 'passwd' && !empty($value))
  2581. $value = Tools::encrypt($value);
  2582. $object->{$key} = $value;
  2583. }
  2584.  
  2585. /* Multilingual fields */
  2586. $rules = call_user_func(array(get_class($object), 'getValidationRules'), get_class($object));
  2587. if (count($rules['validateLang']))
  2588. {
  2589. $languages = Language::getLanguages(false);
  2590. foreach ($languages as $language)
  2591. foreach (array_keys($rules['validateLang']) as $field)
  2592. if (isset($_POST[$field.'_'.(int)$language['id_lang']]))
  2593. $object->{$field}[(int)$language['id_lang']] = $_POST[$field.'_'.(int)$language['id_lang']];
  2594. }
  2595. }
  2596.  
  2597. /**
  2598. * Returns an array with selected shops and type (group or boutique shop)
  2599. *
  2600. * @param string $table
  2601. * @return array
  2602. */
  2603. protected function getSelectedAssoShop($table)
  2604. {
  2605. if (!Shop::isFeatureActive() || !Shop::isTableAssociated($table))
  2606. return array();
  2607.  
  2608. $shops = Shop::getShops(true, null, true);
  2609. if (count($shops) == 1 && isset($shops[0]))
  2610. return array($shops[0], 'shop');
  2611.  
  2612. $assos = array();
  2613. if (Tools::isSubmit('checkBoxShopAsso_'.$table))
  2614. foreach (Tools::getValue('checkBoxShopAsso_'.$table) as $id_shop => $value)
  2615. $assos[] = (int)$id_shop;
  2616. else if (Shop::getTotalShops(false) == 1)// if we do not have the checkBox multishop, we can have an admin with only one shop and being in multishop
  2617. $assos[] = (int)Shop::getContextShopID();
  2618. return $assos;
  2619. }
  2620.  
  2621. /**
  2622. * Update the associations of shops
  2623. *
  2624. * @param int $id_object
  2625. */
  2626. protected function updateAssoShop($id_object)
  2627. {
  2628. if (!Shop::isFeatureActive())
  2629. return;
  2630.  
  2631. if (!Shop::isTableAssociated($this->table))
  2632. return;
  2633.  
  2634. $assos_data = $this->getSelectedAssoShop($this->table, $id_object);
  2635.  
  2636. // Get list of shop id we want to exclude from asso deletion
  2637. $exclude_ids = $assos_data;
  2638. foreach (Db::getInstance()->executeS('SELECT id_shop FROM '._DB_PREFIX_.'shop') as $row)
  2639. if (!$this->context->employee->hasAuthOnShop($row['id_shop']))
  2640. $exclude_ids[] = $row['id_shop'];
  2641. Db::getInstance()->delete($this->table.'_shop', '`'.$this->identifier.'` = '.(int)$id_object.($exclude_ids ? ' AND id_shop NOT IN ('.implode(', ', $exclude_ids).')' : ''));
  2642.  
  2643. $insert = array();
  2644. foreach ($assos_data as $id_shop)
  2645. $insert[] = array(
  2646. $this->identifier => $id_object,
  2647. 'id_shop' => (int)$id_shop,
  2648. );
  2649. return Db::getInstance()->insert($this->table.'_shop', $insert, false, true, Db::INSERT_IGNORE);
  2650. }
  2651.  
  2652. protected function validateField($value, $field)
  2653. {
  2654. if (isset($field['validation']))
  2655. {
  2656. $valid_method_exists = method_exists('Validate', $field['validation']);
  2657. if ((!isset($field['empty']) || !$field['empty'] || (isset($field['empty']) && $field['empty'] && $value)) && $valid_method_exists)
  2658. {
  2659. if (!Validate::$field['validation']($value))
  2660. {
  2661. $this->errors[] = Tools::displayError($field['title'].' : Incorrect value');
  2662. return false;
  2663. }
  2664. }
  2665. }
  2666.  
  2667. return true;
  2668. }
  2669.  
  2670. /**
  2671. * Can be overriden
  2672. */
  2673. public function beforeUpdateOptions()
  2674. {
  2675. }
  2676.  
  2677. /**
  2678. * Overload this method for custom checking
  2679. *
  2680. * @param integer $id Object id used for deleting images
  2681. * @return boolean
  2682. */
  2683. protected function postImage($id)
  2684. {
  2685. if (isset($this->fieldImageSettings['name']) && isset($this->fieldImageSettings['dir']))
  2686. return $this->uploadImage($id, $this->fieldImageSettings['name'], $this->fieldImageSettings['dir'].'/');
  2687. elseif (!empty($this->fieldImageSettings))
  2688. foreach ($this->fieldImageSettings as $image)
  2689. if (isset($image['name']) && isset($image['dir']))
  2690. $this->uploadImage($id, $image['name'], $image['dir'].'/');
  2691. return !count($this->errors) ? true : false;
  2692. }
  2693.  
  2694. protected function uploadImage($id, $name, $dir, $ext = false, $width = null, $height = null)
  2695. {
  2696. if (isset($_FILES[$name]['tmp_name']) && !empty($_FILES[$name]['tmp_name']))
  2697. {
  2698. // Delete old image
  2699. if (Validate::isLoadedObject($object = $this->loadObject()))
  2700. $object->deleteImage();
  2701. else
  2702. return false;
  2703.  
  2704. // Check image validity
  2705. $max_size = isset($this->max_image_size) ? $this->max_image_size : 0;
  2706. if ($error = ImageManager::validateUpload($_FILES[$name], Tools::getMaxUploadSize($max_size)))
  2707. $this->errors[] = $error;
  2708.  
  2709. $tmp_name = tempnam(_PS_TMP_IMG_DIR_, 'PS');
  2710. if (!$tmp_name)
  2711. return false;
  2712.  
  2713. if (!move_uploaded_file($_FILES[$name]['tmp_name'], $tmp_name))
  2714. return false;
  2715.  
  2716. // Evaluate the memory required to resize the image: if it's too much, you can't resize it.
  2717. if (!ImageManager::checkImageMemoryLimit($tmp_name))
  2718. $this->errors[] = Tools::displayError('Due to memory limit restrictions, this image cannot be loaded. Please increase your memory_limit value via your server\'s configuration settings. ');
  2719.  
  2720. // Copy new image
  2721. if (empty($this->errors) && !ImageManager::resize($tmp_name, _PS_IMG_DIR_.$dir.$id.'.'.$this->imageType, (int)$width, (int)$height, ($ext ? $ext : $this->imageType)))
  2722. $this->errors[] = Tools::displayError('An error occurred while uploading the image.');
  2723.  
  2724. if (count($this->errors))
  2725. return false;
  2726. if ($this->afterImageUpload())
  2727. {
  2728. unlink($tmp_name);
  2729. return true;
  2730. }
  2731. return false;
  2732. }
  2733. return true;
  2734. }
  2735.  
  2736. /**
  2737. * Delete multiple items
  2738. *
  2739. * @return boolean true if succcess
  2740. */
  2741. protected function processBulkDelete()
  2742. {
  2743. if (is_array($this->boxes) && !empty($this->boxes))
  2744. {
  2745. $object = new $this->className();
  2746.  
  2747. if (isset($object->noZeroObject))
  2748. {
  2749. $objects_count = count(call_user_func(array($this->className, $object->noZeroObject)));
  2750.  
  2751. // Check if all object will be deleted
  2752. if ($objects_count <= 1 || count($this->boxes) == $objects_count)
  2753. $this->errors[] = Tools::displayError('You need at least one object.').
  2754. ' <b>'.$this->table.'</b><br />'.
  2755. Tools::displayError('You cannot delete all of the items.');
  2756. }
  2757. else
  2758. {
  2759. $result = true;
  2760. foreach ($this->boxes as $id)
  2761. {
  2762. $to_delete = new $this->className($id);
  2763. $delete_ok = true;
  2764. if ($this->deleted)
  2765. {
  2766. $to_delete->deleted = 1;
  2767. if (!$to_delete->update())
  2768. {
  2769. $result = false;
  2770. $delete_ok = false;
  2771. }
  2772. }
  2773. else
  2774. if (!$to_delete->delete())
  2775. {
  2776. $result = false;
  2777. $delete_ok = false;
  2778. }
  2779.  
  2780. if ($delete_ok)
  2781. Logger::addLog(sprintf($this->l('%s deletion', 'AdminTab', false, false), $this->className), 1, null, $this->className, (int)$to_delete->id, true, (int)$this->context->employee->id);
  2782. else
  2783. $this->errors[] = sprintf(Tools::displayError('Can\'t delete #%d'), $id);
  2784. }
  2785. if ($result)
  2786. $this->redirect_after = self::$currentIndex.'&conf=2&token='.$this->token;
  2787. $this->errors[] = Tools::displayError('An error occurred while deleting this selection.');
  2788. }
  2789. }
  2790. else
  2791. $this->errors[] = Tools::displayError('You must select at least one element to delete.');
  2792.  
  2793. if (isset($result))
  2794. return $result;
  2795. else
  2796. return false;
  2797. }
  2798.  
  2799. /**
  2800. * Enable multiple items
  2801. *
  2802. * @return boolean true if succcess
  2803. */
  2804. protected function processBulkEnableSelection()
  2805. {
  2806. return $this->processBulkStatusSelection(1);
  2807. }
  2808.  
  2809. /**
  2810. * Disable multiple items
  2811. *
  2812. * @return boolean true if succcess
  2813. */
  2814. protected function processBulkDisableSelection()
  2815. {
  2816. return $this->processBulkStatusSelection(0);
  2817. }
  2818.  
  2819. /**
  2820. * Toggle status of multiple items
  2821. *
  2822. * @return boolean true if succcess
  2823. */
  2824. protected function processBulkStatusSelection($status)
  2825. {
  2826. $result = true;
  2827. if (is_array($this->boxes) && !empty($this->boxes))
  2828. {
  2829. foreach ($this->boxes as $id)
  2830. {
  2831. $object = new $this->className((int)$id);
  2832. $object->active = (int)$status;
  2833. $result &= $object->update();
  2834. }
  2835. }
  2836. return $result;
  2837. }
  2838.  
  2839. protected function processBulkAffectZone()
  2840. {
  2841. $result = false;
  2842. if (is_array($this->boxes) && !empty($this->boxes))
  2843. {
  2844. $object = new $this->className();
  2845. $result = $object->affectZoneToSelection(Tools::getValue($this->table.'Box'), Tools::getValue('zone_to_affect'));
  2846.  
  2847. if ($result)
  2848. $this->redirect_after = self::$currentIndex.'&conf=28&token='.$this->token;
  2849. $this->errors[] = Tools::displayError('An error occurred while affecting a zone to the selection.');
  2850. }
  2851. else
  2852. $this->errors[] = Tools::displayError('You must select at least one element to affect a new zone.');
  2853.  
  2854. return $result;
  2855. }
  2856.  
  2857. /**
  2858. * Called before Add
  2859. *
  2860. * @param object $object Object
  2861. * @return boolean
  2862. */
  2863. protected function beforeAdd($object)
  2864. {
  2865. return true;
  2866. }
  2867.  
  2868. /**
  2869. * prepare the view to display the required fields form
  2870. */
  2871. public function displayRequiredFields()
  2872. {
  2873. if (!$this->tabAccess['add'] || !$this->tabAccess['delete'] === '1' || !$this->required_database)
  2874. return;
  2875.  
  2876. $helper = new Helper();
  2877. $helper->currentIndex = self::$currentIndex;
  2878. $helper->token = $this->token;
  2879. return $helper->renderRequiredFields($this->className, $this->identifier, $this->required_fields);
  2880. }
  2881.  
  2882. /**
  2883. * Create a template from the override file, else from the base file.
  2884. *
  2885. * @param string $tpl_name filename
  2886. * @return Template
  2887. */
  2888. public function createTemplate($tpl_name)
  2889. {
  2890. // Use override tpl if it exists
  2891. // If view access is denied, we want to use the default template that will be used to display an error
  2892. if ($this->viewAccess() && $this->override_folder)
  2893. {
  2894. if (file_exists($this->context->smarty->getTemplateDir(1).DIRECTORY_SEPARATOR.$this->override_folder.$tpl_name))
  2895. return $this->context->smarty->createTemplate($this->override_folder.$tpl_name, $this->context->smarty);
  2896. else if (file_exists($this->context->smarty->getTemplateDir(0).'controllers'.DIRECTORY_SEPARATOR.$this->override_folder.$tpl_name))
  2897. return $this->context->smarty->createTemplate('controllers'.DIRECTORY_SEPARATOR.$this->override_folder.$tpl_name, $this->context->smarty);
  2898. }
  2899.  
  2900. return $this->context->smarty->createTemplate($this->context->smarty->getTemplateDir(0).$tpl_name, $this->context->smarty);
  2901. }
  2902.  
  2903. /**
  2904. * Shortcut to set up a json success payload
  2905. *
  2906. * @param $message success message
  2907. */
  2908. public function jsonConfirmation($message)
  2909. {
  2910. $this->json = true;
  2911. $this->confirmations[] = $message;
  2912. if ($this->status === '')
  2913. $this->status = 'ok';
  2914. }
  2915.  
  2916. /**
  2917. * Shortcut to set up a json error payload
  2918. *
  2919. * @param $message error message
  2920. */
  2921. public function jsonError($message)
  2922. {
  2923. $this->json = true;
  2924. $this->errors[] = $message;
  2925. if ($this->status === '')
  2926. $this->status = 'error';
  2927. }
  2928.  
  2929. public function isFresh($file, $timeout = 604800000)
  2930. {
  2931. if (file_exists(_PS_ROOT_DIR_.$file) && filesize(_PS_ROOT_DIR_.$file) > 0)
  2932. return ((time() - filemtime(_PS_ROOT_DIR_.$file)) < $timeout);
  2933. return false;
  2934. }
  2935.  
  2936. protected static $is_prestashop_up = true;
  2937. public function refresh($file_to_refresh, $external_file)
  2938. {
  2939. if (self::$is_prestashop_up && $content = Tools::file_get_contents($external_file))
  2940. return (bool)file_put_contents(_PS_ROOT_DIR_.$file_to_refresh, $content);
  2941. self::$is_prestashop_up = false;
  2942. return false;
  2943. }
  2944.  
  2945. public function fillModuleData(&$module, $output_type = 'link', $back = null)
  2946. {
  2947. $obj = null;
  2948. if ($module->onclick_option)
  2949. $obj = new $module->name();
  2950. // Fill module data
  2951. $module->logo = '../../img/questionmark.png';
  2952. if (file_exists('../modules/'.$module->name.'/logo.gif'))
  2953. $module->logo = 'logo.gif';
  2954. if (file_exists('../modules/'.$module->name.'/logo.png'))
  2955. $module->logo = 'logo.png';
  2956. $module->optionsHtml = $this->displayModuleOptions($module, $output_type);
  2957. $link_admin_modules = $this->context->link->getAdminLink('AdminModules', true);
  2958.  
  2959. $module->options['install_url'] = $link_admin_modules.'&install='.urlencode($module->name).'&tab_module='.$module->tab.'&module_name='.$module->name.'&anchor=anchor'.ucfirst($module->name);
  2960. $module->options['update_url'] = $link_admin_modules.'&update='.urlencode($module->name).'&tab_module='.$module->tab.'&module_name='.$module->name.'&anchor=anchor'.ucfirst($module->name);
  2961. $module->options['uninstall_url'] = $link_admin_modules.'&uninstall='.urlencode($module->name).'&tab_module='.$module->tab.'&module_name='.$module->name.'&anchor=anchor'.ucfirst($module->name);
  2962.  
  2963. $module->options['uninstall_onclick'] = ((!$module->onclick_option) ?
  2964. ((empty($module->confirmUninstall)) ? '' : 'return confirm(\''.addslashes($module->confirmUninstall).'\');') :
  2965. $obj->onclickOption('uninstall', $module->options['uninstall_url']));
  2966.  
  2967. if ((Tools::getValue('module_name') == $module->name || in_array($module->name, explode('|', Tools::getValue('modules_list')))) && (int)Tools::getValue('conf') > 0)
  2968. $module->message = $this->_conf[(int)Tools::getValue('conf')];
  2969.  
  2970. if ((Tools::getValue('module_name') == $module->name || in_array($module->name, explode('|', Tools::getValue('modules_list')))) && (int)Tools::getValue('conf') > 0)
  2971. unset($obj);
  2972. }
  2973.  
  2974. /**
  2975. * Display modules list
  2976. *
  2977. * @param $module
  2978. * @param $output_type (link or select)
  2979. * @param $back
  2980. *
  2981. * @return string
  2982. */
  2983. protected $translationsTab = array();
  2984. public function displayModuleOptions($module, $output_type = 'link', $back = null)
  2985. {
  2986. if (!isset($this->translationsTab['Disable this module']))
  2987. {
  2988. $this->translationsTab['Disable this module'] = $this->l('Disable this module');
  2989. $this->translationsTab['Enable this module for all shops'] = $this->l('Enable this module for all shops');
  2990. $this->translationsTab['Disable'] = $this->l('Disable');
  2991. $this->translationsTab['Enable'] = $this->l('Enable');
  2992. $this->translationsTab['Reset'] = $this->l('Reset');
  2993. $this->translationsTab['Configure'] = $this->l('Configure');
  2994. $this->translationsTab['Delete'] = $this->l('Delete');
  2995. $this->translationsTab['Install'] = $this->l('Install');
  2996. $this->translationsTab['Uninstall'] = $this->l('Uninstall');
  2997. $this->translationsTab['This action will permanently remove the module from the server. Are you sure you want to do this?'] = $this->l('This action will permanently remove the module from the server. Are you sure you want to do this?');
  2998. }
  2999. $link_admin_modules = $this->context->link->getAdminLink('AdminModules', true);
  3000. $modules_options = array(
  3001. 'configure-module' => array(
  3002. 'href' => $link_admin_modules.'&configure='.urlencode($module->name).'&tab_module='.$module->tab.'&module_name='.urlencode($module->name),
  3003. 'onclick' => $module->onclick_option && isset($module->onclick_option_content['configure']) ? $module->onclick_option_content['configure'] : '',
  3004. 'title' => '',
  3005. 'text' => $this->translationsTab['Configure'],
  3006. 'cond' => $module->id && isset($module->is_configurable) && $module->is_configurable,
  3007. ),
  3008. 'desactive-module' => array(
  3009. 'href' => $link_admin_modules.'&module_name='.urlencode($module->name).'&'.($module->active ? 'enable=0' : 'enable=1').'&tab_module='.$module->tab,
  3010. 'onclick' => $module->active && $module->onclick_option && isset($module->onclick_option_content['desactive']) ? $module->onclick_option_content['desactive'] : '' ,
  3011. 'title' => Shop::isFeatureActive() ? htmlspecialchars($module->active ? $this->translationsTab['Disable this module'] : $this->translationsTab['Enable this module for all shops']) : '',
  3012. 'text' => $module->active ? $this->translationsTab['Disable'] : $this->translationsTab['Enable'],
  3013. 'cond' => $module->id,
  3014. ),
  3015. 'reset-module' => array(
  3016. 'href' => $link_admin_modules.'&module_name='.urlencode($module->name).'&reset&tab_module='.$module->tab,
  3017. 'onclick' => $module->onclick_option && isset($module->onclick_option_content['reset']) ? $module->onclick_option_content['reset'] : '',
  3018. 'title' => '',
  3019. 'text' => $this->translationsTab['Reset'],
  3020. 'cond' => $module->id && $module->active,
  3021. ),
  3022. 'delete-module' => array(
  3023. 'href' => $link_admin_modules.'&delete='.urlencode($module->name).'&tab_module='.$module->tab.'&module_name='.urlencode($module->name),
  3024. 'onclick' => $module->onclick_option && isset($module->onclick_option_content['delete']) ? $module->onclick_option_content['delete'] : 'return confirm(\''.$this->translationsTab['This action will permanently remove the module from the server. Are you sure you want to do this?'].'\');',
  3025. 'title' => '',
  3026. 'text' => $this->translationsTab['Delete'],
  3027. 'cond' => true,
  3028. ),
  3029. );
  3030.  
  3031. $return = '';
  3032. foreach ($modules_options as $option_name => $option)
  3033. {
  3034. if ($option['cond'])
  3035. {
  3036. if ($output_type == 'link')
  3037. $return .= '<span class="'.$option_name.'">
  3038. <a class="action_module" href="'.$option['href'].(!is_null($back) ? '&back='.urlencode($back) : '').'" onclick="'.$option['onclick'].'" title="'.$option['title'].'">'.$option['text'].'</a>
  3039. </span>';
  3040. elseif ($output_type == 'select')
  3041. $return .= '<option id="'.$option_name.'" data-href="'.$option['href'].(!is_null($back) ? '&back='.urlencode($back) : '').'" data-onclick="'.$option['onclick'].'">'.$option['text'].'</option>';
  3042. }
  3043. }
  3044. if ($output_type == 'select')
  3045. {
  3046. if (!$module->id)
  3047. $return = '<option data-onclick="" data-href="'.$link_admin_modules.'&install='.urlencode($module->name).'&tab_module='.$module->tab.'&module_name='.$module->name.'&anchor=anchor'.ucfirst($module->name).(!is_null($back) ? '&back='.urlencode($back) : '').'" >'.$this->translationsTab['Install'].'</option>'.$return;
  3048. else
  3049. $return .= '<option data-onclick="" data-href="'.$link_admin_modules.'&uninstall='.urlencode($module->name).'&tab_module='.$module->tab.'&module_name='.$module->name.'&anchor=anchor'.ucfirst($module->name).(!is_null($back) ? '&back='.urlencode($back) : '').'" >'.$this->translationsTab['Uninstall'].'</option>';
  3050. $return = '<select id="select_'.$module->name.'">'.$return.'</select>';
  3051. }
  3052.  
  3053. return $return;
  3054. }
  3055. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement