Gestion des positions dans un module prestashop

Voici le code d’un objet et d’un controller qui vont vous permettre de rajouter la gestion des positions dans vos modules.

Le code de l’objet:


class Nomdevotreobjet extends ObjectModel
{
	/* @var string Name */

	public $id_nomdevotretable;
	public $position;

	/*
	 * @see ObjectModel::$definition
	 */
	public static $definition = array(
            'table' => 'nomdevotretable',
            'primary' => 'id_nomdevotretable',
            'multilang' => false,
            'fields' => array(
                    'name' => array('type' => self::TYPE_STRING, 'validate' => 'isString'),
            ),
	);
        
        public function delete()
	{
            if (parent::delete())
		return $this->cleanPositions();
            return false;
	}

        public function cleanPositions()
	{
            $sql = '
            SELECT `id_'.$this->table.'`
            FROM `'._DB_PREFIX_.$this->table.'`
            ORDER BY `position`';

            $result = Db::getInstance()->executeS($sql);

            for ($i = 0, $total = count($result); $i < $total; ++$i)
            {
                $sql = 'UPDATE `'._DB_PREFIX_.$this->table.'`
                    SET `position` = '.(int)$i.'
                    WHERE `id_'.$this->table.'` = '.(int)$result[$i]['id_'.$this->table.''];
                Db::getInstance()->execute($sql);
            }
            return true;
	}
        
        public function getLastPosition()
	{
            return (int)(Db::getInstance()->getValue('SELECT MAX(o.`position`)+ 1 FROM `'._DB_PREFIX_.$this->table.'` o'));
	}
        
        public function add($autodate = true, $null_values = false)
        {
            $this->position = (int)$this->getLastPosition();            
            return parent::add($autodate, true);
	}
        
        public function updatePosition($way, $position)
	{
            if (!$res = Db::getInstance()->executeS('
                SELECT o.`id_'.$this->table.'`, o.`position`
                FROM `'._DB_PREFIX_.$this->table.'` o
                ORDER BY o.`position` ASC'
            ))
            return false;

            foreach ($res as $obj)
                if ((int)$obj['id_'.$this->table.''] == (int)$this->id)
                        $moved_obj = $obj;

            if (!isset($moved_obj) || !isset($position))
                    return false;

            $result = (Db::getInstance()->execute('
                UPDATE `'._DB_PREFIX_.$this->table.'` o
                SET o.`position`= o.`position` '.($way ? '- 1' : '+ 1').'
                WHERE o.`position`
                '.($way
                        ? '> '.(int)$moved_obj['position'].' AND o.`position` <= '.(int)$position
                        : '< '.(int)$moved_obj['position'].' AND o.`position` >= '.(int)$position))
                && Db::getInstance()->execute('
                    UPDATE `'._DB_PREFIX_.$this->table.'`
                    SET `position` = '.(int)$position.'
                    WHERE `id_'.$this->table.'` = '.(int)$moved_obj['id_'.$this->table.'']));
            return $result;
	}
}


Code de votre controller dans l’admin


require_once _PS_MODULE_DIR_.'nomdevotretable/models/Nomdevotreobjet.php';

class AdminNomdevotretableController extends ModuleAdminController
{    
        protected $position_identifier = 'id_nomdevotretable';
        
	public function __construct()
	{
            $this->bootstrap = true;
            $this->table = 'nomdevotretable';
            $this->name = 'nomdevotretable';
            $this->className = 'Nomdevotreobjet';
            $this->lang = false;
            $this->deleted = false;
            $this->colorOnBackground = false;
            $this->bulk_actions = array('delete' => array('text' => $this->l('Delete selected items'), 'confirm' => $this->l('Delete selected items?')));
            $this->context = Context::getContext();
            $this->_path = _PS_BASE_URL_.'/modules/'.$this->name;
            $this->context->smarty->assign(array(
                'module_name' => $this->name,
                'moduledir' => _MODULE_DIR_.$this->name.'/'
            ));
            
            parent::__construct();
	}

	public function renderList()
	{
		$this->fields_list = array(
                    'id_'.$this->table => array(
                        'title' => $this->l('ID'),
                        'align' => 'center',
                        'width' => 25
                    ),
                    'name' => array(
                        'title' => $this->l('Name'),
                        'width' => 'auto',
                    ),
                    'position' => array(
                        'title' => $this->l('Position'),
                        'width' => 40,
                        'filter_key' => 'position',
                        'align' => 'center',
                        'position' => 'position'
                    ),
		);

            $this->_orderBy = 'position';
            $this->initToolbar();
            return parent::renderList();
	}

        
        public function ajaxProcessUpdatePositions()
	{
            if ($this->tabAccess['edit'] === '1')
            {
                $id_obj = (int)Tools::getValue('id');
                $way = (int)Tools::getValue('way');
                $positions = Tools::getValue($this->table);
                if (is_array($positions))
                        foreach ($positions as $key => $value)
                        {
                                $pos = explode('_', $value);
                                if ((isset($pos[1]) && isset($pos[2])) && $pos[2] == $id_obj)
                                {
                                        $position = $key;
                                        break;
                                }
                        }
                $obj = new OsmMenu($id_obj);
                if (Validate::isLoadedObject($obj))
                {
                    if (isset($position) && $obj->updatePosition($way, $position))
                        die(true);
                    else
                        die('{"hasError" : true, "errors" : "Can not update object position"}');
                }
                else
                    die('{"hasError" : true, "errors" : "This object can not be loaded"}');
            }
	}
 
        public function postProcess(){
            //ajax pos update
            if(Tools::getValue('action') == 'updatePositions') {
                $this->ajaxProcessUpdatePositions();
            }
            //classic pos update
            if (Tools::isSubmit('way') && Tools::isSubmit('id_'.$this->table) && (Tools::isSubmit('position')))
            {
                if ($this->tabAccess['edit'] !== '1')
                    $this->errors[] = Tools::displayError('You do not have permission to edit this.');
                elseif (!Validate::isLoadedObject($object = $this->loadObject()))
                    $this->errors[] = Tools::displayError('An error occurred while updating the status for an object.')
                            .' <b>'.$this->table.'</b> '.Tools::displayError('(cannot load object)');
                elseif (!$object->updatePosition((int)Tools::getValue('way'), (int)Tools::getValue('position')))
                    $this->errors[] = Tools::displayError('Failed to update the position.');
                else
                    Tools::redirectAdmin(self::$currentIndex.'&'.$this->table.'Orderby=position&'.$this->table.'Orderway=asc&id_'.$this->table.'='.(int)$object->id.'&token='.Tools::getAdminTokenLite('AdminNomdevotretable'));
            }  
            return parent::postProcess();
        }
}

Pour l’adapter à votre module il suffit de remplacer: « nomdevotretable » et « nomdevotreobjet » par les bonnes valeurs respectives.

Testé sous PS 1.5.4.0

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *