diff --git a/admin-dev/themes/template/list_content.tpl b/admin-dev/themes/template/list_content.tpl index 7cbb44717..ea2251828 100644 --- a/admin-dev/themes/template/list_content.tpl +++ b/admin-dev/themes/template/list_content.tpl @@ -31,8 +31,8 @@ {if isset($tr.color) && $color_on_bg}style="background-color: {$tr.color}"{/if} > - {if $bulk_action} - + {if $bulk_actions} + {/if} {foreach $fields_display AS $key => $params} diff --git a/admin-dev/themes/template/list_footer.tpl b/admin-dev/themes/template/list_footer.tpl index a96c1f34f..4629b0399 100644 --- a/admin-dev/themes/template/list_footer.tpl +++ b/admin-dev/themes/template/list_footer.tpl @@ -24,12 +24,14 @@ * International Registered Trademark & Property of PrestaShop SA *} - -{* -if ($this->delete) -

-{/if} -*} + + {if $bulk_actions} +

+ {foreach $bulk_actions as $key => $params} + + {/foreach} +

+ {/if} diff --git a/admin-dev/themes/template/list_header.tpl b/admin-dev/themes/template/list_header.tpl index 3b60af894..df5b5cdb2 100644 --- a/admin-dev/themes/template/list_header.tpl +++ b/admin-dev/themes/template/list_header.tpl @@ -44,7 +44,7 @@ {/if} {if $add_button} -
{l s='Add new'}

+
{l s='Add new'}

