Prestashop : Ajouter des champs dans un formulaire d’administration

Ce tutoriel est compatible avec les versions de Prestashop suivantes :
1.6 1.7 1.7.5 1.7.7 1.7.8 8.0 +
Cet article est assez ancien, malgré toute l'attention que j' apporte à mes contenus il est possible que celui-ci ne soit plus d'actualité.
N'hésitez pas à me le signaler si nécessaire via le formulaire de contact.

Depuis la version 1.6 de Prestashop, il est possible de rajouter rapidement et facilement le formulaire d’édition d’un objet dans l’administration via un module personnalisé.
Et ceci sans surcharge particulière en utilisant tout simplement les hooks existants.

Les objets éditables via cette méthodes sont ceux qui utilisent l’ancien fonctionnement (non symfony ) de l’administration.
Vous pouvez consulter cet article pour les identifier facilement : https://www.h-hennes.fr/blog/2019/07/25/prestashop-1-7-identifier-si-un-controller-admin-a-ete-migre-vers-symfony/

pour ajouter des champs sur le produit vous pouvez consulter l Prestashop 1.7 : Ajouter des champs produit

Cette modification est réalisable via les hooks dynamiques suivants :

Dans la fonction renderForm de la classe AdminController

Hook::exec('action'.$this->controller_name.'FormModifier')

Dans la fonction postProcess de la classe AdminController via aux choix les hooks suivants :

//Avant l'exécution de l'action du controller admin
Hook::exec('actionAdmin'.ucfirst($this->action).'Before', array('controller' => $this));
Hook::exec('action'.get_class($this).ucfirst($this->action).'Before', array('controller' => $this));
 
 //Après l'exécution de l'action du controller admin
 Hook::exec('actionAdmin'.ucfirst($this->action).'After', array('controller' => $this, 'return' => $return));
 Hook::exec('action'.get_class($this).ucfirst($this->action).'After', array('controller' => $this, 'return' => $return));

Vu comme ça les hooks paraissent un peu barbares mais il n’en est rien :-), ce sera beaucoup plus parlant avec un exemple.

Exemple

Pour illustrer comment réaliser cela nous allons modifier le formulaire d’édition d’une catégorie produit.
Nous souhaitons rajouter plusieurs paramètres personnalisés puis les sauvegarder ensuite.

