Jump to content
paradeyes

HelperList, colonne "Position"

Recommended Posts

Bonjour,

 

Je développe un module perso, et je souhaite ajouter une colonne "Position" qui me permettra de gérer l'ordre d'affichage des objets que je créé via ce module.

 

J'ai donc ajouté à mon constructeur la colonne :

          	 'position' => array(
                   'title' => $this->l('position'),
                   'width' => 30,
                   'position' => 'position',
               ),   

 

Si je ne dis pas de bêtise, cela devrait normalement afficher une colonne avec les flèches Haut et Bas permettant de gérer la position des éléments.

Or ce n'est pas le cas, cela m'affiche une suite de chiffres (cf capture en PJ)

 

J'ai réussi sur ce même procédé à gérer les status actif/inactif, mais pour les positions je suis vraiment bloqué.

 

Quelqu'un aurait-il une piste pour m'aider à avancer ?

 

Merci d'avance.

 

Si besoin, voici le code complet de ma fonction :

protected function initList()
 {

  $this->fields_list = array(
   'id_offre' => array(
 'title' => $this->l('Id_offre'),
 'width' => 30,
 'type' => 'text',
   ),
   'text' => array(
 'title' => $this->l('Text'),
 'width' => 200,
 'type' => 'text',
 'filter_key' => 'a!lastname'
   ),

   'lienURL' => array(
 'title' => $this->l('Lien'),
 'width' => 50,
 'type' => 'text',
   ),

   'active' => array(
 'title' => $this->l('Status'),
 'width' => 50,
 'active' => 'status',
   ),

   'position' => array(
 'title' => $this->l('position'),
 'width' => 30,
 'position' => 'position',
   ),   

  );

  if (Shop::isFeatureActive())
   $this->fields_list['id_shop'] = array('title' => $this->l('ID Shop'), 'align' => 'center', 'width' => 25, 'type' => 'int');

  $helper = new HelperList();
  $helper->shopLinkType = '';
  $helper->simple_header = true;
  $helper->identifier = 'id_offre';
  $helper->actions = array('edit', 'delete');



  $helper->show_toolbar = true;
  $helper->imageType = 'jpg';
  $helper->toolbar_btn['new'] =  array(
   'href' => AdminController::$currentIndex.'&configure='.$this->name.'&add'.$this->name.'&token='.Tools::getAdminTokenLite('AdminModules'),
   'desc' => $this->l('Add new')
  );

  $helper->title = $this->displayName;
  $helper->table = $this->name;
  $helper->token = Tools::getAdminTokenLite('AdminModules');
  $helper->currentIndex = AdminController::$currentIndex.'&configure='.$this->name;


  return $helper;
 }

post-388583-0-18582200-1375797328_thumb.png

Share this post


Link to post
Share on other sites

Est-ce que l'ajout de cette ligne dans le constructeur du controller change quelque chose ?

 

$this->_defaultOrderBy = 'position';

Share this post


Link to post
Share on other sites

Merci beaucoup pour votre réponse rapide.

 

Si j'ai bien compris, j'ai donc rajouté cette ligne à la fonction initList() , mais ce qui n'a malheureusement rien changé.

 

(Je vous mets la fonction pour être sûr que je l'ai bien placé au bon endroit :

protected function initList()
 {

  $this->fields_list = array(
   'id_offre' => array(
	 'title' => $this->l('Id_offre'),
	 'width' => 30,
	 'type' => 'text',
   ),
   'text' => array(
	 'title' => $this->l('Text'),
	 'width' => 200,
	 'type' => 'text',
	 'filter_key' => 'a!lastname'
   ),

   'lienURL' => array(
	 'title' => $this->l('Lien'),
	 'width' => 50,
	 'type' => 'text',
   ),

   'active' => array(
	 'title' => $this->l('Status'),
	 'width' => 50,
	 'active' => 'status',
   ),

   'position' => array(
	 'title' => $this->l('position'),
	 'width' => 30,
	 'position' => 'position',
   ),  

  );

$this->_defaultOrderBy = 'position';

  if (Shop::isFeatureActive())
   $this->fields_list['id_shop'] = array('title' => $this->l('ID Shop'), 'align' => 'center', 'width' => 25, 'type' => 'int');
  $helper = new HelperList();
  $helper->shopLinkType = '';
  $helper->simple_header = true;
  $helper->identifier = 'id_offre';
  $helper->actions = array('edit', 'delete');



  $helper->show_toolbar = true;
  $helper->imageType = 'jpg';
  $helper->toolbar_btn['new'] =  array(
   'href' => AdminController::$currentIndex.'&configure='.$this->name.'&add'.$this->name.'&token='.Tools::getAdminTokenLite('AdminModules'),
   'desc' => $this->l('Add new')
  );
  $helper->title = $this->displayName;
  $helper->table = $this->name;
  $helper->token = Tools::getAdminTokenLite('AdminModules');
  $helper->currentIndex = AdminController::$currentIndex.'&configure='.$this->name;


  return $helper;
 }

Share this post


Link to post
Share on other sites

Bonjour,

 

le code J.Danse est correct mais il faut le placer dans la fonction renderList().

 

Cordialement

 

 

Edit: que le fichier soit dans le constructeur ou dans la fonction renderList() cela ne change rien, il doit manquer quelque chose d'autre... (autant pour moi J.Danse ;) j'ai écris trop vite)

