Suite à mon (ancien ) article (https://www.h-hennes.fr/blog/2017/10/19/prestashop-1-7-ajouter-des-champs-produit/ ) sur l’ajout de champs custom dans le formulaire d’administration d’un produit, j’ai eut pas mal de questions sur comment ajouter un champ de type file.

Il faut reconnaître que la fonctionnalité n’est pas évidente car le formulaire est soumis en ajax et le gère pas l’upload de fichiers.

Le simple fait d’ajouter un champ de type file dans le formulaire n’est donc pas suffisant pour que cela fonctionne.

Cet article présente une approche qui fonctionne, mais je ne peux pas garantir que c’est la meilleure approche.

Pour son fonctionnement je me suis inspiré de la gestion de l’upload qui est faite pour la gestion des images standard du produit via la librairie Js Dropzone

Pour le code j’ai donc repris le code de l’ancien article en y ajoutant la logique d’un champ image.

Voici visuellement comment se présente le champ d’upload

L’ensemble de la logique d’upload et de sauvegarde de la valeur du produit va être gérée directement dans le module

Voici le rendu dans le cas ou une image existe déjà.
Il est possible de la supprimer en cliquant sur le lien correspondant

Voici le code pour l’affichage et la gestion du champ dans le fichier tpl
Les commentaires devrait vous éclairer sur le fonctionnement, je l’ai pensé de manière à pouvoir ajouter facilement plusieurs champs

{* Affichage du champ Image *}
            <div class="col-lg-12 col-xl-12">
                <label class="form-control-label">{l s='my custom field file' mod='hhproduct'}</label>

                <div id="custom_field_file_thumbnail">
                {* Si une image existe déjà sur le produit *}
                    {if isset($custom_field_file) && $custom_field_file !=""}
                        <div style="border: 1px dashed #000; padding:10px; max-width: 500px; margin-bottom: 30px; margin-top: 30px" >
                            <label class="form-control-label">{l s='my current image' mod='hhproduct'}</label><br />
                        <img src="{$file_dir}{$custom_field_file}" style="max-width: 450px" /><br />
                        <a href="#" class="custom_field_file_delete">{l s='Delete this image' mod='hhproduct'}</a>
                        </div>
                {/if}
                </div>
                <input type="file" class="dropzone" name="custom_field_file_uploader" id="custom_field_file_uploader" />
            </div>
                <script>
                    $(function() {
                        //Gestion de l'upload via la librairie DropZone
                        Dropzone.autoDiscover = false;
                        var customFieldImageDropzone = $('#custom_field_file_uploader').dropzone({
                            url: '{$moduleLink}&id_product={$id_product}&uploadProductImage=1&field_name=custom_field_file',
                            paramName: "file", //Nom du champs à envoyer
                            previewTemplate : document.querySelector('#custom_field_file_dropzone_template').innerHTML,
                            thumbnailWidth : 450,
                            success : function(file){
                                alert('{l s='File uploaded with success' mod='hhproduct'}');
                                //Affichage de la nouvelle image dans l'emplacement
                                $('#custom_field_file_thumbnail').html('').html(file.previewElement);
                            }
                        });

                        //Gestion de la suppression
                        $('#custom_field_file_thumbnail').on('click','.custom_field_file_delete',function(){
                            $.ajax({
                               method: 'post',
                               url : '{$moduleLink}&id_product={$id_product}&deleteProductImage=1&field_name=custom_field_file',
                               success : function(msg){
                                   console.log(msg);
                                   alert('{l s='File delete with success' mod='hhproduct'}');
                                   $('#custom_field_file_thumbnail').html('');
                               }
                            });
                            return false;
                        });
                    });
                </script>

            {* template d'affichage dropzone *}
            <div id="custom_field_file_dropzone_template" style="display:none">
                <div style="border: 1px dashed #000; padding:10px; max-width: 500px; margin-bottom: 30px; margin-top: 30px">
                    <div class="dz-details">
                        <label class="form-control-label">{l s='my new image' mod='hhproduct'}</label><br />
                        <img data-dz-thumbnail style="max-width: 450px" /><br />
                        <a href="#" class="custom_field_file_delete">{l s='Delete this image' mod='hhproduct'}</a>
                    </div>
                </div>
            </div>

Et voici le code php de gestion de cet upload
De mon côté l’objet product a été surchargé pour ajouter ce champ mais libre à vous de faire un traitement différent

/**
     * Configuration admin du module
     * @return string
     * @throws PrestaShopDatabaseException
     * @throws PrestaShopException
     */
    public function getContent()
    {
        //Gestion de l'envoi des fichiers
        if (Tools::getValue('uploadProductImage')) {
            $id_product = (int)Tools::getValue('id_product');
            $field_name = Tools::getValue('field_name');
            if ($this->_updateProductImageField($id_product, $field_name)) {
                return $this->l('Image uploaded with success');
            }
        } elseif (Tools::getValue('deleteProductImage')) {
            $id_product = (int)Tools::getValue('id_product');
            $field_name = Tools::getValue('field_name');
            if ($this->_deleteProductImageField($id_product, $field_name)) {
                return $this->l('Image deleted with success');
            }
        } else {
            return 'No configuration needed for this module';
        }
 
    }
 
    /**
     * Upload de l'image d'un produit
     * @param $id_product
     * @param $field_name
     * @return bool
     * @throws PrestaShopDatabaseException
     * @throws PrestaShopException
     */
    protected function _updateProductImageField($id_product, $field_name)
    {
        //Envoi de l'image
        //@TOdo gérer le cas ou l'image existe déjà
        $savePath = dirname(__FILE__) . '/views/img/p';
        $uploader = new Uploader('file');
        $file = $uploader->setSavePath($savePath)
            ->setAcceptTypes(['jpg', 'png', 'git', 'jpeg'])
            ->process();
 
        $fileName = ltrim(str_replace($savePath, '', $file[0]['save_path']), '/');
        try {
            //Sauvegarde la valeur de l'image pour le produit
            $product = new Product($id_product);
            $product->$field_name = $fileName;
            $product->save();
        } catch (PrestaShopException $e) {
            echo $e->getMessage();
            return false;
        }
 
        return true;
    }
 
 
    /**
     * Suppression de l'image d'un produit
     * @param $id_product
     * @param $field_name
     * @return bool
     */
    protected function _deleteProductImageField($id_product, $field_name)
    {
        try {
            //Sauvegarde d'une valeur vide pour le produit
            $product = new Product($id_product);
 
 
            //Si le produit a une image et qu'elle existe on la supprime
            if ($product->$field_name != "") {
                $imagePath = dirname(__FILE__) . '/views/img/p/' . $product->$field_name;
                if (is_file($imagePath)) {
                    unlink($imagePath);
                }
            }
            $product->$field_name = '';
            $product->save();
        } catch (PrestaShopException $e) {
            echo $e->getMessage();
            return false;
        }
    }

Vous pouvez télécharger ci-dessous une version du module qui implémente ce champ (je l’ai testé uniquement sur Ps 1.7.6 )