{/if}  
@@ -132,7 +132,7 @@ -- {else} {if $params.type == 'bool'} - @@ -142,7 +142,7 @@ {l s='To'} {elseif $params.type == 'select'} {if isset($params.filter_key)} - {if isset($params.select) && is_array($params.select)} {foreach $params.select AS $option_value => $option_display} @@ -152,7 +152,7 @@ {/if} {else} - + {/if} {/if} diff --git a/classes/AdminController.php b/classes/AdminController.php index aa929a7d8..6c01b4144 100644 --- a/classes/AdminController.php +++ b/classes/AdminController.php @@ -68,7 +68,24 @@ class AdminControllerCore extends Controller /** @var string Order way (ASC, DESC) determined by arrows in list header */ protected $_orderWay; - protected $bulk_action; + /** + * @var array actions to execute on multiple selections + * Usage: + * array( + * 'actionName' => array( + * 'text' => $this->l('Message displayed on the submit button (mandatory)'), + * 'confirm' => $this->l('If set, this confirmation message will pop-up (optional)')), + * 'anotherAction' => array(...) + * ); + * + * If your action is named 'actionName', you need to have a method named bulkactionName() that will be executed when the button is clicked. + */ + protected $bulk_actions; + + /** + * @var array ids of the rows selected + */ + protected $boxes; protected $is_cms = false; @@ -79,6 +96,10 @@ class AdminControllerCore extends Controller protected $edit; protected $delete; protected $duplicate; + /** + * @var bool is a list filter set + */ + protected $filter; protected $noLink; protected $specificConfirmDelete; protected $colorOnBackground; @@ -87,6 +108,12 @@ class AdminControllerCore extends Controller protected $display; protected $_includeContainer = true; + /** @var bool Redirect or not ater a creation */ + protected $_redirect = true; + + /** @var array Name and directory where class image are located */ + public $fieldImageSettings = array(); + public function __construct() { // retro-compatibility : className for admin without controller @@ -419,6 +446,7 @@ class AdminControllerCore extends Controller if (isset($this->context->cookie->{$this->table.'Orderway'})) unset($this->context->cookie->{$this->table.'Orderway'}); unset($_POST); + $this->filter = false; break; /* Submit options list */ @@ -426,67 +454,6 @@ class AdminControllerCore extends Controller $this->updateOptions($token); break; - /* Manage list filtering */ - case 'update_filters': - $_POST = array_merge($this->context->cookie->getFamily($this->table.'Filter_'), (isset($_POST) ? $_POST : array())); - foreach ($_POST AS $key => $value) - { - /* Extracting filters from $_POST on key filter_ */ - if ($value != NULL AND !strncmp($key, $this->table.'Filter_', 7 + Tools::strlen($this->table))) - { - $key = Tools::substr($key, 7 + Tools::strlen($this->table)); - /* Table alias could be specified using a ! eg. alias!field */ - $tmpTab = explode('!', $key); - $filter = count($tmpTab) > 1 ? $tmpTab[1] : $tmpTab[0]; - if ($field = $this->filterToField($key, $filter)) - { - $type = (array_key_exists('filter_type', $field) ? $field['filter_type'] : (array_key_exists('type', $field) ? $field['type'] : false)); - if (($type == 'date' OR $type == 'datetime') AND is_string($value)) - $value = unserialize($value); - $key = isset($tmpTab[1]) ? $tmpTab[0].'.`'.$tmpTab[1].'`' : '`'.$tmpTab[0].'`'; - if (array_key_exists('tmpTableFilter', $field)) - $sqlFilter = & $this->_tmpTableFilter; - elseif (array_key_exists('havingFilter', $field)) - $sqlFilter = & $this->_filterHaving; - else - $sqlFilter = & $this->_filter; - - /* Only for date filtering (from, to) */ - if (is_array($value)) - { - if (isset($value[0]) AND !empty($value[0])) - { - if (!Validate::isDate($value[0])) - $this->_errors[] = Tools::displayError('\'from:\' date format is invalid (YYYY-MM-DD)'); - else - $sqlFilter .= ' AND `'.bqSQL($key).'` >= \''.pSQL(Tools::dateFrom($value[0])).'\''; - } - - if (isset($value[1]) AND !empty($value[1])) - { - if (!Validate::isDate($value[1])) - $this->_errors[] = Tools::displayError('\'to:\' date format is invalid (YYYY-MM-DD)'); - else - $sqlFilter .= ' AND `'.bqSQL($key).'` <= \''.pSQL(Tools::dateTo($value[1])).'\''; - } - } - else - { - $sqlFilter .= ' AND '; - if ($type == 'int' OR $type == 'bool') - $sqlFilter .= (($key == $this->identifier OR $key == '`'.$this->identifier.'`' OR $key == '`active`') ? 'a.' : '').pSQL($key).' = '.(int)($value).' '; - elseif ($type == 'decimal') - $sqlFilter .= (($key == $this->identifier OR $key == '`'.$this->identifier.'`') ? 'a.' : '').pSQL($key).' = '.(float)($value).' '; - elseif ($type == 'select') - $sqlFilter .= (($key == $this->identifier OR $key == '`'.$this->identifier.'`') ? 'a.' : '').pSQL($key).' = \''.pSQL($value).'\' '; - else - $sqlFilter .= (($key == $this->identifier OR $key == '`'.$this->identifier.'`') ? 'a.' : '').pSQL($key).' LIKE \'%'.pSQL($value).'%\' '; - } - } - } - } - break; - case 'update_fields': if (!is_array($fields = Tools::getValue('fieldsBox'))) $fields = array(); @@ -497,7 +464,71 @@ class AdminControllerCore extends Controller else Tools::redirectAdmin(self::$currentIndex.'&conf=4&token='.$token); break; + default: + if (method_exists($this, $this->action)) + call_user_func(array($this, $this->action), $this->boxes); + } + /* Manage list filtering */ + if ($this->filter) + { + $_POST = array_merge($this->context->cookie->getFamily($this->table.'Filter_'), (isset($_POST) ? $_POST : array())); + foreach ($_POST AS $key => $value) + { + /* Extracting filters from $_POST on key filter_ */ + if ($value != NULL AND !strncmp($key, $this->table.'Filter_', 7 + Tools::strlen($this->table))) + { + $key = Tools::substr($key, 7 + Tools::strlen($this->table)); + /* Table alias could be specified using a ! eg. alias!field */ + $tmpTab = explode('!', $key); + $filter = count($tmpTab) > 1 ? $tmpTab[1] : $tmpTab[0]; + if ($field = $this->filterToField($key, $filter)) + { + $type = (array_key_exists('filter_type', $field) ? $field['filter_type'] : (array_key_exists('type', $field) ? $field['type'] : false)); + if (($type == 'date' OR $type == 'datetime') AND is_string($value)) + $value = unserialize($value); + $key = isset($tmpTab[1]) ? $tmpTab[0].'.`'.$tmpTab[1].'`' : '`'.$tmpTab[0].'`'; + if (array_key_exists('tmpTableFilter', $field)) + $sqlFilter = & $this->_tmpTableFilter; + elseif (array_key_exists('havingFilter', $field)) + $sqlFilter = & $this->_filterHaving; + else + $sqlFilter = & $this->_filter; + + /* Only for date filtering (from, to) */ + if (is_array($value)) + { + if (isset($value[0]) AND !empty($value[0])) + { + if (!Validate::isDate($value[0])) + $this->_errors[] = Tools::displayError('\'from:\' date format is invalid (YYYY-MM-DD)'); + else + $sqlFilter .= ' AND `'.bqSQL($key).'` >= \''.pSQL(Tools::dateFrom($value[0])).'\''; + } + + if (isset($value[1]) AND !empty($value[1])) + { + if (!Validate::isDate($value[1])) + $this->_errors[] = Tools::displayError('\'to:\' date format is invalid (YYYY-MM-DD)'); + else + $sqlFilter .= ' AND `'.bqSQL($key).'` <= \''.pSQL(Tools::dateTo($value[1])).'\''; + } + } + else + { + $sqlFilter .= ' AND '; + if ($type == 'int' OR $type == 'bool') + $sqlFilter .= (($key == $this->identifier OR $key == '`'.$this->identifier.'`' OR $key == '`active`') ? 'a.' : '').pSQL($key).' = '.(int)($value).' '; + elseif ($type == 'decimal') + $sqlFilter .= (($key == $this->identifier OR $key == '`'.$this->identifier.'`') ? 'a.' : '').pSQL($key).' = '.(float)($value).' '; + elseif ($type == 'select') + $sqlFilter .= (($key == $this->identifier OR $key == '`'.$this->identifier.'`') ? 'a.' : '').pSQL($key).' = \''.pSQL($value).'\' '; + else + $sqlFilter .= (($key == $this->identifier OR $key == '`'.$this->identifier.'`') ? 'a.' : '').pSQL($key).' LIKE \'%'.pSQL($value).'%\' '; + } + } + } + } } } } @@ -844,6 +875,7 @@ class AdminControllerCore extends Controller $helper->edit = $this->edit; $helper->delete = $this->delete; $helper->duplicate = $this->duplicate; + $helper->bulk_actions = $this->bulk_actions; $helper::$currentIndex = self::$currentIndex; $helper->table = $this->table; $helper->shopLink = $this->shopLink; @@ -879,7 +911,7 @@ class AdminControllerCore extends Controller $this->addCSS(__PS_BASE_URI__.str_replace(_PS_ROOT_DIR_.DIRECTORY_SEPARATOR,'', _PS_ADMIN_DIR_).'/themes/default/admin.css', 'all'); if ($this->context->language->is_rtl) $this->addCSS(_THEME_CSS_DIR_.'rtl.css'); - + $this->addJquery(); $this->addjQueryPlugin(array('cluetip', 'hoverIntent')); @@ -1007,7 +1039,10 @@ class AdminControllerCore extends Controller elseif (strncmp($key, $this->table.'OrderBy', 7) === 0 OR strncmp($key, $this->table.'Orderway', 12) === 0) $this->context->cookie->$key = $value; - // Code from postProcess + /* Manage list filtering */ + if (Tools::isSubmit('submitFilter'.$this->table) OR $this->context->cookie->{'submitFilter'.$this->table} !== false) + $this->filter = true; + /* Delete object image */ if (isset($_GET['deleteImage'])) { @@ -1041,12 +1076,15 @@ class AdminControllerCore extends Controller else $this->_errors[] = Tools::displayError('You do not have permission to edit here.'); } - elseif (Tools::getValue('submitDel'.$this->table)) + elseif ($submitted_action = Tools::getValue('submitAction'.$this->table)) { - if ($this->tabAccess['delete'] === '1') - $this->action = 'multiple_delete'; + if ($submitted_action == 'delete') + if ($this->tabAccess['delete'] === '1') + $this->action = 'multiple_delete'; + else + $this->_errors[] = Tools::displayError('You do not have permission to delete here.'); else - $this->_errors[] = Tools::displayError('You do not have permission to delete here.'); + $this->action = $submitted_action; } elseif (Tools::getValue('submitAdd'.$this->table)) { @@ -1061,7 +1099,7 @@ class AdminControllerCore extends Controller } elseif (isset($_GET['update'.$this->table]) && isset($_GET['id_'.$this->table])) { - if ($this->tabAccess['edit'] === '1' OR ($this->table == 'employee' AND $this->context->employee->id == Tools::getValue('id_employee'))) + if ($this->tabAccess['edit'] === '1' || ($this->table == 'employee' && $this->context->employee->id == Tools::getValue('id_employee'))) $this->display = 'edit'; else $this->_errors[] = Tools::displayError('You do not have permission to edit here.'); @@ -1072,11 +1110,18 @@ class AdminControllerCore extends Controller /* Submit options list */ elseif (Tools::getValue('submitOptions'.$this->table)) $this->action = 'update_options'; - /* Manage list filtering */ - elseif (Tools::isSubmit('submitFilter'.$this->table) OR $this->context->cookie->{'submitFilter'.$this->table} !== false) - $this->action = 'update_filters'; - elseif(Tools::isSubmit('submitFields') AND $this->requiredDatabase AND $this->tabAccess['add'] === '1' AND $this->tabAccess['delete'] === '1') + elseif (Tools::isSubmit('submitFields') && $this->requiredDatabase && $this->tabAccess['add'] === '1' && $this->tabAccess['delete'] === '1') $this->action = 'update_fields'; + elseif (is_array($this->bulk_actions)) + foreach ($this->bulk_actions AS $bulk_action => $params) + { + if (Tools::isSubmit('submitBulk'.$bulk_action.$this->table)) + { + $this->action = 'bulk'.$bulk_action; + $this->boxes = Tools::getValue($this->table.'Box'); + break; + } + } } /** @@ -1427,4 +1472,37 @@ class AdminControllerCore extends Controller $this->uploadImage($id, $image['name'], $image['dir'].'/'); return !sizeof($this->_errors) ? true : false; } + + protected function bulkDelete($boxes) + { + if (is_array($boxes) && !empty($boxes)) + { + $object = new $this->className(); + if (isset($object->noZeroObject) AND + // Check if all object will be deleted + (sizeof(call_user_func(array($this->className, $object->noZeroObject))) <= 1 OR sizeof($boxes) == sizeof(call_user_func(array($this->className, $object->noZeroObject))))) + $this->_errors[] = Tools::displayError('You need at least one object.').' '.$this->table.'
'.Tools::displayError('You cannot delete all of the items.'); + else + { + $result = true; + if ($this->deleted) + { + foreach($boxes as $id) + { + $toDelete = new $this->className($id); + $toDelete->deleted = 1; + $result = $result AND $toDelete->update(); + } + } + else + $result = $object->deleteSelection(Tools::getValue($this->table.'Box')); + + if ($result) + Tools::redirectAdmin(self::$currentIndex.'&conf=2&token='.$this->token); + $this->_errors[] = Tools::displayError('An error occurred while deleting selection.'); + } + } + else + $this->_errors[] = Tools::displayError('You must select at least one element to delete.'); + } } diff --git a/classes/HelperList.php b/classes/HelperList.php index 8fc3c4b3e..85e01059f 100644 --- a/classes/HelperList.php +++ b/classes/HelperList.php @@ -35,7 +35,6 @@ class HelperListCore extends Helper public $token; - protected $bulk_action; protected $is_cms = false; @@ -62,6 +61,7 @@ class HelperListCore extends Helper public $edit = false; public $delete = false; public $duplicate = false; + public $bulk_actions = false; public $specificConfirmDelete; public $colorOnBackground; @@ -225,14 +225,13 @@ class HelperListCore extends Helper 'is_dnd_identifier' => $this->is_dnd_identifier, 'color_on_bg' => $this->colorOnBackground, 'id_category' => $id_category, - 'bulk_action' => $this->bulk_action, + 'bulk_actions' => $this->bulk_actions, 'key_to_get' => $key_to_get, 'positions' => isset($positions) ? $positions : NULL, 'is_cms' => $this->is_cms, 'fields_display' => $this->fieldsDisplay, 'list' => $this->_list, 'no_link' => $this->noLink, - 'bulk_action' => $this->bulk_action, 'current_index' => self::$currentIndex, 'view' => $this->view, 'edit' => $this->edit, @@ -242,11 +241,6 @@ class HelperListCore extends Helper return $this->context->smarty->fetch(_PS_ADMIN_DIR_.'/themes/template/list_content.tpl'); } - protected function displayAddButton() - { - echo '
'.$this->l('Add new').'

'; - } - protected function _displayDuplicate($token = NULL, $id) { $_cacheLang['Duplicate'] = $this->l('Duplicate'); @@ -415,6 +409,7 @@ class HelperListCore extends Helper { $this->context->smarty->assign(array( 'token' => $this->token, + 'bulk_actions' => $this->bulk_actions, )); return $this->context->smarty->fetch(_PS_ADMIN_DIR_.'/themes/template/list_footer.tpl'); } diff --git a/controllers/admin/AdminAddressesController.php b/controllers/admin/AdminAddressesController.php index b4581c28d..58526647c 100644 --- a/controllers/admin/AdminAddressesController.php +++ b/controllers/admin/AdminAddressesController.php @@ -40,6 +40,7 @@ class AdminAddressesControllerCore extends AdminController $this->lang = false; $this->edit = true; $this->delete = true; + $this->bulk_actions = array('delete' => array('text' => $this->l('Delete selected'), 'confirm' => $this->l('Delete selected items?'))); $this->requiredDatabase = true; $this->addressType = 'customer'; $this->context = Context::getContext(); @@ -77,7 +78,8 @@ class AdminAddressesControllerCore extends AdminController { if (Validate::isEmail(Tools::getValue('email'))) { - $customer = new Customer(Tools::getValue('id_customer')); + $customer = new Customer(); + $customer->getByEmail(Tools::getValue('email')); if (Validate::isLoadedObject($customer)) $_POST['id_customer'] = $customer->id; else @@ -159,68 +161,6 @@ class AdminAddressesControllerCore extends AdminController } } - public function getList($id_lang, $orderBy = NULL, $orderWay = NULL, $start = 0, $limit = NULL, $id_lang_shop = NULL) - { - parent::getList($id_lang, $orderBy, $orderWay, $start, $limit); - /* Manage default params values */ - if (empty($limit)) - $limit = ((!isset($this->context->cookie->{$this->table.'_pagination'})) ? $this->_pagination[0] : $limit = $this->context->cookie->{$this->table.'_pagination'}); - - if (!Validate::isTableOrIdentifier($this->table)) - die('filter is corrupted'); - if (empty($orderBy)) - $orderBy = Tools::getValue($this->table.'Orderby', 'id_'.$this->table); - if (empty($orderWay)) - $orderWay = Tools::getValue($this->table.'Orderway', 'ASC'); - $limit = (int)(Tools::getValue('pagination', $limit)); - $this->context->cookie->{$this->table.'_pagination'} = $limit; - - /* Check params validity */ - if (!Validate::isOrderBy($orderBy) OR !Validate::isOrderWay($orderWay) - OR !is_numeric($start) OR !is_numeric($limit) - OR !Validate::isUnsignedId($id_lang)) - die(Tools::displayError('get list params is not valid')); - - /* Determine offset from current page */ - if ((isset($_POST['submitFilter'.$this->table]) OR - isset($_POST['submitFilter'.$this->table.'_x']) OR - isset($_POST['submitFilter'.$this->table.'_y'])) AND - !empty($_POST['submitFilter'.$this->table]) AND - is_numeric($_POST['submitFilter'.$this->table])) - $start = (int)($_POST['submitFilter'.$this->table] - 1) * $limit; - - /* Cache */ - $this->_lang = (int)($id_lang); - $this->_orderBy = $orderBy; - $this->_orderWay = Tools::strtoupper($orderWay); - - /* SQL table : orders, but class name is Order */ - $sqlTable = $this->table == 'order' ? 'orders' : $this->table; - - /* Query in order to get results number */ - $queryTotal = Db::getInstance()->getRow(' - SELECT COUNT(a.`id_'.$this->table.'`) AS total - FROM `'._DB_PREFIX_.$sqlTable.'` a - '.($this->lang ? 'LEFT JOIN `'._DB_PREFIX_.$this->table.'_lang` b ON (b.`id_'.$this->table.'` = a.`id_'.$this->table.'` AND b.`id_lang` = '.(int)($id_lang).')' : '').' - '.(isset($this->_join) ? $this->_join.' ' : '').' - WHERE 1 '.(isset($this->_where) ? $this->_where.' ' : '').(($this->deleted OR $this->table == 'currency') ? 'AND a.`deleted` = 0 ' : '').$this->_filter.' - '.(isset($this->_group) ? $this->_group.' ' : '').' - '.(isset($this->addressType) ? 'AND a.id_'.strval($this->addressType).' != 0' : '')); - $this->_listTotal = (int)($queryTotal['total']); - - /* Query in order to get results with all fields */ - $this->_list = Db::getInstance()->ExecuteS(' - SELECT a.*'.($this->lang ? ', b.*' : '').(isset($this->_select) ? ', '.$this->_select.' ' : '').' - FROM `'._DB_PREFIX_.$sqlTable.'` a - '.($this->lang ? 'LEFT JOIN `'._DB_PREFIX_.$this->table.'_lang` b ON (b.`id_'.$this->table.'` = a.`id_'.$this->table.'` AND b.`id_lang` = '.(int)($id_lang).')' : '').' - '.(isset($this->_join) ? $this->_join.' ' : '').' - WHERE 1 '.(isset($this->_where) ? $this->_where.' ' : '').(($this->deleted OR $this->table == 'currency') ? 'AND a.`deleted` = 0 ' : '').$this->_filter.' - '.(isset($this->_group) ? $this->_group.' ' : '').' - '.(isset($this->addressType) ? 'AND a.id_'.strval($this->addressType).' != 0' : '').' - ORDER BY '.(($orderBy == 'id_'.$this->table) ? 'a.' : '').'`'.pSQL($orderBy).'` '.pSQL($orderWay).' - LIMIT '.(int)($start).','.(int)($limit)); - } - public function displayForm($isMainTab = true) { $content = parent::displayForm(); @@ -288,8 +228,6 @@ class AdminAddressesControllerCore extends AdminController $addresses_fields = $this->processAddressFormat(); $addresses_fields = $addresses_fields["dlv_all_fields"]; // we use delivery address - - foreach($addresses_fields as $addr_field_item) { if ($addr_field_item == 'company')