Pour ma part si je supprime la ligne de code précédente j'obtiens bien le numéro des lignes comme vous...

 

Edit2: il semblerait que la fonction que vous utilisez initList() ne soit pas le constructeur de votre classe

Essayez avec le véritable constructeur :

public function __construct() {
[...]
}

Edited by Pepitoww (see edit history)

Share this post


Link to post
Share on other sites

Merci pour votre aide.

 

Au risque de paraitre vraiment ridicule, où se situe cette fonction renderList() ? J'aurai bien aimé tester, bien que visiblement il manque quelque chose d'autre..

 

Cela fait 2 jours que je remue le code dans tous les sens pour tenter de débloquer cette situation, sans succès... c'est à s'arracher les cheveux ! D'autant que la colonne "Status" (actif/inactif) fonctionne très bien, c'est vraiment rageant...

Share this post


Link to post
Share on other sites

La fonction renderList() est à surcharger dans votre classe Admin de votre module.

Pour plus d'infos allez voir la classe parente (AdminController je crois).

 

Avez-vous essayé le code dans le constructeur de votre classe ? (voir Edit2 de mon précédent post)

 

Cordialement

Share this post


Link to post
Share on other sites

Bonjour,

 

Désolé pour ma réponse tardive.

 

J'ai effectivement essayé de placer le code dans le constructeur, ainsi que dans la fonction getContent() (qui elle-même fait appel à la fonction initList(). )

 

Mais sans succès malheureusement...

Share this post


Link to post
Share on other sites

Après avoir passé une partie de la nuit sans succès encore une fois, j'en viens à me demander si cela ne vient pas d'un problème sur mon install de presta....

 

Je joins à ce post un fichier zip contenant mon module, si quelqu'un pouvait avoir la gentillesse de le tester pour me dire si il rencontre le même problème ce serait vraiment très sympa.

 

Merci beaucoup par avance.

blockoffresnea.zip

Share this post


Link to post
Share on other sites

Salut,

 

Si tu utilises un ObjectModel, tu dois utiliser un Controller.

La page de configuration du module dois simplement proposer des réglages et non la gestion de contenu.

 

Pourquoi ? Car cela te permettra d'utiliser toutes les méthodes déjà implémentées de AdminController pour te simplifier l’interaction avec ton ObjectModel. En plus de respecter l'architecture MVC.

 

De plus tu fais une grosse erreur en ayant placé ta méthode copyFromPost dans ton ObjectModel ! Cette méthode fait un traitement, elle doit donc être dans un Controller, l'ObjectModel doit s'occuper uniquement des données, tous le reste dois être dans un Controller.

 

De plus, évite d'écrire tes requêtes SQL de cette manière, je te conseil d'utiliser la class DbQuery pour les SELECT et class DB pour les Insert, Update, Delete. (Voir les méthodes présentes dans ces class)

 

Ton module a un ObjectModel, par conséquent tu dois avoir un ModuleAdminController pour le gérer et la page configuration de ton module ne dois servir que pour des petits réglages, tu peux ajouter un lien vers ton ModuleAdminController dedans via la Toolbar si tu ne veux pas créer un nouvel onglet.

 

Par petits réglages je veux dire par exemple proposer à l'utilisateur de sélectionner les hooks où afficher le module, ou si le bloc doit être afficher même si il est vide ou tout autres réglages qui ne dépend pas de ton ObjectModel.

 

