{"id":1554,"date":"2017-06-21T22:19:46","date_gmt":"2017-06-21T20:19:46","guid":{"rendered":"https:\/\/www.h-hennes.fr\/blog\/?p=1554"},"modified":"2020-03-26T14:48:34","modified_gmt":"2020-03-26T12:48:34","slug":"prestashop-ajouter-des-champs-dans-un-formulaire-dadministration","status":"publish","type":"post","link":"https:\/\/www.h-hennes.fr\/blog\/2017\/06\/21\/prestashop-ajouter-des-champs-dans-un-formulaire-dadministration\/","title":{"rendered":"Prestashop : Ajouter des champs dans un formulaire d&rsquo;administration"},"content":{"rendered":"<p>Depuis la version 1.6 de Prestashop, il est possible de rajouter rapidement et facilement le formulaire d&rsquo;\u00e9dition d&rsquo;un objet dans l&rsquo;administration via un module personnalis\u00e9.<br \/>\nEt ceci sans surcharge particuli\u00e8re en utilisant tout simplement les hooks existants.<\/p>\n<p>Les objets \u00e9ditables via cette m\u00e9thodes sont ceux qui utilisent l\u2019ancien fonctionnement (non symfony ) de l&rsquo;administration.<br \/>\nVous pouvez consulter cet article pour les identifier facilement : <a href=\"https:\/\/www.h-hennes.fr\/blog\/2019\/07\/25\/prestashop-1-7-identifier-si-un-controller-admin-a-ete-migre-vers-symfony\/\" target=\"_blank\" rel=\"noopener noreferrer\">https:\/\/www.h-hennes.fr\/blog\/2019\/07\/25\/prestashop-1-7-identifier-si-un-controller-admin-a-ete-migre-vers-symfony\/<\/a><\/p>\n<p>pour ajouter des champs sur le produit vous pouvez consulter l <a href=\"https:\/\/www.h-hennes.fr\/blog\/2017\/10\/10\/prestashop-1-7-ajouter-des-champs-clients\/\">Prestashop 1.7 : Ajouter des champs produit<\/a><\/p>\n<p>Cette modification est r\u00e9alisable via les hooks dynamiques suivants :<\/p>\n<p>Dans la fonction <em>renderForm<\/em> de la classe <em>AdminController<\/em><\/p>\n<pre lang=\"php\" escaped=\"true\">Hook::exec('action'.$this-&gt;controller_name.'FormModifier') \r\n<\/pre>\n<p>Dans la fonction <em>postProcess<\/em> de la classe <em>AdminController<\/em> via aux choix les hooks suivants :<\/p>\n<pre lang=\"php\" escaped=\"true\">\/\/Avant l'ex\u00e9cution de l'action du controller admin\r\nHook::exec('actionAdmin'.ucfirst($this-&gt;action).'Before', array('controller' =&gt; $this));\r\nHook::exec('action'.get_class($this).ucfirst($this-&gt;action).'Before', array('controller' =&gt; $this));\r\n\r\n \/\/Apr\u00e8s l'ex\u00e9cution de l'action du controller admin\r\n Hook::exec('actionAdmin'.ucfirst($this-&gt;action).'After', array('controller' =&gt; $this, 'return' =&gt; $return));\r\n Hook::exec('action'.get_class($this).ucfirst($this-&gt;action).'After', array('controller' =&gt; $this, 'return' =&gt; $return));\r\n<\/pre>\n<p>Vu comme \u00e7a les hooks paraissent un peu barbares mais il n&rsquo;en est rien :-), ce sera beaucoup plus parlant avec un exemple.<\/p>\n<h3 class=\"subtitle\"><span style=\"text-decoration: underline;\"><strong>Exemple<\/strong><\/span><\/h3>\n<p>Pour illustrer comment r\u00e9aliser cela nous allons modifier le formulaire d&rsquo;\u00e9dition d&rsquo;une cat\u00e9gorie produit.<br \/>\nNous souhaitons rajouter plusieurs param\u00e8tres personnalis\u00e9s puis les sauvegarder ensuite.<\/p>\n<p>Le controller admin concern\u00e9 pour les cat\u00e9gorie est <strong><span style=\"color: #0000ff;\">AdminCategories<\/span><\/strong>.<br \/>\nLes hooks \u00e0 impl\u00e9menter seront donc les suivants :<\/p>\n<ul>\n<li>action<span style=\"color: #0000ff;\"><strong>AdminCategories<\/strong><\/span>FormModifier ($this-&gt;controller_name = <strong>AdminCategories<\/strong>\u00a0 =&gt; Modification du formulaire )<\/li>\n<li>action<span style=\"color: #0000ff;\"><strong>AdminCategoriesController<\/strong><\/span><span style=\"color: #ff0000;\">Save<\/span>Before ( get_class($this) = <strong>AdminCategoriesController<\/strong> \/\/ $this-&gt;action = Save\u00a0 =&gt; Ex\u00e9cut\u00e9e avant l&rsquo;action \u00ab\u00a0Save du controller\u00a0\u00bb )<\/li>\n<li>action<strong><span style=\"color: #0000ff;\">AdminCategoriesController<\/span><\/strong><span style=\"color: #ff0000;\">Save<\/span>After ( get_class($this) = <strong>AdminCategoriesController<\/strong> \/\/ $this-&gt;action = Save\u00a0 =&gt; Ex\u00e9cut\u00e9e apr\u00e8s l&rsquo;action \u00ab\u00a0Save du controller\u00a0\u00bb )<\/li>\n<\/ul>\n<p>Nous pourrions \u00e9galement utiliser les hooks g\u00e9n\u00e9raux<\/p>\n<ul>\n<li>actionAdminSaveBefore<\/li>\n<li>actionAdminSaveAfter<\/li>\n<\/ul>\n<p>Cependant je ne le recommande pas dans ce cas, car il sont ex\u00e9cut\u00e9s lors des enregistrements de l&rsquo;ensemble des entit\u00e9s en back office.<br \/>\nDans notre cas il vaut mieux cibler plus pr\u00e9cis\u00e9ment l&rsquo;action.<\/p>\n<h3 class=\"subtitle\"><span style=\"text-decoration: underline;\"><strong>Mise en oeuvre<\/strong><\/span><\/h3>\n<p>Pour mettre en oeuvre ces concepts, nous allons cr\u00e9er un module <strong>Hh_SampleAdminForm<\/strong><\/p>\n<p>Voici la base ( d\u00e9claration \/ installation \/ d\u00e9sinstallation )<\/p>\n<pre lang=\"php\" escaped=\"true\">public function __construct()\r\n    {\r\n        $this-&gt;name = 'hh_sampleadminform';\r\n        $this-&gt;tab = 'others';\r\n        $this-&gt;version = '0.1.0';\r\n        $this-&gt;author = 'hhennes';\r\n        $this-&gt;bootstrap = true;\r\n        parent::__construct();\r\n\r\n        $this-&gt;displayName = $this-&gt;l('Sample Admin form');\r\n        $this-&gt;description = $this-&gt;l('Sample module for admin form hooks');\r\n        $this-&gt;ps_versions_compliancy = array('min' =&gt; '1.6', 'max' =&gt; _PS_VERSION_);\r\n    }\r\n\r\n    \/**\r\n     * Installation du module\r\n     * @return bool\r\n     *\/\r\n    public function install()\r\n    {\r\n        if ( ! parent::install()\r\n            || !$this-&gt;registerHook('actionAdminCategoriesControllerSaveAfter')\r\n            || !$this-&gt;registerHook('actionAdminCategoriesFormModifier')\r\n        ) {\r\n            return false;\r\n        }\r\n\r\n        return true;\r\n    }\r\n\r\n    \/**\r\n     * D\u00e9sinstallation du module\r\n     * @return bool\r\n     *\/\r\n    public function uninstall()\r\n    {\r\n        return parent::uninstall();\r\n    }\r\n<\/pre>\n<h3 class=\"subtitle\"><span style=\"text-decoration: underline;\"><strong>Affichage des nouveaux champs<\/strong><\/span><\/h3>\n<p>Passons ensuite \u00e0 l&rsquo;affichage de nos nouveaux param\u00e8tres.<br \/>\nIl existe plusieurs possibilit\u00e9s :<\/p>\n<ul>\n<li>Ajouter au formulaire existant<\/li>\n<li>Cr\u00e9er un nouveau fieldset<\/li>\n<\/ul>\n<p>Les codes reprennent l&rsquo;utilisation d&rsquo;un helperForm Standard.<br \/>\nLes param\u00e8tres pass\u00e9s \u00e0 la fonction \u00e9tant les suivants :<\/p>\n<pre lang=\"php\" escaped=\"true\">Hook::exec('action'.$this-&gt;controller_name.'FormModifier', array(\r\n                'fields' =&gt; &amp;$this-&gt;fields_form,\r\n                'fields_value' =&gt; &amp;$fields_value,\r\n                'form_vars' =&gt; &amp;$this-&gt;tpl_form_vars,\r\n            ));\r\n<\/pre>\n<p>Attention au fait que les variables sont pass\u00e9es par r\u00e9f\u00e9rence ( signe &amp; ) ce qui signifie qu&rsquo;on peut les modifier directement dans le hook.<br \/>\nOn peut donc \u00e9galement modifier des \u00e9l\u00e9ments d\u00e9j\u00e0 d\u00e9finis par d\u00e9faut.<\/p>\n<pre lang=\"php\" escaped=\"true\">public function hookActionAdminCategoriesFormModifier($params)\r\n    {\r\n\r\n        \/\/Ajout d'un champ au fieldset par d\u00e9faut\r\n        $params['fields'][0]['form']['input'][] =  array(\r\n                        'type' =&gt; 'text',\r\n                        'label' =&gt; $this-&gt;l('Custom field 1'),\r\n                        'name' =&gt; $this-&gt;name.'_newfield1',\r\n                    );\r\n\r\n       \/\/Modification des propri\u00e9t\u00e9s d'un champ d\u00e9j\u00e0 existant\r\n        foreach ( $params['fields'][0]['form']['input'] as &amp;$field ){\r\n            \r\n           if ( $field['name'] == 'meta_description'){\r\n                $field['maxlength'] = '255';\r\n                $field['maxchar'] = '255';        \r\n                $field['hint'] = 'Modified by a module';\r\n            }\r\n        }\r\n\r\n        \/\/Cr\u00e9ation d'un nouveau fieldset\r\n        $params['fields'][$this-&gt;name] = array(\r\n            'form' =&gt; array(\r\n                'legend' =&gt; array(\r\n                    'title' =&gt; $this-&gt;l('Sample Category Fieldset'),\r\n                    'icon' =&gt; 'icon-tags',\r\n                ),\r\n                'description' =&gt; $this-&gt;l('New sample fieldset'),\r\n                'input' =&gt; array(\r\n                    array(\r\n                        'type' =&gt; 'text',\r\n                        'label' =&gt; $this-&gt;l('Custom field New Fieldset 1'),\r\n                        'name' =&gt; $this-&gt;name.'_newfieldset1',\r\n                    ),\r\n                    array(\r\n                        'type' =&gt; 'text',\r\n                        'label' =&gt; $this-&gt;l('Custom field New Fieldset 2'),\r\n                        'name' =&gt; $this-&gt;name.'_newfieldset2',\r\n                    ),\r\n                )\r\n            )\r\n        );\r\n\r\n        \/\/Pour remonter les valeurs des champs\r\n        $params['fields_value'][$this-&gt;name.'_newfield1'] = 'Custom value 1';\r\n        $params['fields_value'][$this-&gt;name.'_newfieldset1'] = 'Custom value fieldset 1';\r\n        $params['fields_value'][$this-&gt;name.'_newfieldset2'] = 'Custom value fieldset 2';\r\n    }\r\n<\/pre>\n<p>Le rendu est le suivant :<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1555\" src=\"https:\/\/www.h-hennes.fr\/blog\/wp-content\/uploads\/2017\/06\/new-fields.jpg\" alt=\"Nouveaux champs admin prestashop\" width=\"780\" height=\"564\" srcset=\"https:\/\/www.h-hennes.fr\/blog\/wp-content\/uploads\/2017\/06\/new-fields.jpg 780w, https:\/\/www.h-hennes.fr\/blog\/wp-content\/uploads\/2017\/06\/new-fields-300x217.jpg 300w, https:\/\/www.h-hennes.fr\/blog\/wp-content\/uploads\/2017\/06\/new-fields-768x555.jpg 768w\" sizes=\"auto, (max-width: 780px) 100vw, 780px\" \/><\/p>\n<h3 class=\"subtitle\"><span style=\"text-decoration: underline;\"><strong>Enregistrement des donn\u00e9es<\/strong><\/span><\/h3>\n<p>Il est temps \u00e0 pr\u00e9sent de passer \u00e0 l&rsquo;enregistrement des donn\u00e9es.<br \/>\nLes hooks <em>actionAdminCategoriesControllerSaveAfter<\/em> et <em>actionAdminCategoriesControllerSaveBefore<\/em> \u00e9tant redondants pour notre example je n&rsquo;utiliserais que l&rsquo;After<br \/>\nPour le traitement des donn\u00e9es nous n&rsquo;auront qu&rsquo;a r\u00e9cup\u00e9rer les variables posts envoy\u00e9es par le formulaire<\/p>\n<pre lang=\"php\" escaped=\"true\"> public function hookActionAdminCategoriesControllerSaveAfter($params)\r\n    {\r\n        \/\/R\u00e9cup\u00e9ration des variables custom soumises via le formulaire\r\n        $custom1 = Tools::getValue($this-&gt;name.'_newfield1');\r\n        $fiedlset1 = Tools::getValue($this-&gt;name.'_newfieldset1');\r\n        $fiedlset2 = Tools::getValue($this-&gt;name.'_newfieldset2');\r\n\r\n        \/\/Faites ensuite le traitement souhait\u00e9\r\n    }\r\n<\/pre>\n<p>Et voila nous avons rajout\u00e9 facilement des informations \u00e0 un formulaire admin sans faire de surcharge de classe \ud83d\ude09<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Depuis la version 1.6 de Prestashop, il est possible de rajouter rapidement et facilement le formulaire d&rsquo;\u00e9dition d&rsquo;un objet dans l&rsquo;administration via un module personnalis\u00e9. Et ceci sans surcharge particuli\u00e8re en utilisant tout simplement les hooks existants. Les objets \u00e9ditables via cette m\u00e9thodes sont ceux qui utilisent l\u2019ancien fonctionnement (non symfony ) de l&rsquo;administration. Vous [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"site-sidebar-layout":"default","site-content-layout":"","ast-site-content-layout":"default","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","ast-disable-related-posts":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"default","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"footnotes":""},"categories":[245],"tags":[494,495,361,104],"class_list":["post-1554","post","type-post","status-publish","format-standard","hentry","category-prestashop-2","tag-adminform","tag-helperform","tag-modules","tag-prestashop","prestashop-1-6","prestashop-1-7","prestashop-1-7-5","prestashop-1-7-7","prestashop-1-7-8","prestashop-8-0","prestashop-8-1"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.h-hennes.fr\/blog\/wp-json\/wp\/v2\/posts\/1554","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.h-hennes.fr\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.h-hennes.fr\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.h-hennes.fr\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.h-hennes.fr\/blog\/wp-json\/wp\/v2\/comments?post=1554"}],"version-history":[{"count":9,"href":"https:\/\/www.h-hennes.fr\/blog\/wp-json\/wp\/v2\/posts\/1554\/revisions"}],"predecessor-version":[{"id":2095,"href":"https:\/\/www.h-hennes.fr\/blog\/wp-json\/wp\/v2\/posts\/1554\/revisions\/2095"}],"wp:attachment":[{"href":"https:\/\/www.h-hennes.fr\/blog\/wp-json\/wp\/v2\/media?parent=1554"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.h-hennes.fr\/blog\/wp-json\/wp\/v2\/categories?post=1554"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.h-hennes.fr\/blog\/wp-json\/wp\/v2\/tags?post=1554"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}