{"id":2020,"date":"2019-08-05T13:55:40","date_gmt":"2019-08-05T11:55:40","guid":{"rendered":"https:\/\/www.h-hennes.fr\/blog\/?p=2020"},"modified":"2021-12-07T09:37:27","modified_gmt":"2021-12-07T07:37:27","slug":"prestashop-1-7-ajouter-des-champs-dans-un-formulaire-dadministration","status":"publish","type":"post","link":"https:\/\/www.h-hennes.fr\/blog\/2019\/08\/05\/prestashop-1-7-ajouter-des-champs-dans-un-formulaire-dadministration\/","title":{"rendered":"Prestashop 1.7 : Ajouter des champs dans un formulaire d\u2019administration"},"content":{"rendered":"\n<p>Cet article est une mise \u00e0 jour de l&rsquo;article suivant <a href=\"https:\/\/www.h-hennes.fr\/blog\/2017\/06\/21\/prestashop-ajouter-des-champs-dans-un-formulaire-dadministration\/\" target=\"_blank\" rel=\"noopener noreferrer\">https:\/\/www.h-hennes.fr\/blog\/2017\/06\/21\/prestashop-ajouter-des-champs-dans-un-formulaire-dadministration\/<\/a> qui s&rsquo;applique aux controllers qui utilisent symfony, c&rsquo;est le cas \u00e0 partir <strong>1.7.6<\/strong> de Prestashop<\/p>\n<p>Si vous avez des doutes si le controller sur lequel vous souhaitez ajouter des champs fonctionne avec ce m\u00e9thode, n&rsquo;h\u00e9sitez pas \u00e0 consulter l&rsquo;article suivant pour l&rsquo;identifier&nbsp; : <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>L&rsquo;objectif est d&rsquo;ajouter un nouveau champ dans un formulaire d&rsquo;administration de mani\u00e8re propre via un module.<\/p>\n<h3>Fonctionnement technique<\/h3>\n<p>Comme pour les versions pr\u00e9c\u00e9dentes des hooks dynamiques sont pr\u00e9sents dans le code prestashop pour vous permettre g\u00e9rer des informations suppl\u00e9mentaires via vos modules dans les formulaires.<\/p>\n<p>Pour ajouter des champs le hook est ex\u00e9cut\u00e9 dans la fonction buildForm du fichier src\/Core\/Form\/IdentifiableObject\/Builder\/FormBuilder.php<br><br>Les noms des hooks sont construits sous la forme suivante :<\/p>\n<p>action . Container::camelize(<strong>$formBuilder-&gt;getName()<\/strong>) . FormBuilderModifier<\/p>\n\n\n\n<pre escaped=\"true\" lang=\"php\">\/**\n     * @param string $formType\n     * @param array $data\n     * @param int|null $id\n     * @param array $options\n     *\n     * @return FormInterface\n     *\/\n    private function buildForm($formType, $data, $id = null, array $options = [])\n    {\n        $formBuilder = $this-&gt;formFactory-&gt;createBuilder($formType, $data, $options);\n        $this-&gt;hookDispatcher-&gt;dispatchWithParameters('action' . Container::camelize($formBuilder-&gt;getName()) . 'FormBuilderModifier', [\n            'form_builder' =&gt; $formBuilder,\n            'data' =&gt; &amp;$data,\n            'id' =&gt; $id,\n        ]);\n\n        return $formBuilder-&gt;getForm();\n    }\n<\/pre>\n\n\n\n<p>Pour la cr\u00e9ation et la mise \u00e0 jour des donn\u00e9es les hooks sont appell\u00e9s dans les fonctions handleFormUpdate ou handleFormCreate du fichier src\/Core\/Form\/IdentifiableObject\/Handler\/FormHandler.php<\/p>\n\n\n\n<p>Les noms des hooks sont construits sous la forme suivante :<\/p>\n\n\n\n<p>actionBeforeUpdate . Container::<em>camelize(<\/em><strong>$form-&gt;getName<\/strong><em><strong>()<\/strong>) <\/em>. FormHandler<br>actionAfterUpdate. Container::<em>camelize(<\/em><strong>$form-&gt;getName<\/strong><em><strong>()<\/strong>) <\/em>. FormHandler<\/p>\n\n\n\n<p>Voici le code ex\u00e9cut\u00e9 par exemple apr\u00e8s la mise \u00e0 jour d&rsquo;un formulaire<\/p>\n\n\n\n<pre escaped=\"true\" lang=\"php\">\/**\n     * @param FormInterface $form\n     * @param int $id\n     *\n     * @return FormHandlerResultInterface\n     *\/\n    private function handleFormUpdate(FormInterface $form, $id)\n    {\n        $data = $form-&gt;getData();\n\n        $this-&gt;hookDispatcher-&gt;dispatchWithParameters('actionBeforeUpdate' . Container::camelize($form-&gt;getName()) . 'FormHandler', [\n            'form_data' =&gt; &amp;$data,\n            'id' =&gt; $id,\n        ]);\n\n        $this-&gt;dataHandler-&gt;update($id, $data);\n\n        $this-&gt;hookDispatcher-&gt;dispatchWithParameters('actionAfterUpdate' . Container::camelize($form-&gt;getName()) . 'FormHandler', [\n            'id' =&gt; $id,\n            'form_data' =&gt; &amp;$data,\n        ]);\n\n        return FormHandlerResult::createWithId($id);\n    }\n\n<\/pre>\n\n\n\n<h3>Exemples de noms de hooks<\/h3>\n<p>Suite aux informations pr\u00e9c\u00e9dentes voici donc des exemples de hook disponibles pour l&rsquo;objet <strong>Category :<\/strong><\/p>\n<ul>\n<li>hookAction<strong>Category<\/strong>FormBuilderModifier<\/li>\n<li>hookActionBeforeCreate<strong>Category<\/strong>FormHandler<\/li>\n<li>hookActionAfterCreate<strong>Category<\/strong>FormHandler<\/li>\n<li>hookActionBeforeUpdate<strong>Category<\/strong>FormHandler<\/li>\n<li>hookActionAfterUpdate<strong>Category<\/strong>FormHandler<\/li>\n<\/ul>\n<h3>Objets disponibles.<\/h3>\n<p>A ce jour sur la version 1.7.6.0 ce fonctionnement est disponible pour les objets suivants :<\/p>\n<ul>\n<li>SqlRequest<\/li>\n<li>Customer<\/li>\n<li>Language<\/li>\n<li>Currency<\/li>\n<li>WebserviceKey<\/li>\n<li>Meta<\/li>\n<li>Category<\/li>\n<li>RootCategory<\/li>\n<li>Contact<\/li>\n<li>CmsPage<\/li>\n<li>CmsPageCategory<\/li>\n<li>Tax<\/li>\n<li>Manufacturer<\/li>\n<li>Employee<\/li>\n<li>Profile<\/li>\n<li>ManufacturerAddress<\/li>\n<\/ul>\n<h3>Exemple d&rsquo;impl\u00e9mentation<\/h3>\n<p>Voici comment proc\u00e9der pour rajouter des champs via un module qui s&rsquo;appellera<strong> hh_sampleadminform<\/strong><\/p>\n<p>Pour l&rsquo;exemple nous allons ajouter :<\/p>\n<ul>\n<li>un champ simple<\/li>\n<li>un champ langue<\/li>\n<\/ul>\n<p>Voici le code complet du module avec l&rsquo;impl\u00e9mentation des diff\u00e9rents hooks \u00e9voqu\u00e9 plus hauts.<br \/><br \/>J&rsquo;ai mis un maximum de commentaires directement dans le code pour expliquer les diff\u00e9rentes possibilit\u00e9s. <br \/>( Et laiss\u00e9 le nom des classes complets pour s&rsquo;y retrouver plus facilement )<br \/><br \/>Pour ceux qui utilisent d\u00e9j\u00e0 symfony la modification des formulaires sera relativement facile \u00e0 comprendre<\/p>\n<p>\u00a0<\/p>\n\n\n\n<pre escaped=\"true\" lang=\"php\"><!--?php\nclass Hh_SampleAdminForm extends Module\n{\n\n    \/**\n     * Hh_SampleAdminForm constructor\n     * Instanciation du module\n     *\/\n    public function __construct()\n    {\n        $this-&gt;name = 'hh_sampleadminform';\n        $this-&gt;tab = 'others';\n        $this-&gt;version = '0.2.0';\n        $this-&gt;author = 'hhennes';\n        $this-&gt;bootstrap = true;\n        parent::__construct();\n\n        $this-&gt;displayName = $this-&gt;l('Sample Admin form');\n        $this-&gt;description = $this-&gt;l('Sample module for admin form hooks for ps 1.7.6 and &gt; ');\n    }\n\n    \/**\n     * Installation du module\n     * @return bool\n     *\/\n    public function install()\n    {\n        if (!parent::install()\n            \/\/Installation des hooks\n            || !$this-&gt;registerHook([\n                'actionCategoryFormBuilderModifier',\n                'actionAfterCreateCategoryFormHandler',\n                'actionAfterUpdateCategoryFormHandler',\n            ])\n        ) {\n            return false;\n        }\n\n        return true;\n    }\n\n    \/**\n     * Modification du formulaire de la cat\u00e9gorie\n     * @param array $params\n     *\/\n    public function hookActionCategoryFormBuilderModifier(array $params)\n    {\n        \/\/R\u00e9cup\u00e9ration du form builder\n        \/** @var \\Symfony\\Component\\Form\\FormBuilder $formBuilder *\/\n        $formBuilder = $params['form_builder'];\n\n\n        \/\/Ajout de notre champ sp\u00e9cifique\n        $formBuilder-&gt;add($this-&gt;name . '_newfield1',\n            \/\/Cf g\u00e9n\u00e9riques symonfy https:\/\/symfony.com\/doc\/current\/reference\/forms\/types.html\n            \/\/ et sp\u00e9cificiques prestashop https:\/\/devdocs.prestashop.com\/1.7\/development\/components\/form\/types-reference\/\n            \\Symfony\\Component\\Form\\Extension\\Core\\Type\\TextType::class,\n            [\n                'label' =&gt; $this-&gt;l('Custom field 1'), \/\/Label du champ\n                'required' =&gt; false, \/\/Requis ou non\n                'constraints' =&gt; [ \/\/Contraintes du champs\n                    \/\/cf. g\u00e9n\u00e9riques symfony : https:\/\/symfony.com\/doc\/current\/reference\/constraints.html\n                    \/\/ Ou vous pouvez \u00e9crire la votre cf. https:\/\/symfony.com\/doc\/current\/validation\/custom_constraint.html\n                    new \\Symfony\\Component\\Validator\\Constraints\\Length([\n                        'max' =&gt; 20,\n                        'maxMessage' =&gt; $this-&gt;l('Max caracters allowed : 20'),\n                    ]),\n                ],\n                \/\/La valeur peut \u00eatre set\u00e9e ici\n                'data' =&gt; 'test valeur', \/\/Valeur du champ\n                \/\/ Texte d'aide\n                'help' =&gt; $this-&gt;l('help text')\n            ]\n        );\n        \n        \/\/Ou surcharg\u00e9e ici\n        $params['data'][$this-&gt;name . '_newfield1'] = 'Custom value 1';\n\n      \/\/Ajout d'un champ langue\n        $formBuilder-&gt;add($this-&gt;name . '_newfield_lang',\n            \/\/ cf. https:\/\/devdocs.prestashop.com\/1.7\/development\/components\/form\/types-reference\/\n            \\PrestaShopBundle\\Form\\Admin\\Type\\TranslatableType::class,\n            [\n                'label' =&gt; $this-&gt;l('Custom field Lang'), \/\/Label du champ\n                'required' =&gt; false, \/\/Requis ou non\n                'type' =&gt; \\Symfony\\Component\\Form\\Extension\\Core\\Type\\TextType::class \/\/ OU TextAreaType::class\n            ]\n        );\n        \/\/D\u00e9finition des donn\u00e9es du champ langue\n        $languages = Language::getLanguages(true);\n        foreach ( $languages as $lang){\n            $params['data'][$this-&gt;name . '_newfield_lang'][$lang['id_lang']] = 'Custom value for lang '.$lang['iso_code'];\n        }\n\n        \/\/On peut \u00e9galement changer facilement la donn\u00e9e de n'importe quel autre champ du formulaire\n        $params['data']['active'] = false;\n\n        \/\/Il faut bien penser \u00e0 mettre cette ligne pour mettre \u00e0 jour les donn\u00e9es au formulaire\n        $formBuilder-&gt;setData($params['data']);\n    }\n\n    \/**\n     * Action effectu\u00e9e apr\u00e8s la cr\u00e9ation d'une cat\u00e9gorie\n     * @param array $params\n     *\/\n    public function hookActionAfterCreateCategoryFormHandler(array $params)\n    {\n        $this-&gt;updateData($params['id'],$params['form_data']);\n    }\n\n    \/**\n     * Action effectu\u00e9e apr\u00e8s la mise \u00e0 jour d'une cat\u00e9gorie\n     * @param array $params\n     *\/\n    public function hookActionAfterUpdateCategoryFormHandler(array $params)\n    {\n        $this-&gt;updateData($params['id'],$params['form_data']);\n    }\n\n    \/**\n     * Fonction qui va effectuer la mise \u00e0 jour\n     * @param array $data\n     *\/\n    protected function updateData(int $id_category,array $data)\n    {\n        \/\/R\u00e9alisation du traitement de mise \u00e0 jour\n    }\n\n\n}\n<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\"><\/pre>\n\n\n\n<p>Les nouveaux champs sont ensuites bien pr\u00e9sents dans la fiche d'\u00e9dition de la cat\u00e9gorie \ud83d\ude42<\/p>\n\n\n\n<p><\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"805\" height=\"405\" src=\"https:\/\/www.h-hennes.fr\/blog\/wp-content\/uploads\/2019\/08\/blog-category-fields.png\" alt=\"Champs cat\u00e9gorie\" class=\"wp-image-2034\" srcset=\"https:\/\/www.h-hennes.fr\/blog\/wp-content\/uploads\/2019\/08\/blog-category-fields.png 805w, https:\/\/www.h-hennes.fr\/blog\/wp-content\/uploads\/2019\/08\/blog-category-fields-300x151.png 300w, https:\/\/www.h-hennes.fr\/blog\/wp-content\/uploads\/2019\/08\/blog-category-fields-768x386.png 768w\" sizes=\"auto, (max-width: 805px) 100vw, 805px\" \/><\/figure>\n\n\n\n<p>Il est \u00e0 pr\u00e9sent facile de r\u00e9aliser les traitements souhait\u00e9s sur les diff\u00e9rents objets , n'h\u00e9sitez pas \u00e0 partager vos astuces ou \u00e0 remonter les probl\u00e8mes rencontr\u00e9s sur cette partie<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Cet article est une mise \u00e0 jour de l&rsquo;article suivant https:\/\/www.h-hennes.fr\/blog\/2017\/06\/21\/prestashop-ajouter-des-champs-dans-un-formulaire-dadministration\/ qui s&rsquo;applique aux controllers qui utilisent symfony, c&rsquo;est le cas \u00e0 partir 1.7.6 de Prestashop Si vous avez des doutes si le controller sur lequel vous souhaitez ajouter des champs fonctionne avec ce m\u00e9thode, n&rsquo;h\u00e9sitez pas \u00e0 consulter l&rsquo;article suivant pour l&rsquo;identifier&nbsp; : https:\/\/www.h-hennes.fr\/blog\/2019\/07\/25\/prestashop-1-7-identifier-si-un-controller-admin-a-ete-migre-vers-symfony\/ [&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":[348,547,104,483],"class_list":["post-2020","post","type-post","status-publish","format-standard","hentry","category-prestashop-2","tag-admin","tag-form","tag-prestashop","tag-prestashop-1-7","prestashop-1-6","prestashop-1-7-5","prestashop-1-7-6","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\/2020","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=2020"}],"version-history":[{"count":15,"href":"https:\/\/www.h-hennes.fr\/blog\/wp-json\/wp\/v2\/posts\/2020\/revisions"}],"predecessor-version":[{"id":2360,"href":"https:\/\/www.h-hennes.fr\/blog\/wp-json\/wp\/v2\/posts\/2020\/revisions\/2360"}],"wp:attachment":[{"href":"https:\/\/www.h-hennes.fr\/blog\/wp-json\/wp\/v2\/media?parent=2020"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.h-hennes.fr\/blog\/wp-json\/wp\/v2\/categories?post=2020"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.h-hennes.fr\/blog\/wp-json\/wp\/v2\/tags?post=2020"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}