Là non seulement tu cherches la difficulté inutilement mais en plus tu ne respectes pas les normes... (Oui je sais les normes dans Prestashop... Et puis peu de développeurs s'attachent à les respecter d'où une qualité des modules assez médiocres)

Edited by Matt75 (see edit history)

Share this post


Link to post
Share on other sites

Je viens de tester... Alors, oui, le soucis vient du fait que les variables $order_by et $order_way ne sont pas initialisées dans Smarty car elles n'existent pas dans ce contexte.

 

Et il est n'est pas possible d'instancier celles du contrôleur puisque les variables sont protégées. Et impossible de mettre ces variables comme souhaitées, car elles seront remises à null par la suite.

 

Dans l'idée, le message ci-dessus sur les normes est juste. Mais, par contre, il est vrai que l'on devrait pouvoir utiliser un HelperList même dans un configure de module, cela dit. Et entièrement :)

Share this post


Link to post
Share on other sites
Dans l'idée, le message ci-dessus sur les normes est juste. Mais, par contre, il est vrai que l'on devrait pouvoir utiliser un HelperList même dans un configure de module, cela dit. Et entièrement :)

Là je ne suis pas d'accord, théoriquement le configure d'un module devrait uniquement être un formulaire qui enregistre ces données dans l'Object Configuration...

Si tu veux utiliser le helperList c'est que tu veux lister des éléments, donc utiliser un ObjectModel (Soit un natif, soit un que tu créé dans ton module) donc cela suppose un AdminController...

 

La plupart des modules, y compris les modules natifs utilise cette page de configuration pour tout et n'importe quoi...

Personnellement je trouve que cette page configure ne devrait même pas exister ! Pour moi le lien Configurer devrait rediriger vers un ModuleAdminController Configure !

Je trouve cette implémentation réellement ridicule quand aux modules natifs comme le blockreinsurance, je trouve ça horrible de proposer cela, beaucoup gens risque de le prendre en exemple... Alors que c'est plutôt un exemple à ne pas suivre !

Share this post


Link to post
Share on other sites

Merci à vous 2 d'avoir pris le temps de tester et de me répondre, c'est vraiment très sympa.

 

Pour la méthode CopyFromPost placée dans le ObjectModel, je me suis simplement inspiré du module blockreinsurance qui fait de même...

[edit : croisement de réponse !]

Après j'entends bien toutes tes remarques et préconisations, et je te remercie beaucoup pour ces éclaircissements.

 

Du coup, dans l'immédiat, quelle solution s'offre à moi ?

Si je comprends bien, je dois créer un fichier controllers/admin/adminoffres.php, qui contient :

<?php
class AminOffresController extends ModuleAdminController {

public function __construct() {
//traitement des données
}

}

 

Mais comment le "connecter" ensuite à mon module ? Cela se fait "automatiquement" du fait du nommage des dossiers?

En fait c'est vraiment pas clair pour moi et je ne trouve pas beaucoup de doc ni d'info à ce sujet, ce n'est pas simple... :/

 

Merci encore d'avoir pris le temps de m'aider !

Edited by paradeyes (see edit history)

Share this post


Link to post
Share on other sites

Tu as plusieurs possibilités:

  1. Ajouter un onglet dans le menu Modules du Back Office
  2. Ajouter un lien dans la Toolbar de la page configuration de ton module.
  3. Faire une redirection de la page configuration de ton module vers ton ModuleAdminController

Pour ajouter un nouvel onglet, dans la méthode install de ton module, ajoute ceci

$parent_tab = new Tab();
$parent_tab->name = $this->l('My new link'); //Mettre le nom de ton lien ici
$parent_tab->class_name = 'AminOffresController'; //Mettre le nom de ta class ici
$parent_tab->id_parent =  Tab::getIdFromClassName('AdminParentModules');
$parent_tab->module = $this->name;
$parent_tab->add();

 

Dans la méthode uninstall de ton module, ajoute ceci

$tab = new Tab((int)Tab::getIdFromClassName('AminOffresController')); //Mettre le nom de ta class ici
$tab->delete();

Edited by Matt75 (see edit history)

Share this post


Link to post
Share on other sites

[...] Alors que c'est plutôt un exemple à ne pas suivre !

 