Le controller admin concerné pour les catégorie est AdminCategories.
Les hooks à implémenter seront donc les suivants :

  • actionAdminCategoriesFormModifier ($this->controller_name = AdminCategories  => Modification du formulaire )
  • actionAdminCategoriesControllerSaveBefore ( get_class($this) = AdminCategoriesController // $this->action = Save  => Exécutée avant l’action « Save du controller » )
  • actionAdminCategoriesControllerSaveAfter ( get_class($this) = AdminCategoriesController // $this->action = Save  => Exécutée après l’action « Save du controller » )

Nous pourrions également utiliser les hooks généraux

  • actionAdminSaveBefore
  • actionAdminSaveAfter

Cependant je ne le recommande pas dans ce cas, car il sont exécutés lors des enregistrements de l’ensemble des entités en back office.
Dans notre cas il vaut mieux cibler plus précisément l’action.

Mise en oeuvre

Pour mettre en oeuvre ces concepts, nous allons créer un module Hh_SampleAdminForm

Voici la base ( déclaration / installation / désinstallation )

public function __construct()
    {
        $this->name = 'hh_sampleadminform';
        $this->tab = 'others';
        $this->version = '0.1.0';
        $this->author = 'hhennes';
        $this->bootstrap = true;
        parent::__construct();
 
        $this->displayName = $this->l('Sample Admin form');
        $this->description = $this->l('Sample module for admin form hooks');
        $this->ps_versions_compliancy = array('min' => '1.6', 'max' => _PS_VERSION_);
    }
 
    /**
     * Installation du module
     * @return bool
     */
    public function install()
    {
        if ( ! parent::install()
            || !$this->registerHook('actionAdminCategoriesControllerSaveAfter')
            || !$this->registerHook('actionAdminCategoriesFormModifier')
        ) {
            return false;
        }
 
        return true;
    }
 
    /**
     * Désinstallation du module
     * @return bool
     */
    public function uninstall()
    {
        return parent::uninstall();
    }

Affichage des nouveaux champs

Passons ensuite à l’affichage de nos nouveaux paramètres.
Il existe plusieurs possibilités :

  • Ajouter au formulaire existant
  • Créer un nouveau fieldset

Les codes reprennent l’utilisation d’un helperForm Standard.
Les paramètres passés à la fonction étant les suivants :

Hook::exec('action'.$this->controller_name.'FormModifier', array(
                'fields' => &$this->fields_form,
                'fields_value' => &$fields_value,
                'form_vars' => &$this->tpl_form_vars,
            ));

Attention au fait que les variables sont passées par référence ( signe & ) ce qui signifie qu’on peut les modifier directement dans le hook.
On peut donc également modifier des éléments déjà définis par défaut.

public function hookActionAdminCategoriesFormModifier($params)
    {
 
        //Ajout d'un champ au fieldset par défaut
        $params['fields'][0]['form']['input'][] =  array(
                        'type' => 'text',
                        'label' => $this->l('Custom field 1'),
                        'name' => $this->name.'_newfield1',
                    );
 
       //Modification des propriétés d'un champ déjà existant
        foreach ( $params['fields'][0]['form']['input'] as &$field ){
 
           if ( $field['name'] == 'meta_description'){
                $field['maxlength'] = '255';
                $field['maxchar'] = '255';        
                $field['hint'] = 'Modified by a module';
            }
        }
 
        //Création d'un nouveau fieldset
        $params['fields'][$this->name] = array(
            'form' => array(
                'legend' => array(
                    'title' => $this->l('Sample Category Fieldset'),
                    'icon' => 'icon-tags',
                ),
                'description' => $this->l('New sample fieldset'),
                'input' => array(
                    array(
                        'type' => 'text',
                        'label' => $this->l('Custom field New Fieldset 1'),
                        'name' => $this->name.'_newfieldset1',
                    ),
                    array(
                        'type' => 'text',
                        'label' => $this->l('Custom field New Fieldset 2'),
                        'name' => $this->name.'_newfieldset2',
                    ),
                )
            )
        );
 
        //Pour remonter les valeurs des champs
        $params['fields_value'][$this->name.'_newfield1'] = 'Custom value 1';
        $params['fields_value'][$this->name.'_newfieldset1'] = 'Custom value fieldset 1';
        $params['fields_value'][$this->name.'_newfieldset2'] = 'Custom value fieldset 2';
    }

Le rendu est le suivant :

Nouveaux champs admin prestashop

Enregistrement des données

Il est temps à présent de passer à l’enregistrement des données.
Les hooks actionAdminCategoriesControllerSaveAfter et actionAdminCategoriesControllerSaveBefore étant redondants pour notre example je n’utiliserais que l’After
Pour le traitement des données nous n’auront qu’a récupérer les variables posts envoyées par le formulaire

 public function hookActionAdminCategoriesControllerSaveAfter($params)
    {
        //Récupération des variables custom soumises via le formulaire
        $custom1 = Tools::getValue($this->name.'_newfield1');
        $fiedlset1 = Tools::getValue($this->name.'_newfieldset1');
        $fiedlset2 = Tools::getValue($this->name.'_newfieldset2');
 
        //Faites ensuite le traitement souhaité
    }

Et voila nous avons rajouté facilement des informations à un formulaire admin sans faire de surcharge de classe 😉

 

46 réflexions sur “Prestashop : Ajouter des champs dans un formulaire d’administration”

  1. Bonjour,

    je souhaite ajouter un field « upload » lors de l’enregistrement d’un client. Le champ apparait bien sauf que l’upload ne se fait jamais…

    J’ai dans customerFormatter.php

    $format[‘fileupload’] = (new FormField)
    ->setName(‘fileupload’)
    ->setType(‘file’)
    ->setLabel(
    $this->translator->trans(
    ‘Document ID’, [], ‘Shop.Forms.Labels’
    )
    )
    ;

    et j’ai fait un ALTER TABLE `ps_customer` ADD `fileupload` VARCHAR(100) NOT NULL;

    Le nom du fichier est bien stocké dans la DB mais ce que je voudrais faire c’est avoir l’url qui pointe dans le dossier upload.

    Donc j’ai rajouté dans « AdminCustomersController.php » à la function processAdd()

    $_registration_allowed_extensions = array(‘txt’,’rtf’,’doc’,’docx’,’pdf’,’png’,’jpeg’,’gif’,’jpg’);

    $uploader = new Uploader(‘fileupload’); //Renseigner ici le nom du champ input
    $uploader->setAcceptTypes($this->_registration_allowed_extensions) // Définition des extensions autorisées
    ->setCheckFileSize(UploaderCore::DEFAULT_MAX_SIZE) //Taille maximum des fichiers à envoyer
    ->setSavePath(dirname(__FILE__) . ‘/’ . $this->_upload_dir) // Répertoire de destination
    ->process(); // Traitement de l’envoi

    Mais rien n’est uploadé… Je debute encore en développement, pouvez vous m’aider ?

    Merci beaucoup!

    1. Bonjour,

      Votre approche de modifier directement les fichiers prestashop n’est pas la bonne.
      Comme évoqué dans mon article il est préférable de passer par la création d’un module et l’utilisation des hooks.
      Votre logique a cependant l’air d’être bonne, est-ce que le dossier d’upload existe bien ? ( j’ai déjà eu des problèmes d’upload liés à ce point )
      Avez-vous tenté d’afficher le contenu du $_FILES lors de l’envoi de vos informations ?

      Cordialement,
      Hervé

  2. Bonjour,

    Merci de votre réponse! Oui j’aimerai faire ça sauf que je suis dans la version prestashop 1.7 et votre tutorial était pour 1.6 donc j’ai eu peur que cela ne soit pas la même chose… Donc j’ai trifouillé un peu partout sur le net mais personne n’a encore fait d’exemple concret sur 1.7.
    Je suis encore débutant sur Prestashop, donc hook, création de module… je ne connais strictement rien.

    Je n’ai pas encore testé d’afficher le $_FILES. Le dossier upload existe bel et bien. Le problème est que je ne sais même pas si le code que j’ai mis est dans la bonne place ?

    Merci d’avance

    Vince

    1. Bonjour,

      En partant de la logique de mon article l’upload d’une image est tout à fait fonctionnel.
      La version 1.7 fonctionne comme la 1.6 pour ces controllers admin.

      Voici un exemple de code sans surcharge qui ajoute un champ d’upload d’image via un module et gère son envoi.

      class HhAdmin extends Module
      {

      public function __construct()
      {
      $this->name = 'hhadmin';
      $this->tab = 'others';
      $this->author = 'hhennes';
      $this->version = '0.1.0';
      $this->need_instance = 0;
      $this->bootstrap = true;

      parent::__construct();

      $this->displayName = $this->l('hhadmin');
      $this->description = $this->l('hhadmin description');
      $this->ps_versions_compliancy = array('min' => '1.6', 'max' => _PS_VERSION_);
      }

      /**
      * @todo Test un champ upload sur les customers
      * @return boolean
      */
      public function install()
      {
      if ( ! parent::install()
      || !$this->registerHook('actionAdminCustomersControllerSaveAfter')
      || !$this->registerHook('actionAdminCustomersFormModifier')
      ) {
      return false;
      }

      return true;
      }

      public function hookActionAdminCustomersControllerSaveAfter($params)
      {
      //Gestion de l'upload
      $_registration_allowed_extensions = array('txt','rtf','doc','docx','pdf','png','jpeg','gif','jpg');

      $uploader = new Uploader('fileupload'); //Renseigner ici le nom du champ input
      $uploader->setAcceptTypes($_registration_allowed_extensions) // Définition des extensions autorisées
      ->setCheckFileSize(Uploader::DEFAULT_MAX_SIZE) //Taille maximum des fichiers à envoyer
      ->setSavePath(dirname(__FILE__)) // Répertoire de destination
      ->process(); // Traitement de l'envoi

      }

      /**
      * Modification du formulaire d'édition d'un client
      * @param type $params
      */
      public function hookActionAdminCustomersFormModifier($params)
      {

      $params['fields'][0]['form']['input'][] = array(
      'type' => 'file',
      'label' => $this->l('File upload'),
      'name' => 'fileupload',
      'hint' => $this->l('File upload field add with a module')
      );
      }
      }

  3. Bonsoir!

    Merci beaucoup! j’ai pu copié le code et installé le module correctement sauf qu’il n’y a pas le champ upload lors de l’inscription d’un utilisateur. J’ai vidé le cache et enlever mon code précédemment dans la classe CustomerFormatter.php

    Si je comprends bien ceci permet d’afficher le champ mais cela n’affiche rien chez moi :

    /**
    * Modification du formulaire d’édition d’un client
    * @param type $params
    */
    public function hookActionAdminCustomersFormModifier($params)
    {
    $params[‘fields’][0][‘form’][‘input’][] = array(
    ‘type’ => ‘file’,
    ‘label’ => $this->l(‘File upload’),
    ‘name’ => ‘fileupload’,
    ‘hint’ => $this->l(‘File upload field add with a module’)
    );
    }

    Merci d’avance

    1. Bonjour,

      Effectivement ce tutoriel est complet, mais très aproximatif et il ne suis absolument pas les bonnes pratiques prestashop ( En éditant les fichiers systèmes ceux-ci seront écrasés lors de la mise à jour de votre site )

      Ma réponse était uniquement axée sur la partie backoffice de ce champ qui est la problématique initiale de cet article.
      Le fait d’ajouter des nouveaux champs visibles sur le front office n’est pas du tout traité.

      En conservant la logique des hooks et des modules il est possible de rajouter un champ via le hook additionalCustomerFormFields comme vous pouvez le voir dans le fichier : https://github.com/PrestaShop/PrestaShop/blob/develop/classes/form/CustomerFormatter.php#L211
      En revanche je n’ai pas encore fait face à cette problématique, donc je n’ai pas de code tout fait à vous fournir.
      Si j’ai du temps je vais essayer de faire un article complet sur le sujet ( en me basant peut être sur votre lien mais avec les bonnes pratiques )

      Cordialement,
      Hervé

  4. Merci 😀

    J’ai essayé de rajouter le code ci dessous dans le module mais bon ca m’a pas l’air de bien marcher.
    Lorsque j’ajoute ceci dans la fonction getFormat de CustormerFormatter.php le field apparait bien.

    public function hookAdditionalCustomerFormFields($params)
    {

    $params[‘fileupload’] = (new FormField)
    ->setName(‘fileupload’)
    ->setType(‘file’)
    ->setLabel(
    $this->translator->trans(
    ‘Document ID’, [], ‘Shop.Forms.Labels’
    )
    );
    }

  5. Bonsoir,

    Merci du conseil! Oui j’ai mis avant :

    if ( ! parent::install()
    || !$this->registerHook(‘additionalCustomerFormFields’)
    || !$this->registerHook(‘actionAdminCustomersControllerSaveAfter’)
    || !$this->registerHook(‘actionAdminCustomersFormModifier’)
    )

    J’ai ensuite changé avec le return :

    public function hookAdditionalCustomerFormFields($params)
    {

    return array((new FormField)
    ->setName(‘fileupload’)
    ->setType(‘file’)
    ->setLabel(
    $this->translator->trans(
    ‘Document ID’, [], ‘Shop.Forms.Labels’
    )
    ));

    Mais toujours rien :S

  6. Re,

    le probleme venait de $this->translator->trans(
    ‘Document ID’, [], ‘Shop.Forms.Labels’
    )

    j’ai changé en : setLabel(‘Document ID’)

    et le field apparait bel et bien! Sauf que l’upload ne fonctionnne pas

  7. J’ai réutilisé votre code pour le module upload en presta 1.6

    https://codeshare.io/GbwQLV

    avec public function hookActionCustomerAccountAdd($params

    Le hook est dans CustomerPersister.php maintenant mais je ne sais pas si c’est bien ce hook qu’il faut utiliser ? car quand j’upload quelques choses, rien ne s’upload dans le dossier upload

  8. Bonjour,

    J’ai fait des var_dump($_FILES);
    mais en fait il est toujours NULL
    Donc le hook qui est censé gérer l’upload ne se déclenche en fait jamais.
    Je ne sais pas trop quel hook utiliser pour faire ça ?

    est-ce : hookActionAdminCustomersControllerStatusAfter
    ou
    hookActionAdminCustomersControllerSaveAfter
    ou bien hookActionCustomerAccountAdd ?

    Merci d’avance

    1. Bonjour,

      Ce problème n’est pas lié au hook, mais au fait que le formulaire de création de compte sur le front ne permets pas l’envoi de fichier à première vue.
      Il faudrait donc ajouter le paramètre enctype= »multipart/form-data » directement dans le template du formulaire.

      Cordialement,
      Hervé

  9. Merci!

    J’ai réussi à mettre dans la balise de la page enctype= »multipart/form-data » (en js).
    Mais cela ne fait toujours rien. Rien n’est uploadé

  10. Merci pour votre article. J’ai une question supplémentaire. Vous avez une piste pour effectuer ce traitement mais justement dans la fiche produit ?

    Merci

  11. Bonjour !
    Merci de votre code qui fonctionne très bien (prestashop 1.6).
    J’ai une question cependant : mon champ est bien enregistré en base mais lorsque je reviens sur le formulaire, il ne remonte pas, puisqu’il y a cette ligne :

    $params[‘fields_value’][$this->name.’_newfield1′] = ‘Custom value 1’;

    Comment faire pour remonter, à la place d’une chaîne de caractères, la valeur enregistrée en base de données ?

    Merci beaucoup

    1. Bonjour Agnes,

      Je ne vois pas trop d’ou vient votre difficulté.
      Pour assigner une valeur en base de données il vous suffit de lancer vune simple requête sql.
      Vous avez accès à l’identifiant de l’entité situé dans les paramètres d’url via la fonction Tools::getValue()

      Cordialement,
      Hervé

      Cordialement,
      Hervé

  12. Bonjour,

    Merci pour cet article utile, mais malheureusement, cela ne me permet pas de faire ce que je souhaite 🙁

    Je souhaite modifier les attributs d’un input « natif » au RenderForm de PrestaShop.

    En l’occurence, dans le controller AdminCategories, j’ai besoin de modifier la taille (160) du champ meta_description. J’arrive sans soucis a ajouter un field « custom » mais impossible de trouver comment modifier un field existant.

    Avez-vous une idée pour faire cela ? Est-ce possible depuis un module / override ?

    Merci,
    Dimitri

    1. Bonjour Dimitri,

      Votre demande est très pertinente merci.
      C’est tout à fait possible via cette méthode, je viens de mettre à jour l’article en conséquence 🙂
      Comme nous avons accès la référence de la variable, les modifications effectuées sur celle-ci remonteront bien dans le formulaire.

      Cordialement,
      Hervé

  13. Merci pour cette mise à jour, ça fonctionne parfaitement, et très simplement !

    C’est vraiment un gros défaut de PrestaShop le manque de documentation … heureusement qu’il y a une communauté 🙂

    Merci beaucoup,
    Dimitri

  14. Bonjour ,
    Super tuto merci cela marche niquel , par contre j’aurai une question ,vu que l’on ne fais pas de surcharge comment est ce qu’on injecte nos custom value en front ?
    Notament au niveau de category.tpl pour ma part

    1. Bonjour,

      Cet article illustre comment faire pour ajouter des champs dans le formulaire d’administration, ce qui peut être utile lors de la création de module tiers qui utilisent des tables additionnelles par exemple.
      Pour quelle version de Prestashop souhaitez vous faire remonter les informations ?
      Sur la 1.7 vous pouvez utiliser le hook « filterCategoryContent » pour ajouter ou modifier des informations.

      Cordialement,

  15. Bonjour,

    Je suis présentement en train de travailler sur un site de client sur la version 1.7.3.2 de Prestashop et je n’y connais rien en Prestashop!

    J’ai réussi à faire afficher un champs personnalisé dans les fiches clients du Back Office. Cependant, aussitôt que je dépasse la première page de clients ou que j’accède à un compte client à partir de la recherche, mon champ personnalisé n’est pas sauvegardé! Je ne peux même plus modifié ceux qui fonctionnaient sur la première page.

    Je dois alors redémarrer mon navigateur (testé sur -> Chrome, Firefox & Edge), me reconnecter et seulement à ce moment je peux modifier mon champ personnalisé de la première page de clients…

    Avez-vous une idée?

    Merci,

    Claude M-K.

    1. Bonjour Claude,
      Je ne comprends pas exactement le comportement que vous obtenez.
      Avez-vous bien surchargé l’entité client pour que les données soient enregistrées ?
      Cet article illustre uniquement comment afficher les champs, mais pas comment les sauvegarder.

      Cordialement,
      Hervé

  16. Bonjour Hervé,

    J’ai bien surchargé l’entité client pour me permettre de sauvegarder les données. J’ai également suivi votre autre article qui montrait comment faire.

    La donnée de mon champ supplémentaire s’enregistre bien dans la base de données tant et aussi longtemps que je reste sur la première page des clients.

    Aussitôt que je fais une recherche de client ou si je change pour la deuxième page de clients, le champ supplémentaire ne s’enregistre plus dans la base de données, pas même ceux qui fonctionnaient sur la première page.

    Je dois alors fermer le navigateur pour pouvoir modifier les clients de la première page. Par contre, les 15000 autres clients sont impossibles à modifier.

    Merci,
    Claude M-K.

  17. Bonjour,
    J’ai ajouté un champs de type datetime dans la liste des commandes.
    Je souhaite appliquer une class bold à ce champs lorsque cette date est supérieure à la date d’aujourd’hui.
    Mais cela ne marche pas…
    Voici mes bouts de codes :
    Dans hookActionAdminOrdersListingFieldsModifier
    [code]
    if (!isset($params[‘fields’][‘latest_ship_date’])) {
    $params[‘fields’][‘latest_ship_date’] = array(
    ‘title’ => $this->l(‘Date Exp. Max.’),
    ‘align’ => ‘text-right’,
    « filter_key » => « amo!latest_ship_date »,
    ‘callback’ => ‘LastShip’,
    ‘type’ => ‘datetime’,
    « callback_object » => Module::getInstanceByName($this->name),
    « class » => $classe,
    );
    }
    public static function LastShip($id_order, $tr)
    {
    foreach ($tr[‘latest_ship_date’] as &$field )
    {
    //$latest_ship_date = $id_order->latest_ship_date;
    $latest_ship_date=$tr[‘latest_ship_date’];
    $now=new DateTime(« now »);
    if ($tr[‘latest_ship_date’] < $now)
    {
    //$classe = 'boldok';
    return $tr['latest_ship_date'];
    //return $tr['latest_ship_date'];

    }
    else
    {
    //$classe = 'boldnok';
    return $tr['latest_ship_date'];
    //return $tr['latest_ship_date'];
    //return date("d/m/Y H:i:s");
    }
    }
    }
    [/code]
    Merci d'avance.
    Bruce

    1. Bonjour Bruce,
      Votre appel de callback semble bon, en reprenant un appel identique j’ai bien un code fonctionnel.
      Pensez à activer le mode dev qui pourrait vous remonter des erreurs utiles pour corriger ce point.

      Cordialement,
      Hervé

  18. Bonjour Hervé, je suis vos tutos depuis des années et je vous remercie car ils m’ont souvent sorti du pétrin !

    J’ai suivi ce tuto avec attention mais malheureusement il n’a plus l’air de fonctionner pour une 1.7.6.0, j’ai beau faire des dump dans les méthodes actionAdminCategoriesControllerSaveAfter et actionAdminCategoriesFormModifier, rien ne s’affiche, comme s’il s’en fichait.

    D’autant plus que les anciens tutos qui font des overrides de /controllers/admin/AdminCategoriesController.php ne fonctionnent plus non plus car ce fichier n’existe plus (déplacé dans /src/PrestaShopBundle/Controller/Admin/Sell/Catalog/CategoryController.php qui n’est pas – encore – overridable).

    Il y a bien le hook displayBackOfficeCategory mais celui n’a pas l’air de fonctionner non plus…

    Voila, si jamais vous avez une astuce… Et si j’y arrive je vous le dit !

    Merci encore pour vos tutos 🙂

    1. Bonjour,

      Effectivement cet article n’est plus applicable aux catégories depuis la version 1.7.6 de Prestashop …
      La migration des controllers admin vers symfony au fur et à mesure des versions, fait que cet article sera de moins en moins utile sur les futures versions de prestashop 1.7
      Je vais rajouter une note d’information et donner les informations nécessaires pour identifier si un controller admin utilise l’ancienne ou la nouvelle architecture.
      Je n’ai pour l’instant pas tenté de mettre en place cette modification sur des pages migrées, j’ai vu que des travaux étaient encore en cours car le process n’était pas encore tout à fait au point.
      Mais je vais essayer de tester l’état actuel et voir quelles sont les possibilités sans surcharger les fichiers du core.

      Cordialement,
      Hervé

  19. Alors je suis bien dégoûté car à l’aide du hookDisplayBackOfficeCategory j’ai pu afficher mon nouveau champ (un colorpicker, la galèèèère) par contre impossible d’enregistrer sa valeur, aucun hook n’est appelé dans le nouveau controller. Je continue l’investigation et vous tiens au courant.
    Et si j’y arrive, je vous fourni les sources du module !

    Cordialement,
    Rémi

  20. (Désolé pour le spam, je vous laisse modérer)

    J’ai enfin réussi à enregistrer un nouveau champ dans ma catégorie. J’utilise le hookDisplayBackOfficeCategory pour l’afficher et les hookActionAfterCreateCategoryFormHandler et hookActionAfterUpdateCategoryFormHandler pour l’enregistrer (à la création et à la mise à jour de la catégorie, c’est en fait le même code).

    Voici le code de ces hooks :

    public function hookDisplayBackOfficeCategory($params)
    {
    $id_category = (int) $params[‘request’]->get(‘categoryId’);
    $color =  »;
    if($id_category) {
    $category = new Category($id_category);
    $color = $category->color;
    }

    $this->context->smarty->assign([
    ‘color’ => $color,
    ]);

    return $this->display(__FILE__, ‘views/templates/admin/category_infos.tpl’);
    }

    et

    // Meme code pour hookActionAfterUpdateCategoryFormHandler
    public function hookActionAfterCreateCategoryFormHandler($params)
    {
    $id_category = (int) $params[‘id’];
    $color = $params[‘request’]->get(‘category_color’);
    $category = new Category($id_category);
    $category->color = $color;
    $category->update();
    }

    En espérant que ça aidera !!

    Cordialement,
    Rémi

    1. Bonjour Rémi,
      Merci pour votre retour et pour le partage 🙂 !
      J’essaierais de faire un article de mise à jour compatibles les dernières versions de prestashop durant les prochaines semaines

  21. Bonjour,

    je trouve vos posts super et je vous en remercie.
    Depuis que je suis passé sur le version 1.7.6 je suis un peu perdu.
    Voici mon fichier module…mais malgré cela, le champ en question n’apparait pas dans le backend 🙁

    ps : je suis en multi-boutiques.

    ?php

    if (!defined(‘_PS_VERSION_’)) {
    exit;
    }

    class Facture extends PaymentModule
    {
    private $_html =  »;
    private $_postErrors = array();

    public $address;

    public function __construct()
    {
    $this->author = ‘JNKConsult’;
    $this->name = ‘facture’;
    $this->tab = ‘payments_gateways’;
    $this->version = ‘0.4’;
    $this->controllers = array(‘payment’,’validation’);
    $this->currencies = true;
    $this->currencies_mode = ‘checkbox’;
    $this->bootstrap = true;
    $this->need_instance = 0;

    parent::__construct();

    $this->displayName = $this->l(‘Facture Mensuelle’);
    $this->description = $this->l(‘Paiement via facture mensuelle’);
    $this->ps_versions_compliancy = array(‘min’ => ‘1.7.0’, ‘max’ => _PS_VERSION_);

    }

    /**
    * Installation du module
    * @return boolean
    */
    public function install() {
    if (!parent::install()
    // Install Sql du module
    || !$this->_installSql()
    || !$this->registerHook(‘actionAdminCustomersFormModifier’)
    || !$this->registerHook(‘actionAdminCustomersControllerSaveAfter’)
    || !$this->registerHook(‘paymentOptions’)
    || !$this->registerHook(‘paymentReturn’)
    ) {
    return false;
    }

    return true;
    }

    /**
    * Désinstallation du module
    * @return boolean
    */
    public function uninstall() {
    return parent::uninstall() && $this->_unInstallSql();
    }

    /**
    * Modifications sql du module
    * @return boolean
    */
    protected function _installSql() {
    $sqlInstall = « ALTER TABLE  » . _DB_PREFIX_ . « customer  »
    . « ADD customer_invoice_id VARCHAR(255) NULL »;

    return Db::getInstance()->execute($sqlInstall);
    }

    /**
    * Suppression des modification sql du module
    * @return boolean
    */
    protected function _unInstallSql() {
    $sqlUnInstall = « ALTER TABLE  » . _DB_PREFIX_ . « customer  »
    . « DROP customer_invoice_id »;

    return Db::getInstance()->execute($sqlUnInstall);
    }

    /**
    * Returns a string containing the HTML necessary to
    * generate a configuration screen on the admin
    *
    * @return string
    */
    public function getContent()
    {
    return $this->_html;
    }

    /**
    * Display this module as a payment option during the checkout
    *
    * @param array $params
    * @return array|void
    */
    public function hookPaymentOptions($params)
    {
    /*
    * Verify if this module is active
    */
    if (!$this->active) {
    return;
    }

    /**
    * Form action URL. The form data will be sent to the
    * validation controller when the user finishes
    * the order process.
    */
    $formAction = $this->context->link->getModuleLink($this->name, ‘validation’, array(), true);

    /**
    * Assign the url form action to the template var $action
    */
    $this->smarty->assign([‘action’ => $formAction]);

    /**
    * Load form template to be displayed in the checkout step
    */
    $paymentForm = $this->fetch(‘module:facture/views/templates/hook/payment_options.tpl’);

    /**
    * Create a PaymentOption object containing the necessary data
    * to display this module in the checkout
    */
    $newOption = new PrestaShop\PrestaShop\Core\Payment\PaymentOption;
    $newOption->setModuleName($this->displayName)
    ->setCallToActionText($this->displayName)
    ->setAction($formAction)
    ->setForm($paymentForm);

    $payment_options = array(
    $newOption
    );

    return $payment_options;
    }

    /**
    * Display a message in the paymentReturn hook
    *
    * @param array $params
    * @return string
    */
    public function hookPaymentReturn($params)
    {
    /**
    * Verify if this module is enabled
    */
    if (!$this->active) {
    return;
    }

    return $this->fetch(‘module:facture/views/templates/hook/payment_return.tpl’);
    }

    public function hookActionAdminCustomersFormModifier($params) {

    $params[‘fields’][0][‘form’][‘input’][] = [
    ‘type’ => ‘text’,
    ‘label’ => $this->l(‘Customer invoice id’),
    ‘name’ => ‘customer_invoice_id’,
    ‘class’ => ‘input fixed-width-xxl’,
    ‘hint’ => $this->l(‘Customer invoice id’)
    ];

    $params[‘fields_value’][‘customer_invoice_id’] = $params[‘object’]->customer_invoice_id;

    }

    public function hookActionAdminCustomersControllerSaveAfter($params)
    {

    }
    }

    1. Bonjour,

      Effectivement la page de gestion des clients a été mise à jour vers le nouveau framework sur la version 1.7.6
      J’ai mis à jour l’article, et créé un nouvel article qui permets d’identifier facilement si le controller admin a été migré ou non vers symfony :
      https://www.h-hennes.fr/blog/2019/07/25/prestashop-1-7-identifier-si-un-controller-admin-a-ete-migre-vers-symfony/

      Je me note de faire un article de mise à jour sur les nouveaux fonctionnements.

      Cordialement,
      Hervé

  22. Bonjour,

    je n’arrive pas à trouver le bon hook pour la sauvegarde d’une page CMS dans l’admin, j’ai testé hookActionAdminCmsContentSaveAfter mais ça ne marche pas

  23. Bonjour,

    Merci pour la qualité de vos contenus sur prestashop. Je rencontre néanmoins un soucis sur celui-ci.
    En effet je souhaite ajouter un champ à la valeur d’une caractéristique (champ textarea avec tiny par exemple).
    Le formModifier, fonctionne sur l’ajout/edition d’une caractéristique, mais pas sur la value (c’est dans le même controleur (AdminFeatures), mais conditionné au display) et ce n’est pas encore un controler symfony (je suis sur la 1.7.8.5)
    Avez-vous une astuce pour cela ? j’aimerais vraiment éviter les overrides.

    par avance merci

    1. Bonjour Vincent,

      Le cas des caractéristiques est effectivement spécifique.
      Vous pouvez le gérer en utilisant le hook displayFeatureValueForm qui est présent dans le fichier admin/themes/default/template/controllers/feature_value/helpers/form/form.tpl
      Le module ps_facetedsearch l’utilise par exemple pour afficher les champs supplémentaires url et meta title.
      Vous devriez pouvoir vous inspirer de son fonctionnement.

      Cordialement,
      Hervé

Répondre à Bruce Annuler la réponse

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