Nous sommes d'accord. Bon, outre passons le fait que ce soit dans un configure. Il devrait être possible de l'utiliser dans un Front Controller, par exemple. C'est un peu le but d'un Helper, tout de même. Non ? ;-) (Mais nous serons d'accord et n'étant pas le but du sujet, on va se stopper là dans la suite je pense que c'est mieux ;-)).

Share this post


Link to post
Share on other sites

Mouai, à la base il s'agit quand même d'un helper pour l'Admin donc je trouve assez logique qu'il soit utilisable que dans un AdminController.

Car niveau ergonomie, ce n'est pas vraiment adapté au Front Office, ça me parait une mauvaise idée de vouloir l'utiliser dans un FrontController. Ce n'est pas son but...

Idéalement il aurait fallut des helpers spécifiques au Front Office, notamment un HelperPaginate par exemple.

De toute façon Prestashop souffre de nombreux manques et incohérences ;)

Share this post


Link to post
Share on other sites

Sans rentrer dans votre débat qui dépasse bien mon champ de compétence :)

Pour quelqu'un qui s'initie au développement de module (tel que moi), j'ai vraiment du mal à comprendre pourquoi j'ai pu afficher et développer les fonctions qui permettent de modifier le status (active/inactive), et pourquoi les flèches de Position n'aparaissent pas, alors que c'est censé faire partie du même "pack"..

Share this post


Link to post
Share on other sites

Certes mais ce petit débat peut aider d'autres personnes, c'est pourquoi c'est intéressant d'en discuter quand même :)

 

Pour en revenir à ton problème, c'est tout simplement parce ce "pack" n'a pas été conçu pour fonctionner en dehors d'un AdminController. Certes des modules l'utilisent dans le configure d'un Module, mais c'est une mauvaise pratique, car ce n'est pas prévu pour initialement.

 

La gestion des flèches de position est faites dans AdminController, hors le configure d'un module hérite de la class Module et non de la class AdminController, par conséquent elle n'a pas accès à la gestion des flèches de positions qui sont réservées aux class héritant de AdminController ;)

 

Si tu regardes le code de AdminController, tu verras que ces fonctions sont Protected, ce qui signifient qu'elles ne peuvent utilisées uniquement par des class héritant de AdminController.

Share this post


Link to post
Share on other sites

Merci beaucoup pour ces précisions !

Je crois que j'ai encore pas mal de boulot pour rendre mon petit module fonctionnel....

 

Et effectivement votre débat est très intéressant et je pense qu'il peut vraiment apporter des éclaircissements à pas mal de monde :)

Edited by paradeyes (see edit history)

Share this post


Link to post
Share on other sites

Bah en fait pas tellement car là où tu perdais ton temps dans le configure de ton module, tu vas le gagner grâce à ton ModuleAdminController qui te permet d'utiliser plein de méthodes déjà existantes, du coup ça va plus vite que de réécrire soit même des méthodes ou de chercher comment les faire fonctionner dans le configure :)

 

Tu peux t'aider du Canvas de Module réaliser par Jdanse, qui est un bon exemple : http://www.prestashop.com/forums/topic/188181-doc-canvas-de-module

Par contre il y a une petite erreur dans ce Canvas:

[...] La méthode renderList est fausse, car $this->fields_list doit être déclaré dans le constructeur (Regarde les AdminController de base) car si tu regardes le fonctionnement de la class AdminController, tu verras que cette variable est utilisée par d'autres méthodes que renderList et si tu ne la déclares pas dans le constructeur ces méthodes ne pourront pas fonctionner.

 

Cela s'applique aux autres propriétés déclarées dans ta méthode renderList, normalement tu n'as pas besoin de surcharger cette méthode, tout ce qui est affectation de variable doit être fait dans le constructeur.

[...]

Share this post


Link to post
Share on other sites

Bonjour,

 

Je continue donc d'avancer vers le droit chemin en suivant le Canvas de JDanse qui est effectivement très bien documenté !

 

Si je comprends bien ta remarque concernant la méthode RenderList, il faut que je place le contenu de celle ci :

public function renderList()
{
 $this->addRowAction('edit');
 $this->addRowAction('delete');
 $this->addRowAction('details');

 $this->bulk_actions = array(
  'delete' => array(
   'text' => $this->l('Delete selected'),
   'confirm' => $this->l('Delete selected items?')
   )
  );

 $this->fields_list = array(
  'id_offre' => array(
   'title' => $this->l('id_offre'),
   'align' => 'center',
   'width' => 25
  ),
  'text' => array(
   'title' => $this->l('text'),
   'width' => 'auto',
  ),
 );

 // Gère les positions
 $this->fields_list['position'] = array(
   'title' => $this->l('Position'),
   'width' => 70,
   'align' => 'center',
   'position' => 'position'
  );

 $lists = parent::renderList();

 parent::initToolbar();

 return $lists;
}

 

au sein du constructeur __construct de la classe AdminExampleController ?

Share this post


Link to post
Share on other sites

Salut,

 

Exact, tu peux supprimer la méthode renderList de ton ModuleAdminController car il n'y pas besoin de surcharger cette méthode, si tu regardes les AdminController natif, tu verras qu'ils le font dans le constructeur.

 

Donc tu peux mettre ça dans le constructeur:

$this->addRowAction('edit');
$this->addRowAction('delete');
$this->addRowAction('details');

$this->bulk_actions = array(
'delete' => array(
	'text' => $this->l('Delete selected'),
	'confirm' => $this->l('Delete selected items?')
)
);

$this->fields_list = array(
'id_offre' => array(
	'title' => $this->l('id_offre'),
	'align' => 'center',
	'width' => 25
),
'text' => array(
	'title' => $this->l('text'),
	'width' => 'auto',
),
'position' => array( // Gère les positions
	'title' => $this->l('Position'),
	'width' => 70,
	'align' => 'center',
	'position' => 'position'
)
);

Share this post


Link to post
Share on other sites

Bonjour,

 

Je tenais à vous remercier pour votre précieuse aide. Grâce au canvas de J.Danse et aux remarques de Mat75, j'ai enfin réussi à résoudre mon problème de position et à mener à bien mon développement en respectant l'architecture MVC..

 

A bientôt !

post-388583-0-34308400-1376387600_thumb.png

Share this post


Link to post
Share on other sites
Le 06/08/2013 à 4:15 PM, J. Danse a dit :

 


$this->_defaultOrderBy = 'position';
 

Non, mais en fait ça fonctionne parfaitement il faut juste lui donner les bons éléments ;)

		$helper = new HelperList();
		$helper->shopLinkType = '';
		$helper->imageType = 'jpg';
		$helper->simple_header = true;
		$helper->actions = $actions;
		$helper->show_toolbar = false;
		$helper->module = $this;
		$helper->listTotal = count($blocks);
		$helper->identifier = 'id_mon_module';
		$helper->orderBy = 'position';
		$helper->position_identifier = 'position';
                $helper->position_group_identifier = 0;
....

et dans le field_list:

,
			'position' => array(
			   'title' => $this->l('Position'),
			   'width' => 70,
			   'align' => 'center',
			   'position' => 'position'
			)

 

Share this post


Link to post
Share on other sites

Wow. Ce déterrage impromptu et sans aucun sens d'un sujet de 2013. Palme du déterrage 2019 sans aucun doutes.

Share this post


Link to post
Share on other sites

Pourquoi aucun sens ?

J'ai suivi ton idée

Le 08/08/2013 à 2:02 PM, J. Danse a dit :

Mais, par contre, il est vrai que l'on devrait pouvoir utiliser un HelperList même dans un configure de module, cela dit. Et entièrement :)

Pourquoi se compliquer la vie sérieusement ?

Share this post


Link to post
Share on other sites

2013 -> 2019. Y'a eu un LARGE spectre de commits/de modifications sur le projet ainsi que sur l'utilisation des Helper.

Ca n'a aucun sens de déterrer ce sujet. Inutilement.

Très clairement, utiliser un HelperList/HelperForm/Helper* dans un module est désormais bien plus possible qu'avant ; il existe cependant des techniques plus récentes (mais pour cela, il faut utiliser une version 1.7, bien entendu).

Share this post


Link to post
Share on other sites

Je ne te comprends vraiment pas?

Ce code fonctionne parfaitement sur les 1.5 et 1.6 et si quelqu'un tombe sur ce sujet au moins il aura une réponse à sa problématique. Ce n'est pas le but d'un forum d'entraide ?

Tout le monde n'est pas en 1.7, loin de là.

Share this post


Link to post
Share on other sites

En plus ça évitera à l’équipe de virer le contenu puisque... ils doivent manquer de stockage car ils virent tout ce qui est ancien et surtout utile.

Étrange quand même de voir une réaction "déterrage" sur ce topic où il est apporté quelque chose alors que les déterrages pour "j'ai le même problème" quasi hebdomadaire, aucune réaction

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×
×
  • Create New...

Important Information

Cookies ensure the smooth running of our services. Using these, you accept the use of cookies. Learn More