New Slang - Création de Site Internet Artisanale

Guide complet : créer un module dans Prestashop 1.7

thierry
Guide complet : créer un module dans Prestashop 1.7

Que ce soit dans le but de le vendre sur la marketplace, afin de réaliser un développement personnalisé dans votre boutique ou simplement pour comprendre les modules dans Prestashop, ce guide complet vous aidera à créer votre premier module dans la version 1.7 de Prestashop.

Petit disclaimer avant de commencer, afin d’être totalement transparent, une grande partie de cet article se basera sur la solide documentation fournie par Prestashop sur la création de module.

Cependant cette documentation a trois problèmes :

  1. Elle n’est disponible qu’en anglais
  2. Alors que certains points sont clairement expliqués, d’autres sont un peu survolés, j’essaierai de remplir les blancs
  3. Il s’agit d’une mise à jour de la documentation pour la version 1.6, il reste donc quelques parties qui parlent ou semble s’adresser à d’anciennes versions. Ici on ne parlera que de la version 1.7

Comme cet article sera plutôt conséquent, voici les points qui seront traités :

  1. Introduction
  2. Structure des dossiers et fichiers
  3. Créer son premier module
  4. Créer une vue de configuration
  5. Afficher du contenu sur votre boutique
  6. Traduire le module
  7. Conclusion

Evidemment, si vous vous attaquez à la création de module, j’imagine que vous n’êtes pas totalement débutant en PHP, que vous comprenez le fonctionnement des modèles de Prestashop et de Smarty et que vous connaissez la programmation orientée objet et le modèle MVC.

Accélérez le processus

Téléchargez le module présenté dans cet article

Avec le module commenté créé dans cet article, vous pourrez mieux comprendre le code et développer votre propre module 2x plus vite.

Téléchargez le module présenté dans cet article

Introduction

Fonctionnement

Un module Prestashop se constitue d’un fichier PHP principal avec autant de fichiers PHP que vous jugez nécessaires, des templates (fichiers .tpl) et des ressources (CSS, JavaScript, images, polices).

Un module peut s’afficher uniquement pour le marchand dans le back office ou pour le visiteur sur la boutique, ou les deux.

Le module peut ensuite interagir avec ce que Prestashop appel les hooks (crochet) qui permet lors de l’appel d’un hook par Prestashop d’exécuter certaines parties du code de votre module.

Par exemple lorsque le hook displayHome qui affiche la page d’accueil est appelé, il est possible de lier son module à ce hook et d’afficher des informations ou de réaliser une opération à ce moment-là.

Un module peut :

  • Afficher du contenu HTML dynamique en fonction de vos besoins
  • Exécuter divers tâches (import / export, modification en masse, etc.)
  • Être configuré selon les besoins de la tâche à réaliser. Plus la configuration est complète, plus les possibilités sont grandes pour l’utilisateur
  • Ajouter des fonctionnalités à Prestashop sans toucher aux fichiers de base du logiciel, ce qui permet d’éviter les problèmes lors des mises à jour de l’application.

Si vous venez de la version 1.6 de Prestashop et que vous aimeriez connaître les changements, vous pouvez lire cet article en anglais sur le sujet.

Je n’entrerai pas dans les détails mais sachez que dans l’ensemble, bien que les changements de fond de Prestashop 1.7 sont importants, leur impact sur les modules est minime.

Emplacement

Tous les modules se trouvent dans le dossier /modules à la racine de votre installation de Prestashop.

Vous verrez en vous rendant dans ce dossier qu’il existe déjà pas mal de modules, une grande partie d’entre eux sont des modules standards installés par défaut avec Prestashop.

Liste des modules dans le dossier /modules de Prestashop
Liste des modules installés par défaut dans le dossier /modules de Prestashop

Par exemple le moyen de paiement Transfère bancaire est en fait un module appelé ps_wirepayment. Les développeurs ont pris le parti de réaliser des modules séparés pour certaines fonctionnalités afin de les extraire du cœur de l’application et de faciliter leur gestion de manière indépendante.

Note sur le cache et la documentation officielle

Je vous parlais plus haut des inconsistances de la documentation officielle sur certains sujets où, malgré la mention Prestashop 1.7, on parle encore des versions antérieures.

Dans la partie About the cache la documentation parle du dossier /cache situé à la racine de votre boutique. Dans ce dossier se trouve désormais un fichier deprecated.txt qui explique que la gestion du cache dans Prestashop 1.7 se fait à présent dans var/cache/[ENV].

*****************************
**   D E P R E C A T E D   **
*****************************

This folder has been deprecated since PrestaShop 1.7.
Make sure your code uses `var/cache/ENV` folder, please use the
constant `_PS_CACHE_DIR_` which is available everywhere.

ENV étant en fait l’environnement de travail, à savoir dev ou prod. C’est dans ce dossier que vous trouverez le fichier class_index.php où seront enregistré les liens entre les classes et les fichiers de déclaration.

En cas de problème de mise à jour de vos classes lors du développement, ce fichier peut être supprimé sans autre.

Même chose lorsque vous rencontrez des problèmes de mise à jour des templates, vous pouvez tenter de supprimer le contenu du dossier suivant :

\var\cache\dev\smarty\compile

Ce chapitre a été écrit pour l’exemple, mais je n’entrerai pas dans le détail sur toutes les informations qui ne sont pas à jour dans la documentation, je ne peux que vous conseiller de vous baser sur mon article pour être sûr. 😉

Générateur de module

Pour fonctionner avec Prestashop un module doit suivre certaines règles. Si vous désirez démarrer rapidement, vous pouvez utiliser le générateur de module mis à disposition par Prestashop. Il vous faudra un compte sur la marketplace de Prestashop pour l’utiliser.

Générateur de module mis à disposition par Prestashop
Le générateur de module mis à disposition par Prestashop pour créer un module rapidement

Il vous permettra entre autres de définir toutes les informations de base de votre module (nom, description, etc.), de définir son emplacement dans le back office et d’inscrire les hooks auxquels s’enregistrer.

Je vous conseille de l’essayer pour voir le résultat en fonction de votre choix et pour vous aider à comprendre la structure.

Mais pour débuter, il est important de bien comprendre comment fonctionne la création d’un module en le faisant de A à Z à la main.

Structure des dossiers et fichiers

Exemple de structure d’un module

Dans Prestashop 1.7 voici un exemple d’architecture pour un dossier de module :

.
├── classes
├── controllers
├── override
├── upgrade
├── vendor
└── views
    ├── css
    ├── img
    ├── js
    └── templates
├── config.xml
├── logo.png
└── nom_du_module.php
  • classes : Vous permet d’ajouter les classes spécifiques à votre module qui ne sont pas des controllers ou des overrides de classes existantes
  • controllers : Vous permet de déclarer les controllers qui seront utilisés par votre module. Le controller permet de déclarer une action qui affichera une vue à l’utilisateur, il est d’ailleurs toujours couplé à un template. Vous pouvez créer vos propres controller ou hériter de controllers existants
  • override : Permet de réécrire, en respectant la même structure de dossier, les méthodes, propriétés et fonctions de classes spécifiques à Prestashop. Généralement il est déconseillé de faire de l’override dans Prestashop, cette pratique pouvant créer des problèmes à lors de mises à jour. Il est préférable d’hériter d’une classe et d’y ajouter les méthodes nécessaires
  • upgrade : Permet de définir le comportement lors d’une mise à jour (modification des champs, ajout de hooks, etc.)
  • vendor / lib / libraries / sdk / etc. : Ces dossiers sont réservés pour les librairies externes que vous utiliserez pour vos modules
  • views : Contient à la racine les dossiers des différentes ressources du module (CSS, JavaScript, images, polices, etc.) et le dossier templates dans lequel se trouveront toutes vos vues. Pour remplacer une vue existante par votre propre vue, vous pouvez utiliser le même chemin et nom de fichier tpl que celui présent dans le dossier /views de la racine de votre installation de Prestashop
  • config.xml : Fichier créé à l’installation du module, garde toutes les informations du module en cache dans pour rendre l’affichage de la liste des modules plus rapide dans le back office.
  • logo.png : Logo affiché sur la liste des modules
  • nom_du_module.php : Fichier principal du module s’occupant de déclarer la classe principale du même nom, son initialisation et la gestion de l’installation / désinstallation. Ce fichier peut aussi contenir beaucoup d’autres éléments que nous verrons plus tard.

Le dossier modules dans /themes

Lorsque vous installez un module dans Prestashop, par défaut il est installé dans /modules uniquement.

Si vous souhaitez apporter des modifications à un module spécifiquement pour votre thème, vous pouvez copier certains de ces fichiers dans /themes/modules/[nom du module].

Par exemple, imaginons un module avec une vue spéciale se trouvant dans le dossier suivant :

/modules/modulexy/views/templates/hook/vue_speciale.tpl

Si vous souhaitez modifier le comportement de ce template, vous n’allez pas modifier directement ce fichier tpl. Car cela voudrait dire que vous modifiez le module directement, en cas de mise à jour, vos modifications seront perdues.

Au lieu de ça, créez une architecture avec un chemin identique dans le dossier /themes pointant vers un fichier du même nom :

/themes/votretheme/modules/modulexy/views/templates/hook/vue_speciale.tpl

Et copiez le contenu du vue_speciale.tpl original dans ce fichier, puis apportez-y les modifications désirées. De cette manière, celles-ci seront spécifiques à votre thème et n’altéreront pas la source du module original !

Vous verrez alors apparaître les modules spécifiques au thème actif dans la liste des modules, sous Modules du thème :

Modules du thème

Créer son premier module

L’équipe de Prestashop a défini une série de règles de codage lors du développement dans l’application ou la création de module. Avant de débuter je vous conseil de les consulter, bien qu’elles n’existent qu’en anglais.

Dossier

Pour créer votre premier module, rendez-vous dans le dossier /modules et là, créez un dossier avec le nom de votre module. Il devrait avoir le même que votre module, uniquement des caractères alpha numériques et aucun espace. Par exemple je vais créer un module appelé :

Mon module

Dans ce cas le dossier pourrait être simplement :

/modules/monmodule

Il est cependant conseillé de préfixer son module avec le nom de son entreprise par exemple, pour éviter les confusions. Dans ce cas il pourrait devenir :

/modules/ns_monmodule

Ensuite le dossier doit contenir le fichier principal du module pour être valide. Ce fichier doit être nommé comme le dossier, c’est à dire :

ns_monmodule.php

Ça y est, vous avez créé votre premier module ! Seul ce dossier et ce fichier sont obligatoires pour disposer d’un module valide. Mais on ne va pas s’arrêter là bien sûr.

Fichier principal du module

Dans ce fichier ns_monmodule.php nous allons gérer le fonctionnement de base du module :

  • Son constructeur
  • Méthode d’installation / désinstallation
  • Inscription et fonctionnement des hooks
  • Gestion des vues dans le back office

Test initial

Pour commencer, la première étape au début de chaque module est de vérifier que la constante PS_VERSION est définie :

<?php

    if (!defined('_PS_VERSION_')) {
        exit;
    }

Cette ligne de code permet de vérifier qu’une constante qui est toujours définie dans Prestashop existe et est accessible. Cela indique que l’environnement est bien chargé.

Ce code permet d’éviter à un individu malveillant d’accéder et d’exécuter ce fichier seul.

Classe principale

Ensuite on définit la classe du module, le fichier principal doit définir la classe principale et celle-ci doit être nommée de la même manière que le fichier de module et son dossier, en version Camel Case.

C’est à dire en passant les premières lettres de chaque mot en majuscule. Donc le nom de module ns_monmodule devient lorsqu’on instancie la classe :

if (!defined('_PS_VERSION_')) {
    exit;
}

class Ns_MonModule extends Module
{
}

Notez que la classe extends la classe Module, c’est à dire qu’elle hérite de celle-ci. La classe Module est la classe de base pour les modules, il est aussi possible d’hériter d’autres classes de modules comme PaymentModule, ModuleGridEngine, ModuleGrap, etc. afin de profiter des fonctionnalités qui leur sont propres.

À ce stade, si vous vous rendez dans votre back office sous Personnaliser > Catalogue de modules et que vous tapez le nom de votre module dans la recherche, ici ns_monmodule :

Affichage de votre module personnalisé dans la liste des modules de Prestashop

Celui-ci devrait déjà être visible, bien sûr, sans autre informations pour le moment.

Constructeur

Chaque classe dispose d’un constructeur. Qu’elle hérite de celui de sa classe parente ou qu’il soit clairement défini.

Cette méthode est appelée lorsqu’une classe de votre module est instancié avec le mot clé new. Lorsque le module est chargée par Prestashop, celui-ci créé une nouvelle instance de votre module.

<?php

	if (!defined('_PS_VERSION_')) {
	    exit;
	}

	class Ns_MonModule extends Module
	{
	    public function __construct()
	    {
	        $this->name = 'ns_monmodule';
	        $this->tab = 'front_office_features';
	        $this->version = '1.0.0';
	        $this->author = 'New Slang';
	        $this->need_instance = 0;
	        $this->ps_versions_compliancy = [
	            'min' => '1.7',
	            'max' => _PS_VERSION_
	        ];
        	$this->bootstrap = true;

	        parent::__construct();

	        $this->displayName = $this->l('Module New Slang');
	        $this->description = $this->l('Mon premier module super cool');

	        $this->confirmUninstall = $this->l('Êtes-vous sûr de vouloir désinstaller ce module ?');

	        if (!Configuration::get('NS_MONMODULE_PAGENAME')) {
	            $this->warning = $this->l('Aucun nom fourni');
	        }
	    }
	}

Voici en détail ce que fait la méthode __construct :

  • $this->name = 'ns_monmodule'; permet de définir le nom du module. Il s’agit d’un identifiant interne qui doit porter le même nom que le dossier du module
  • $this->tab défini à quel onglet appartient ce module dans la liste des modules, voir ici pour la liste complète des onglets existants et à quoi ils correspondent dans cette version 1.7
  • $this->version défini la version du module
  • $this->author spécifie l’auteur du module. Votre nom ou celui de votre entreprise
  • $this->need_instance indique s’il faut créer une instance du module au chargement de la liste des modules installés dans Prestashop. Une instance peut être utile si vous devez afficher un avertissement sur la page des modules par exemple.
  • $this->ps_versions_compliancy défini avec quelle version de Prestashop le module est compatible. Ici on indique de la version 1.7 à la version actuelle de Prestashop
  • $this->bootstrap = true indique qu’on utilisera le système de rendu de Bootstrap pour ce module. Ce qui fera qu’au lieu d’avoir ce genre d’affichage dans le back office :
Affichage d'un module dans le back office sans bootstrap

Ça ressemblera plutôt à ça :

Affichage d'un module dans le back office avec bootstrap
  • parent::__construct() appel le constructeur de la classe parente, à savoir Module pour exécuter la méthode constructeur de base
  • $this->displayName défini le nom affiché dans la liste des modules
  • $this->description défini la description affichée dans la liste des modules
  • $this->confirmUninstall : Message de confirmation optionnel à afficher lors de la désinstallation
  • if (!Configuration::get('NS_MONMODULE_PAGENAME'))... permet de vérifier si la valeur NS_MONMODULE_PAGENAME est configurée ou non. Nous y reviendrons

Si maintenant on recherche le nom de mon module désormais, à savoir Module New Slang voici le résultat :

Affichage de votre module personnalisé avec son nom et sa description dans la liste des modules de Prestashop
C’est déjà plus clair… ou pas !

Et vous pourrez l’installer pour le fun, mais pour le moment, il ne fera rien.

Installation / désinstallation

Par défaut, les méthodes install et uninstall appellent celles de la classe parente, ici donc si ces méthodes ne sont pas spécifiées Prestashop appel celle de la classe Module.

Voici comment appeler ces méthodes le plus simplement possible :

public function install()
{
    return parent::install();
}

public function uninstall()
{
    return parent::uninstall();
}

Sachez que ne pas définir ces méthodes ou les appeler de cette manière aura exactement le même comportement.

Prestashop les appellent simplement en renvoyant le message (true si c’est OK et false en cas d’erreur) de confirmation d’installation et désinstallation.

Nous allons compléter ces méthodes pour ajouter la valeur de configuration NS_MONMODULE_PAGENAME mentionnée plus haut et inscrire le module à des hooks spécifiques à l’installation.

public function install()
{
    if (Shop::isFeatureActive()) {
        Shop::setContext(Shop::CONTEXT_ALL);
    }

    if (!parent::install() ||
        !$this->registerHook('leftColumn') ||
        !$this->registerHook('header') ||
        !Configuration::updateValue('NS_MONMODULE_PAGENAME', 'Mentions légales')
    ) {
        return false;
    }

    return true;
}
  • if (Shop::isFeatureActive()) ... vérifie si le mode multi-boutique de Prestashop 1.7 est activé. Si c’est le cas définit le contexte pour appliquer l’installation à toutes les boutiques
  • Ensuite un test vérifie que l’installation s’est bien déroulée en récupérant le résultat de la méthode !parent::install(), en s’inscrivant au hook leftColumn, au hook header et en enregistrant la valeur NS_MONMODULE_PAGENAME. Chacune de ces actions va s’exécuter et si l’une d’elle retourne false l’installation a échouée. Dans le cas contraire l’installation a réussi

Une fois l’installation réalisée vous aurez donc inscrit votre module aux hooks leftColumn et header et créé un nouveau réglage dans la base de données appelé NS_MONMODULE_PAGENAME.

Lors de la désinstallation, pas besoin de désinscrire le module des différents hooks. Cependant il est important, pour faire une désinstallation propre, de supprimer le réglage NS_MONMODULE_PAGENAME créé dans la base.

Voici comment procéder :

public function uninstall()
{
    if (!parent::uninstall() ||
        !Configuration::deleteByName('NS_MONMODULE_PAGENAME')
    ) {
        return false;
    }

    return true;
}

Le code est assez simple, il vérifie que la méthode uninstall retourne true et idem pour la méthode de suppression du réglage appelé Configuration::deleteByName().

L’objet Configuration

Pour gérer la configuration de notre module, dans notre cas un simple champ appelé NS_MONMODULE_PAGENAME, nous avons utilisé l’objet Configuration de 3 manières :

  • Configuration::get(key) : Récupère la valeur donnée en paramètre
  • Configuration::update(key, value) : Modifie le réglage avec la clé donnée en paramètre, à la valeur spécifiée. Si le réglage n’existe pas il est automatiquement créé
  • Configuration::deleteByName(key) : Supprime le réglage de la base de données

En fait l’objet Configuration représente un accès facilité à la table ps_configuration dans laquelle la plupart des modules inscrivent leurs réglages. Elle permet d’accéder à la table et de la modifier sans écrire de requêtes SQL.

Notez que lorsque vous enregistrez un réglage, la valeur de celui-ci peut-être une chaîne de caractère, un nombre entier, un tableau, etc.

Tant que la récupération de la variable se fait correctement, basée sur son type, ça fonctionnera. Voici un exemple pour enregistrer un tableau PHP :

// Enregistre un tableau dans la table Configuration
Configuration::updateValue('NS_MONMODULE_SETTINGS', serialize(array(true, true, false)));

// Le récupère
$configuration_array = unserialize(Configuration::get('NS_MONMODULE_SETTINGS'));

Autre point important la table ps_configuration ne se limite pas à vos propres réglages, vous pouvez accéder à tous les réglages qu’elle contient de la même manière.

Par exemple si vous tapez Configuration::get('PS_LANG_DEFAULT') vous pourrez récupérer l’id de la langue par défaut de la boutique.

Pour connaître les champs disponibles, allez consulter le contenu de la table ps_configuration de votre boutique.

Ajouter une icône

Parce que jusqu’à présent, l’affichage de votre module dans la liste des modules est un peu triste et difficile à identifier au premier coup d’œil, vous pouvez y ajouter une icône pour le représenter.

Pour s’afficher sur votre module, le logo doit respecter ces points :

  • Il doit être à la racine du dossier de votre module
  • Il doit être au format PNG
  • Il doit s’appeler logo.png
  • Il doit être carré et d’une dimension minimum de 32x32px

Une fois le logo ajouté, voici un exemple de ce à quoi il va ressembler dans la liste des modules :

Affichage de votre module personnalisé avec son nom, sa description et son icône dans la liste des modules de Prestashop

Sécuriser l’accès votre module

Dernier point pour finaliser la création de ce premier module, sécuriser l’accès à son contenu. Dans la situation actuelle, si un utilisateur tape :

https://votresite.com/modules/votremodule

Il pourra potentiellement accéder à son contenu. Même si l’accès à votre module risque de ne retourner que quelques erreurs PHP, il est conseillé d’éviter ce genre de pratique.

Pour se faire, créer un fichier index.php dans chacun des dossiers et sous-dossier de votre module avec un contenu de ce type :

<?php 
     header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
     header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
     header("Cache-Control: no-store, no-cache, must-revalidate");
     header("Cache-Control: post-check=0, pre-check=0", false);
     header("Pragma: no-cache");
     header("Location: ../");
     exit;

L’idée est que l’en-tête renvoyé par PHP force l’absence de mise en cache avec les options Cache-Control, Pragma et la date d’expiration dans le passé puis redirige l’utilisateur vers la page d’accueil avec header("Location: ../").

Ce même fichier peut être utilisé dans tous vos sous-dossiers pour atteindre le même but.

Créer une vue de configuration

Pour commencer

Notre premier module a bien été créé, maintenant il faut commencer à lui donner une utilité ! Pour se faire nous allons commencer par créer un formulaire dans le back office pour gérer ses réglages.

Dans notre cas nous n’aurons qu’un seul réglage appelé NS_MONMODULE_PAGENAME qui demandera le nom d’une page qui sera affiché en lien dans la colonne de gauche de Prestashop.

Rien de bien excitant, mais ça sera suffisant pour l’exemple.

Afficher une page de configuration

Pour que Prestashop sache que votre module dispose d’une page de configuration, il faut utiliser la méthode getContent() qui retournera un formulaire accessible par l’utilisateur.

Si cette méthode existe, un bouton Configurer sera présent à droite du module, même si cette méthode ne retourne rien !

Voici le contenu de cette méthode :

public function getContent()
{
    $output = null;

    if (Tools::isSubmit('btnSubmit')) {
        $pageName = strval(Tools::getValue('NS_MONMODULE_PAGENAME'));

        if (
            !$pageName||
            empty($pageName)
        ) {
            $output .= $this->displayError($this->l('Invalid Configuration value'));
        } else {
            Configuration::updateValue('NS_MONMODULE_PAGENAME', $pageName);
            $output .= $this->displayConfirmation($this->l('Settings updated'));
        }
    }

    return $output.$this->displayForm();
}
  • Tools::isSubmit commence par vérifier si le formulaire a été envoyé ou non en fonction du nom du bouton de validation, ici appelé btnSubmit. Si ce n’est pas le cas, il affiche simplement le formulaire plus bas, sinon il gère les informations envoyées par le formulaire
  • On récupère la valeur de NS_MONMODULE_PAGENAME avec strval(Tools::getValue('NS_MONMODULE_PAGENAME'))
  • Et on teste cette valeur en regardant si elle existe et si elle n’est pas vide avec !$pageName || empty($pageName)
  • Si elle est n’est pas valide, on affiche une erreur à l’aide de la méthode displayError
  • Sinon on met à jour la valeur avec Configuration::updateValue et ensuite on affiche une confirmation de modification avec displayConfirmation
  • Pour terminer, on fait appel à la méthode displayForm (que nous allons créer par la suite) pour afficher le contenu du formulaire

Créer un formulaire

La méthode getContent() s’occupe de gérer l’affichage de la page de configuration, pour simplifier les choses nous allons gérer l’affichage du formulaire dans une méthode à part appelée displayForm.

Cette méthode utilisera la classe HelperForm qui met à disposition toute une série de méthodes pour créer et des formulaires dans le back office.

Voici à quoi ressemblera cette méthode :

public function displayForm()
{
    // Récupère la langue par défaut
    $defaultLang = (int)Configuration::get('PS_LANG_DEFAULT');
 
    // Initialise les champs du formulaire dans un tableau
    $form = array(
    	'form' => array(
	        'legend' => array(
	            'title' => $this->l('Settings'),
	        ),
	        'input' => array(
            	array(
	                'type' => 'text',
	                'label' => $this->l('Configuration value'),
	                'name' => 'NS_MONMODULE_PAGENAME',
	                'size' => 20,
	                'required' => true
	            )
	        ),
	        'submit' => array(
	            'title' => $this->l('Save'),
	            'name'  => 'btnSubmit'
	        )
	    ),
	);
 
    $helper = new HelperForm();
 
    // Module, token et currentIndex
    $helper->module = $this;
    $helper->name_controller = $this->name;
    $helper->token = Tools::getAdminTokenLite('AdminModules');
    $helper->currentIndex = AdminController::$currentIndex.'&configure='.$this->name;
 
    // Langue
    $helper->default_form_language = $defaultLang;	
 
    // Charge la valeur de NS_MONMODULE_PAGENAME depuis la base
    $helper->fields_value['NS_MONMODULE_PAGENAME'] = Configuration::get('NS_MONMODULE_PAGENAME');
 
    return $helper->generateForm(array($form));
}

Voilà un gros morceau, mais ne vous inquiétez pas ce n’est pas très compliqué.

  • On commence par récupérer la langue actuelle avec Configuration::get('PS_LANG_DEFAULT') ce qui nous permettra de définir la langue du formulaire plus tard.
  • On créé les différents éléments qui composeront notre formulaire : titre (legend), champ (input) et bouton de validation (submit). Pour ce dernier élément, on lui donne explicitement le nom btnSubmit pour valider l’envoi du formulaire plus haut. Le code suivant :
'input' => array(
	array(
        'type' => 'text',
        'label' => $this->l('Configuration value'),
        'name' => 'NS_MONMODULE_PAGENAME',
        'size' => 20,
        'required' => true
    )
)

Générera automatiquement ce contenu HTML une fois interprété :

<div class="form-group">
	<label class="control-label col-lg-3 required">
		Configuration value
	</label>
	<div class="col-lg-9">
		<input type="text" 
                       name="NS_MONMODULE_PAGENAME"
                       id="NS_MONMODULE_PAGENAME" 
                       value="Mentions légales" 
                       class="" 
                       size="20" 
                       required="required">
	</div>
</div>

Ensuite on va créer un nouvel objet HelperForm avec $helper = new HelperForm() et il recevra les champs définis en paramètre lors de la génération.

Mais avant de générer le formulaire, voici les champs définis :

  • $helper->module = $this : Spécifie le module parent de ce formulaire
  • $helper->name_controller = $this->name : Renseigne le nom du controller, ici le nom du module
  • $helper->token = Tools::getAdminTokenLite('AdminModules') : Token unique spécifique à ce formulaire (pour éviter le code malicieux). Ce token est générée grâce à la méthode getAdminTokenLite fournie par Prestashop
  • $helper->currentIndex = AdminController::$currentIndex.'&configure='.$this->name : Indique la valeur de l’attribut action du formulaire, donc l’URL à laquelle soumettre le formulaire. Ici il s’agit du controller actuel avec en paramètre le nom de notre module en valeur de la clé configure. En gros, la page actuelle
  • $helper->default_form_language = $defaultLang : Défini la langue utilisée pour ce formulaire à la langue par défaut du shop récupérée plus haut
  • $helper->fields_value['NS_MONMODULE_PAGENAME'] = Configuration::get('NS_MONMODULE_PAGENAME') : Pour terminer, récupère la valeur actuelle de notre champ dans la base pour l’afficher

Dernière chose, génération du formulaire avec, en paramètre, la liste des champs à créer à l’aide de la ligne :

return $helper->generateForm(array($form));

Pour obtenir le résultat suivant :

Résultat affiché dans la page de configuration du module
Résultat affiché dans la page de configuration du module

Si vous modifiez le contenu de ce champ, vous devriez voir cette page se rafraîchir avec une confirmation de modification !

Afficher du contenu sur votre boutique

Ajouter les méthodes liées aux hooks

Pour afficher du contenu sur la boutique, nous allons utiliser les 2 hooks auxquels le module s’inscrit à l’installation.

Si on reprend le code de la méthode d’installation :

public function install()
{
    if (Shop::isFeatureActive()) {
        Shop::setContext(Shop::CONTEXT_ALL);
    }

    if (!parent::install() ||
        !$this->registerHook('leftColumn') ||
        !$this->registerHook('header') ||
        !Configuration::updateValue('NS_MONMODULE_PAGENAME', 'Mentions légales')
    ) {
        return false;
    }

    return true;
}

On retrouve les méthodes registerHook pour le hook leftColumn et header. Vous pourrez donc voir que votre module a automatiquement été greffé à ces deux hooks en vous rendant dans Personnaliser > Apparence > Positions.

Une fois le module installé, celui-ci est automatiquement greffé aux hooks correspondants

Veuillez noter que si vous cliquez sur Greffer un module en haut à droite, vous ne pourrez lier votre module qu’aux hooks que vous aurez définis.

Ajoutons donc le code suivant pour gérer l’affichage du contenu dans la colonne de gauche avec la méthode hookDisplayLeftColumn.

Si à l’enregistrement du hook son nom était leftColumn, la méthode à appeler se forme elle de hook qui préfixe chaque méthode de ce type, Display pour indiquer qu’il s’agit d’un hook d’affichage (il existe des hooks d’action qui commencent par Action) et LeftColumn qui représente le nom du hook.

public function hookDisplayLeftColumn($params)
{
    $this->context->smarty->assign([
        'ns_page_name' => Configuration::get('NS_MONMODULE_PAGENAME'),
        'ns_page_link' => $this->context->link->getModuleLink('ns_monmodule', 'display')
      ]);

      return $this->display(__FILE__, 'ns_monmodule.tpl');
}
  • Cette méthode va commencer par assigner des variables qui seront utilisables dans les modèles tpl. Grâce à la méthode $this->context->smarty->assign on peut assigner des variables à la vue.
  • Ces variables appelées ici ns_page_name et ns_page_link seront ensuite accessibles dans la vue sous la forme $ns_page_name et $ns_page_link
  • ns_page_name récupère le champ dans la table ps_configuration tel que défini dans la configuration du module
  • ns_page_link lui va récupérer, dans le contexte actuel, un lien vers une action display de notre module ns_monmodule. Nous la définirons plus loin
  • Pour terminer, $this->display s’occupe de récupérer le fichier de template ns_monmodule.tpl utilisé pour afficher le contenu

Maintenant que le hook leftColumn a été défini, définissons le hook header. Celui-ci sera exécuté dans la balise <head> du document HTML.

public function hookDisplayHeader()
{
    $this->context->controller->registerStylesheet(
		        'ns_monmodule',
		        $this->_path.'views/css/ns_monmodule.css',
		        ['server' => 'remote', 'position' => 'head', 'priority' => 150]
		    );
}

Le hook header est très utile pour ajouter des fichiers CSS ou JavaScript à vos pages et la méthode registerStylesheet permet de générer une ligne de type <link> pour afficher le CSS correctement en fonction du chemin donné.

Effectuer le rendu

Pour gérer l’affichage des templates, ceux-ci se trouveront dans le dossier /views/templates du module, sous l’un des 3 dossiers suivant :

  • /front : Templates liés à la boutique
  • /admin : Templates liés au back office
  • /hook : Templates lié à un hook défini (indépendant du front ou back office)

Dans notre cas, nous créerons donc le fichier suivant :

/views/templates/hook/ns_monmodule.tpl

Lorsqu’on fait appel à un modèle à partir d’un hook, Prestashop va systématiquement allez voir dans le dossier correspondant des vues si un fichier avec ce nom existe.

Si c’est le cas, il l’affiche et en interprète le contenu. Le voici :

<!-- Block ns_monmodule -->
<div id="ns_monmodule_block_home" class="block">
  <h4>{l s='New Slang Link' d='Modules.Ns_MonModule'}</h4>
  <div class="block_content">
    <a href="{$ns_page_link}">
           {if isset($ns_page_name) && $ns_page_name}
               {$ns_page_name}
           {else}
               Votre lien
           {/if}
    </a>
  </div>
</div>
<!-- /Block ns_monmodule -->

Si vous voulez en savoir plus sur les modèles Prestashop et le code Smarty, consultez mon article sur la personnalisation de votre thème Prestashop ou découvrez mes 13 astuces pour modifier les vues de votre thème.

Mais rien de bien compliqué ici, il s’agit de simple HTML, agrémenté d’un peu de code Smarty :

  • {l s='New Slang Link' d='Modules.Ns_MonModule'} utilise la méthode de traduction l() en recherchant la traduction dans le contexte créé pour notre module, à savoir Modules.Ns_MonModule, pour la clé New Slang Link
  • {$ns_page_link} affiche simplement la variable assignée depuis la méthode hookDisplayLeftColumn plus haut
  • {if isset($ns_page_name) && $ns_page_name} ... affiche la variable ns_page_name si elle est définie, sinon un texte par défaut

Reste encore à créer un fichier CSS appelé ns_monmodule.css dans /views/css :

#ns_monmodule_block_home {
    box-shadow: 2px 2px 8px 0 rgba(0,0,0,.2);
    background: #fff;
    padding: 1.563rem 1.25rem;
    margin-bottom: 1.563rem;
}

Ce qui, une fois généré, donne le résultat suivant dès lors que la barre latérale est affichée :

Résultat du module affiché dans la barre latérale

Et si vous survolez le lien vous pourrez constater qu’il pointe vers l’action display de notre module qui pour le moment est introuvable. Nous allons nous occuper de ça tout de suite !

Suite à un commentaire très sympa de Grégory, petit rappel : n’oubliez pas que ce hook displayLeftColumn affiche du contenu dans la barre latérale de gauche dans Prestashop.

Et par défaut cette barre latérale ne s’affiche pas à beaucoup d’endroits dans le CMS, pour voir le résultat il faudra par exemple vous rendre sur la page d’une catégorie de produits.

Créer un controller et une vue

Lorsque vous tentez d’accéder à cette page, Prestashop va en fait allez interpréter un controller qui se trouvera dans :

ns_monmodule/controllers/front/display.php

Normalement, un controller est une classe qui gère l’affichage d’une vue liée. Il va s’occuper de récupérer les informations dont la vue aura besoin, lui transmettre les variables et objets nécessaires et définir le template à utiliser pour l’affichage.

Si vous créez simplement un fichier display.php dans /controllers/front avec un contenu de ce genre :

Salut tout le monde les gens !

En accédant à la page vous aurez ce résultat :

Erreur affiché à l'ouverture de la page display.php

Si vous avez le mode debug de Prestashop activé, sinon l’erreur PHP ne sera pas affichée. Mais remarquez qu’il affiche le contenu et qu’ensuite il soulève une erreur indiquant qu’il ne trouve pas la classe ns_monmoduledisplayModuleFrontController.

Pour lui, l’action demandée doit donc renvoyer une classe de ce type, nous allons donc la créer en lui donnant le template à afficher.

<?php
	class ns_monmoduledisplayModuleFrontController extends ModuleFrontController
	{
	    public function initContent()
	    {
	        parent::initContent();
	        $this->setTemplate('module:ns_monmodule/views/templates/front/display.tpl');
	    }
	}

Ici on crée donc le controller, qui hérite de ModuleFrontController, et dont le contenu est généré à partir de la méthode initContent.

Celle-ci commence par exécuter la méthode de la classe parente, puis définit le template à utiliser. Ici display.tpl dans ns_monmodule/views/templates/front. Si vous créez le fichier tel quel, vous n’aurez plus d’erreur mais seulement ce contenu affiché :

Salut tout le monde les gens !

Si vous désirez faire apparaître ce contenu au sein d’une page de votre shop, avec le menu, l’en-tête, etc. vous pouvez injecter votre code dans le template page.tpl par exemple (modèle par défaut des pages) en spécifiant le block dans lequel ajouter ce contenu, ici page_content :

{extends file='page.tpl'}

{block name="page_content"}
	<p>Salut tout le monde les gens !</p>
{/block}

Et voilà le résultat :

Résultat de l'affichage du controller display

Traduire le module

Dans le code

Selon la convention utilisée dans Prestashop, les textes par défaut d’un module sont toujours écris en anglais. Bien sûr ce n’est pas une obligation, mais c’est une bonne pratique.

Pour traduire une chaîne de caractère on utilise la méthode l() que vous avez déjà pu voir utiliser à plusieurs endroit dans cet article. Le fonctionnement de cette méthode varie en fonction de l’endroit où elle est utilisée.

Fichier principal du module

Au sein de la classe principale du module on appellera cette méthode de cette manière :

$this->l('Chaîne à traduire')

Ce qui indiquera à Prestashop qu’il devra rechercher la traduction avec la clé Chaîne à traduire et qui concerne le module actuel.

Controller

Dans un controller, il faudra faire référence au module de cette manière :

$this->module->l('Chaîne à traduire')

L’instance du module étant accessible à partir de la propriété module au sein d’un controller de type ModuleAdminController et ModuleFrontController.

Autres classes

Dans une autre classe il sera nécessaire de récupérer manuellement une instance du module. Voici un exemple de comment procéder :

class CustomModuleClass 
{
    public $module;
    
    public function foo()
    {
        // [...]
        $this->module = Module::getInstanceByName(<Module_name>);
        $this->text = $this->module->l('Chaîne à traduire', 'CustomModuleClass');

On récupère l’instance du module à l’aide de Module::getInstanceByName() et ensuite on appel l() sur cette instance en fournissant le nom de la classe actuel qui fait appel à la traduction.

Modèles

Dans les templates, il faudra donner le module explicitement en utilisant le contexte de notre module :

{l s='Chaîne à traduire' d='Modules.Ns_MonModule'}

s est la chaîne de caractère à traduire et d le contexte de la traduction, à savoir Modules suivi du nom de votre module.

Il est également possible d’y ajouter une hiérarchie, par exemple en créant un contexte pour la boutique et un autre pour l’administration :

{l s='Chaîne admin à traduire' d='Modules.Ns_MonModule.Admin'}
{l s='Chaîne de la boutique à traduire' d='Modules.Ns_MonModule.Front'}

Dans le back office

Lorsque vous définissez une traduction dans Prestashop, vous pouvez ensuite aller la consulter et la modifier directement dans le back office.

Un fichier généré par Prestashop s’occupe de créer la liste des traductions à partir des appels réalisés dans les différents modèles et classes de votre module (c’est aussi valide pour les modifications de modèles de votre thème par exemple).

En allant dans Personnaliser > International > Traductions vous pourrez choisir de traduire un module spécifique dans la liste :

Traduire votre module dans le back office de Prestashop

En choisissant la langue et en cliquant sur Modifier, vous verrez apparaître les différentes valeurs que vous avez défini à l’aide de la méthode l() dans vos classes et modèles :

Traduire votre module dans le back office de Prestashop

Si vous modifier une traduction et que vous l’enregistrez, comme dans cet exemple ou New Slang Link devient Autres liens, voici le résultat à l’affichage :

Résultat à l'affichage une fois la traduction effectuée

Et en plus de ça, Prestashop vous créé automatiquement un dossier translations dans le dossier de votre module, avec à l’intérieur un fichier PHP pour chaque langue traduite. Ici fr.php :

Dossier translations créé automatiquement par Prestashop

Avec ce dossier et la traduction créé, vous pouvez gérer la traduction de l’intégralité de votre module avant de le distribuer.

Conclusion

Créer un module avec Prestashop peut demander un certain temps d’adaptation, surtout concernant la structure des dossiers et fichiers (classes, controllers, etc.).

Mon conseil ? Inspirez-vous des modules existants ! Plusieurs erreurs trouvées dans la documentation officielle ont pu être corrigés pour cet article en fouillant dans les modules existants.

Par exemple la doc officielle indiquait que la traduction au sein d’un template se faisait avec le code :

{l s="Ma chaîne" mod="mon_module"}

Alors que dans Prestashop 1.7 il faut définir un contexte précis de cette manière, avec un paramètre d au lieu de mod :

 {l s="Ma chaîne" d="Modules.Mon_module} 

Bien sûr, j’avais déjà utilisé des traductions dans Prestashop 1.7 et cet attribut mod m’a tout de suite paru étrange. En consultant un des modules créés par Prestashop dans ma boutique, en gros tous les modules préfixés de ps_ dans le dossier /modules, j’ai pu clarifier certains problèmes rencontrés.

Si un temps d’adaptation est nécessaire, les possibilités sont nombreuses, la doc officielle recèle quand même beaucoup d’infos utiles et créer un module n’est finalement pas la mer à boire.

En cas de problème avec mon article, n’hésitez pas à me contacter en commentaire, j’essaierai de vous aider.

Vous avez réalisé un module à l’aide de cet article ? De quel type de module s’agit-il ?

95 commentaires

95 réflexions au sujet de “Guide complet : créer un module dans Prestashop 1.7”

  1. Merci beaucoup Thierry pour cet excellent article. J’ai tous suivi à la lettre …. tous marche nickel ! … juste un petit detail …. pourrais tu nous indiquer comment ajouter ou remplacer une icone (material design icons ou autre) à l’onglet de notre module qui apparait maintenant dans la barre de navigation de l’administration. Par default, j’ai hérité de celle de la categorie mere ou j’ai placé mon module …c’est à dire celle de l’onglet « Modules » qui s’appele « extension ».

    Merci encore pour la qualité de ton tuto.

    Répondre
    • Bonjour JM,

      Merci du retour ça fait super plaisir ! Très content d’avoir pu t’aider.

      Concernant ta demande, je vais essayer de faire un nouvel article sur le développement de module dans les prochaines semaines pour expliquer plus en détail certains éléments (affichage dans le menu, gestion de plusieurs onglets dans les réglages, création d’un module de paiement, etc.).

      Mais pour être tout à fait honnête, je n’ai pas encore trouvé comment ajouter un icône personnalisé à un élément du menu ! Par défaut Prestashop attribue un icône basé sur material design (l’icône ‘extension’). Et en fouillant le code de certains modules et en regardant la doc, rien trouvé à ce sujet !

      Je vais creuser ça et je reviendrai avec un tuto, la doc de Prestashop a de bonnes choses, mais entre les pages non à jour et d’autres explications expéditives, pas toujours facile de s’y retrouver.

      Bonne continuation en tout cas et merci pour ton commentaire.

      Répondre
      • Bonjour,

        Le dossier est à créer directement dans le dossier de votre module, sous le dossier de Prestashop, dans :
        \modules\[dossier de votre module]\views\templates\hook

        Bonne chance pour la suite !

        Répondre
    • Bonjour Grégory,

      Merci pour votre retour, c’est un plaisir. Je suis toujours content d’apprendre qu’un de mes tuto ai pu profiter à quelqu’un !

      Comme écrit juste au dessus, je reviendrai dans les prochaines semaines avec un autre article sur les modules pour approfondir encore un peu tout ça.

      Alors n’hésitez pas à repasser 😉

      Répondre
  2. Le tutoriel est super mais, lorsque nous arrivons dans la section faire apparaître le module dans la vue je ne vois rien et après je suis confus sur que page aller pour voire le résultat

    Répondre
    • Bonjour Frédéric,

      Pourriez-vous me donner plus de détail quant à votre problème ? Est-ce que celui-ci arrive lors de l’affichage dans le back office des réglages de votre module, ou dans la boutique directement ?

      Dans le deuxième cas, le contenu affiché par le module devrait s’afficher dans la barre latérale de gauche. Si ça ne fonctionne pas est-il possible que vous n’ayez pas activé la barre latérale de gauche ?

      Si vous avez un doute, vous pouvez aussi télécharger le module créé dans cet article. Vous trouverez un nouveau formulaire ajouté aujourd’hui dans cet article pour le télécharger !

      J’espère que ça vous aidera, je reste à votre dispo !

      Répondre
  3. Bonsoir je vous remercie beaucoup pour votre cours. je n accédé l espace admin de prestashop 1-7 .voici mon erreur « Impossible de traiter cette demande via localhost à l’heure actuelle.
    HTTP ERROR 500 « .je suis en local

    Répondre
    • Bonjour Kasse,

      Votre erreur semble liée à la manière dont vous avez installé Prestashop 1.7 en local et pas au développement de module précisément. Vous utilisez MAMP pour gérer Apache, MySQL et PHP ?

      Dans le doute, jetez un œil à mon tutoriel pour installer PS 1.7 en local, en suivant la procédure vous tomberez peut-être sur ce qui a cloché lors de votre installation. Malheureusement, difficile pour moi de vous donner une cause précise pour ce problème, cette erreur étant assez générique.

      Bonne chance pour la suite !

      Répondre
  4. Tutoriel incroyable !
    Merci à toi pour avoir passé du temps à rédiger cet article très détaillé et très instructif, cela va me faire gagner énormément de temps.

    Un grand merci

    Répondre
    • Merci beaucoup, Mathieu pour les compliments, ça fait super plaisir !

      Je vais travailler ces prochains temps sur une formation sur la création d’un module Prestashop en essayant de tout couvrir (ce que la doc de PS ne fait vraiment pas).
      J’espère pouvoir la proposer dans les 6 prochains mois !

      Répondre
  5. Excelent travail!!. Merci beaucoup d’avoir enseigné si clairement. Lorsque j’installe le module, je ne vois pas d’informations affichées dans le magasin (store). Le crochet ne semble pas fonctionner ou je n’ai probablement pas activé la barre latérale gauche dans le magasin (store). Comment puis-je activer la barre latérale gauche dans le magasin (front)?

    Répondre
    • Bonjour Gilberto,

      Content d’avoir pu t’aider pour créer ton premier module !

      Concernant ta demande, tu ne dois pas « activer » la barre latérale de gauche dans le magasin, mais il faut que tu visualises une page qui contient la barre latérale à gauche (par défaut la vue des produits affiche une barre latérale à gauche).
      Pour trouver une page utilisant ce modèle et faire les tests, tu peux te rendre dans le back-office sous Apparences > Thème et logo. Là tu cliques sur Choisir la mise en page en dessous de la liste de tes thèmes.

      Tu verras ensuite la liste des modèles de ton thème et pour chacun d’entre eux, le layout utilisé par défaut. Il suffit de trouver un modèle avec le layout Two Columns, small left column. Et pour tester, rends-toi sur cette page.

      Au pire si tu n’en trouves pas, modifie le layout à afficher sur une de tes pages en Two Columns, small left column pour voir apparaître la colonne de gauche. Si la barre latérale n’apparaît toujours pas, contrôle bien tes modèles dans ton thème sous templates\layout. Vérifie bien que le layout layout-both-columns.tpl, appel au sein de la barre latérale de gauche ({block name="left_column"}) le hook {hook h="displayLeftColumn"}.

      J’espère que ça pourra t’aider ! Bon courage pour la suite.

      Répondre
  6. Très bon tuto, merci Thierry d’avoir passé du temps pour rédiger cet article !!!!

    Pour un novice comme moi, j’ai pu réaliser en quelques minutes ce que je n’ai pas pu faire en plusieurs jours, merci beaucoup Thierry, c’est une aide précieuse.

    Je cherche à créer un module qui renvoie le client qui souhaite payer sa commande vers une page dont j’aurais enregistré le lien dans les paramètres du module; l’url doit contenir en paramètres la référence et l’identifiant de la commande. Pendant ce temps, la commande doit rester en attente d’une confirmation de traitement avant de passer en statut « Payé ». Le module doit s’utiliser au moment de la confirmation de paiement de la commande, après la sélection du transporteur (dans la rubrique « Paiement »).

    Aurais-tu une orientation semblable à celle-ci pour m’accompagner dans ma quête ?
    Je suis intéressé par la formation dont tu as parlé. Je suis disponible inbox si nécessaire.

    Répondre
    • Bonjour Michel,

      Très content que mon article ait pu t’aider à accélérer le processus ! La doc de Prestashop a de vraies lacunes à ce sujet et j’avoue que cet article est un des plus populaires de mon blog.

      Concernant ta demande, cela signifierait qu’il faut que tu crées un type de module spécifique, un module de paiement héritant de PaymentModule et qui a des hooks spécifiques (par exemple son affichage et l’action à entreprendre à la validation de la commande). Dans ton cas, le plus simple serait peut-être de le faire en Ajax avec une vue modale qui chargerait ta page et demanderait les infos supplémentaires (comme PayPal) avant de valider la commande.

      Ou simplement au choix du type de paiement, imposer la saisie des informations nécessaires avant de valider la commande ? Dans quel but faudrait-il renvoyer forcément sur une autre page avant de valider la commande ?

      J’espère en tout cas que ces précisions pourront t’aider à avancer. Pour la formation, je n’ai pas encore eu le temps de m’y attaquer sérieusement malheureusement, j’espère pouvoir commencer ça dans les 2-3 prochains mois. Je t’informerai dès que ça sera dispo !

      Répondre
      • Bonjour Thierry,

        Merci pour ta réponse, tu as bien compris l’objet de mon besoin et ma difficulté pour le mettre en place car je ne m’y connais pas dans ces langages de programmation, voilà pourquoi ton support, si tu le veux bien, serait la bienvenue.

        Je pense à un scénario où tu pourrais créer ce module prestashop spécifique à ma place et ce, dans un cadre que nous pourrions convenir ensemble inbox. En effet, je suis codeur en Windev exclusivement et je me retrouve dans l’environnement Prestashop dont les langages me sont inconnus, pour un projet qui a déjà accumulé du retard. Je te propose de me contacter via mon mail pour qu’on en discute plus en profondeur.

        Concernant ta question : « Dans quel but faudrait-il renvoyer forcément sur une autre page avant de valider la commande ? », la réponse est que cette autre page assure à 100% le paiement par monnaie électronique et elle exige les paramètres « Numéro de commande » et « référence de commande ». Ces informations sont créées dans la database de prestashop, lorsque la commande est confirmée.

        Je souhaite vivement te relire inbox et te souhaite un bon week-end.

        Répondre
  7. Bonjour Thierry,

    merci pour ton tuto, bien fait.

    Par contre j’ai rencontré un problème (ps 1.7.6.2) lors de la soumission du formulaire, j’étais redirigé vers la page de listing des modules et non pas sur la même page. Du coup mon champ n’étais pas sauvegardé.

    Pour remédier à cela, j’ai remplacé dans le bloc de code du Helper :

    AdminController::$currentIndex

    par

    $this->context->link->getAdminLink(‘AdminModules’, false)

    A priori je n’avais pas accès à $currentIndex : il y a une raison ?

    Cdlt,
    Stéphane.

    Répondre
    • Bonjour Stéphane,

      Merci pour le retour et surtout les précisions !

      Pour être tout à fait honnête, cette partie de code est un peu un passage obligé pour la plupart des modules. Quand on code le comportement du module dans le back-office, on utilise AdminController::$currentIndex pour construire l’URL qui sera utilisée par le formulaire.
      C’est comme ça dans tous les modules et n’ayant jamais eu de problème sur ce point, je n’ai jamais creusé le fonctionnement de $currentIndex !

      Vous avez donc remplacé la génération de l’URL de :

      $helper->currentIndex = AdminController::$currentIndex.'&configure='.$this->name;

      Vers :

      $helper->currentIndex = $this->context->link->getAdminLink(‘AdminModules’, false).'&configure='.$this->name;

      Je n’ai donc pas de réponse à ce sujet, mais grâce à votre commentaire cela pourrait peut-être aider d’autres personnes ! Et de mon côté, je garde ça en tête si je creuse encore un peu plus les modules dans le futur. Il faudra aussi que je fasse un test sur cette version 1.7.6.2.

      Merci encore du retour !

      Répondre
  8. Bonjour Thierry,
    Tout d’abord, super tuto ! J’ai vraiment beaucoup aimé et c’était très clair. Je pense même que c’est le seul tuto pour ps1.7 en français qui n’est ni trop complexe, ni trop long. J’ai remarqué une petite erreur que tu as corrigé sur ton module à télécharger mais pas sur le tuto pour la méthode hookDisplayHeader(), il manque le ‘server’ => ‘remote’.

    Sinon, j’aimerais savoir s’il est prévu un autre tuto qui sera le continuité de celui-ci, qui pourrait par exemple porter sur la présentation des hooks existant ou la création de nouveaux hook ? Et éventuellement si tu as des liens intéressants en français, nous sommes preneur 🙂

    Merci beaucoup 🙂

    Répondre
    • Bonjour Mohamed,

      Merci beaucoup pour le retour et les compliments ! J’y ai passé pas mal de temps, difficile de savoir de quoi parler et quoi laisser de côté, content que ça soit adapté. Pour ta remarque c’est corrigé, bien vu, et merci !

      J’en ai déjà parlé, j’aimerais sur le long terme proposer une formation complète, mais entre temps débarqueront certainement des articles plus condensés sur le sujet.

      Grâce aux commentaires ici, au retour d’e-mails que j’ai et à ma propre expérience, j’ai tout un tas de petites choses sur lesquelles je veux développer des articles, donc ça arrivera, mais pas dans les 2 prochains mois, je pense.

      Merci encore pour le retour !

      Répondre
  9. bonjour

    Tout d’abord merci pour ce tutoriel.

    j’ai donc crée mon module mais certaine zone de prestashop reste sombre, je souhaiterais que mon module s’implante dans les fiche produits et a la place du lien afficher une vue de mon module de calcule, auriez vous une doc qui pourrais m’aider ou même pourriez vous m’expliquez comment m’y prendre pour faire cela je ne demande pas forcement la réponse mais plus des indication.

    Répondre
    • Bonjour Andy,

      Content de pouvoir t’aider !

      Le développement de module sous Prestashop est très mal documenté malheureusement, cet article se base sur mes travaux de création de modules pour des projets clients et ce que j’ai appris grâce à la documentation, beaucoup d’analyse de modules existants et beaucoup de tentatives et d’erreurs.

      Je travaille toujours à une formation complète, mais je n’ai pas encore toutes les subtilités pour t’aider dans ce cas, il n’y a quasiment aucune documentation sur ce sujet. Je peux te conseiller d’essayer de trouver un module (gratuit idéalement) qui fasse quelque chose de similaire, et de creuser le code à la recherche d’information.

      Désolé de ne pas avoir de réponse plus claire !

      Répondre
    • Bonjour,

      À quel endroit souhaiteriez-vous avoir cet affichage, car sur la fiche produit, il existe de nombreux hooks permettant de le faire ?

      Sinon il faut regarder du côté d’un override du controller de produit, afin de modifier l’affichage pour forcer ce que vous souhaitez mettre en place.

      Cordialement,

      Répondre
  10. Bonjour

    Erreur dans votre exemple (MAGNIFIQUE quoi qu’il en soit, merci)

    Sur PS 1.7.6.5 sur lequel je teste, il faut remplacer votre ligne de code données en exemple :

    $helper->currentIndex = AdminController::$currentIndex.’&configure=’.$this->name;

    par

    $helper->currentIndex = AdminController::$currentIndex.’&configure=’.$this->name;

    Répondre
    • Bonjour Pierre,

      Merci pour le compliment, content que ce tuto puisse vous aider ! Concernant votre correction, je ne vois pas de différence entre les deux lignes de code est-ce possible ?

      Répondre
  11. bonjour,

    très bon tuto, encore merci, il me permet de m’initier au développement de module sur prestashop

    Pierre devait parler de cette ligne
    « $helper->currentIndex = AdminController::$currentIndex.’&configure=’.$this->name; » qui possede un « amp; » en trop 😉

    j’ai corrigé aussi cette ligne
    {if isset($ns_page_name) && $ns_page_name}
    par
    {if isset($ns_page_name)}

    je suis un peu égaré dans « Créer un controller et une vue » et « traduire le module » , surement la fatigue, je reprendrais ça un peu plus tard.

    encore merci et super boulot 😉

    Répondre
  12. Pierre a du bien mettre 2 lignes différentes, en fait une fois qu’on valide le formulaire le « amp; » disparait 😉

    ligne avec l’erreur:
    $helper->currentIndex = AdminController::$currentIndex.’& (a.m.p.;.) configure=’.$this->name;

    Répondre
    • Bonjour !

      Merci du retour, des compliments et des précisions ! J’ai mon plugin de formattage de syntax qui me joue des tours aussi, j’ai remarqué.
      Je suis en pleine création d’un petit module pour un client, ça me permettra de refaire un peu le point sur mon code, mais je note vos retours.

      Bon courage pour la suite. 😉

      Répondre
  13. Bonjour, tout d’abord merci pour votre tutoriel d’une rare clarté. J’ai une petite question moi aussi : Je dois créer un module permettant de créer un « accordéon » (en front) via le formulaire du back-office. Ma question se pose au niveau des variables : dois-je faire un serialize() au moment de l’install() contenant en array toutes les variables qui seront nécessaires (correspondant à chaque entrée du formulaire) ou serait t’il plus judicieux de créer une variable pour chaque input du formulaire ? Qu’en pensez vous ?

    Répondre
    • Bonjour Hugo,

      Merci pour les commentaires et compliments, heureux de pouvoir vous aider !

      Pour votre demande, j’ai tendance quand je travaille avec les modules à toujours créer une variable par champ / paramètre. Je dirais surtout que ça dépend de la manière dont votre module se comporte. Si vous pensez que votre module peut évoluer, avec une série de variables qui changeront peut-être avec le temps, un array peut-être une bonne idée.

      En fait c’est plutôt à vous de voir les avantages / inconvénients de chaque solution. Créé une variable pour chaque champ du formulaire peut-être un peu laborieux, mais permet de garder une structure stricte, alors que gérer un tableau peut s’avérer plus flexibles, mais pour enregistrer et récupérer les valeurs c’est moins intuitif et cela peut engendrer potentiellement d’autres erreurs.

      Il s’agit vraiment d’une préférence de code, une fois qu’on sort du cadre de l’env de Prestashop, c’est à vous de voir comment vous préférez travailler 😉

      Répondre
  14. Bonjour, merci pour ces explications … Je suis en cours d’apprentissage et adore prestashop. Puis je avoir un conseil sur comment avoir une vue du graphisme d’un module ? Quel outils utiliserais tu pour ca ? Pour le moment je me sert de Visual studio code mais ca ne montre pas le résultat final du module comme cela peut être pour un site … Merci de tes conseils 😉

    Répondre
    • Bonjour Thierry,

      J’utilise Sublime Text ou Visual Studio Code ainsi que mon navigateur (Chrome ou Firefox) pour le développement. tu ne trouveras pas d’autres solutions tes permettant de visualiser le graphisme du module malheureusement !

      Impossible donc de construire ce visuel à l’aide d’un builder quelconque, tu devras passer par le code, enregistrer vos modifications, afficher la page concernée par votre module (dans le back-office ou sur la boutique) et rafraîchir la page, il n’y a pas de miracle 😉

      Bon courage pour la suite de l’apprentissage en tout cas !

      Répondre
  15. Bonjour Thierry,

    Ton tuto est top et tes explications vont de le meme sens.

    Tout se passait pour le mieux pour moi mais j’ai ce message « Aucun gabarit trouvé pour le module testmodule « .
    J’aiun peu regardé, il parle de leo position module.
    Qu’en penses tu toi?

    Répondre
    • Bonjour Tom,

      Tout d’abord merci et très content que ça puisse t’aider !

      Concernant ton problème, en cherchant un peu sur le web je suis tombé sur ce topic sur le forum de Prestashop. Ils proposent des solutions qui pourraient peut-être t’aider !

      Vu l’erreur, tu utilises certainement un thème Leo Theme et je pense que le conflit vient d’une config ou d’un élément de fonctionnement de ton thème, en conflit avec ton nouveau module.

      J’espère que ça pourra t’aider, bon courage à toi !

      Répondre
      • Merci pour ta réponse, j’avais tout recommencé et celq fonctionnait mais c’est bon à savoir.

        Je me suis fais un backoffice maiso qui se connecte à la bdd de presta et j’aimerais afficher des données de la base au module créé. Cependant je n’arrive pas à afficher das le module, je suis un peu perdu avec les smarty, aurais-tu un tuto ou autres choses pour me faire comprendre comment faire cela s’il te plait?

        Répondre
  16. merci pour votre tuto

    J’ai juste un petit soucis, j’ai fait exactement la meme chose mais lorsque je clique sur sauvegarder, il ne sauvegarde pas et reviens sur la liste des modules sans afficher d’erreur

    Avez-vous une idée du soucis?

    Répondre
  17. Bonjour !

    Super tuto, merci pour vos explications !

    Je cherche à lier deux modules entre eux, savez-vous comment faire ? Faut-il créer un nouveau module en y copiant le code des deux modules de base puis ajouter une ligne de code qui joint ces deux derniers ?

    Merci,

    Stéphanie

    Répondre
    • Bonjour Stéphanie,

      Merci du retour ça fait plaisir !

      Cela dépend du lien que vous souhaitez créer, mais un module est constitué d’une classe principale publique que vous pouvez appeler depuis n’importe où dans Prestashop, jetez un oeil à ce thread du forum de Prestashop.

      En gros, il suffit de faire un include_once du module que vous voulez utiliser, puis de créer une nouvelle instance de la classe de ce module $mon_module_externe = new ModuleExterne(). Ensuite vous pouvez appeler une méthode spécifique du module avec $mon_module_externe->methode_externe().

      Bonne chance à vous pour la suite !

      Répondre
    • Bonjour Haloïse,

      Merci beaucoup pour le commentaire et les compliments, ça fait très plaisir !

      Bonne suite à vous dans le monde fabuleux du développement Prestashop 😉

      Répondre
  18. Super tutoriel, merci. Par contre il manque sur le net un tutoriel de cette qualité qui permettrait de réaliser un module backoffice qui utiliserait les données (analyse, export, etc…). Je suis sur 1.7.6.7, j’essaye d’afficher une grille avec des données depuis une table mais impossible de trouver un tuto qui indique comment faire. Rien à configurer, juste affichage d’une grille en BO avec des données de plusieurs tables de la BDD. Peut-être une idée pour un prochain tutoriel 😉

    Répondre
    • Bonjour Steven,

      Merci pour le commentaire et pour l’idée !
      Votre problème si je comprends bien n’est pas tant de créer la vue dans le back-office et d’afficher du HTML, mais plus de récupérer les données depuis une ou plusieurs tables pour la représenter en grille de données dans le BO ?

      Dans cet article j’avais monté un petit module qui permettait de voir comment ajouter une vue dans le back-office, ainsi que sur le front end, mais dans les 2 cas, le contenu était assez limité. Il faut que je réfléchisse si je peux trouver un moyen de créer un nouvel article ou de faire évoluer celui-ci en présentant un peu plus de possibilités de personnalisation dans le back-office.

      Et justement comment accéder à des tables et en afficher le contenu ! Je garde votre proposition dans un coin de ma tête dans tous les cas, merci 😉

      Répondre
  19. Bonjour Thierry

    est-il possible d’ajouter plusieurs pages dans votre module ?

    Dans le dossier controllers/front
    j’ai essayé display2.php
    en modifiant pour:

    // Et défini le template à utiliser

    $this->setTemplate(‘module:monkiki_tv/views/templates/front/display2.tpl’);

    }

    }

    et dans views/templates/front
    j’ai essayé display2.tpl

    https://localhost/MonKIKI/module/monkiki_tv/display2 (cela ne fonctionne pas !)
    alors que https://localhost/MonKIKI/module/monkiki_tv/display fonctionne très bien.

    faut-il faire une autre modification dans votre module ?

    merci d’avance pour l’aide.

    Répondre
    • Bonjour Thierry 🙂

      Changer le template défini dans le controller, ne fait que changer la vue que va utiliser le contrôleur à l’affichage. Si vous modifiez display2.tpl, vous verrez qu’en accédant à https://localhost/MonKIKI/module/monkiki_tv/display le résultat affiché ne sera plus celui du fichier display.php, mais celui du fichier display2.php.

      Pour pouvoir générer un lien différent, il faut créer un autre fichier dans controller/front spécifique pur cette nouvelle action display2. Vous l’appelleriez display2.php avec comme nom de classe :

      class ns_monmoduledisplay2ModuleFrontController extends ModuleFrontController

      Afin que le système sache que le chemin vers ce controller est display2 et non display. Ensuite la classe initContent s’occupe de charger votre modèle (que vous pourrez définir à display2.tpl).

      Il faut bien différencier le fichier tpl qui est la vue et qui s’occupe d’afficher le contenu et qui peut-être n’importe quel fichier, et le contrôleur qui va définir le chemin, le travail à effectuer (récupérer du contenu dans la base, effectuer des calculs, des validations, etc.) et la vue à utiliser pour afficher le résultat au visiteur.

      J’espère que c’est clair, bon courage à vous !

      Répondre
  20. Bonjour Thierry,
    Merci pour cet article!
    J’ai développé quelques modules pour mes clients et je me posais une question concernant leur mise à jour:
    quel est le meilleur moyen de mettre à jours les modules de façon automatique?

    Je pensais procéder ainsi:
    ajouter une tâche cron dans le module, cette fonction effectuerait un contrôle sur mon propre serveur pour vérifier le numéro de version actuel, s’il est différent: télécharger le fichier upgrade_x.x.x.php dans le dossier upgrade du module, et changer le numéro de version dans le fichier principal pour que Prestashop reconnaissance qu’il y a une mise à jour disponible dans l’admin.

    Qu’en penses-tu?

    merci!

    Répondre
    • Bonjour Eric,

      Avec grand plaisir !

      Je vais faire part de mes limites ici, mais je n’ai jamais développé de système de mise à jour pour l’un des modules que j’ai développé. En général, les modules sont assez spécifiques à mes clients et en cas de mise à jour, je travail directement dans le code. Et le peu de modules partagés entre plusieurs clients, je m’occupe de les mettre à jour manuellement en cas de besoin.

      Il semblerait qu’un module posté sur le Marketplace (ce qui serait ma prochaine étape pour savoir comment ça fonctionne de mon côté et le documenter sur le blog) dispose d’un système de mise à jour proposé directement par Prestashop, selon ce que dit la documentation.

      Si quelqu’un peut clarifier ce point, ça serait avec plaisir !

      Au sujet de la technique que tu proposes, elle me paraît tout à fait implémentable, mais difficile pour moi de confirmer ou d’infirmer qu’il s’agit de la meilleure manière de faire.

      Répondre
  21. bonjou frérot
    déjà merci pour le travail abattu c’est félicité

    j’ai soucis
    je veux developper un module prestahop qui me permettra d’extraire les factures en csv
    pourrait tu maider avec le code correspondant sinon un début pour m’orienter et si tu vraiment m’expliquer toute les étapes ce serait très chouette bro

    Je suis vraiment bloqué depuis car j’aimerais pouvoir permettre à mon comptable de les avoir facilement pour les traiter

    jesper que tu saura me guider et m’édifier

    merci davance

    Répondre
    • Bonjour Frérot 😉

      Je n’ai pas de code tout fait malheureusement, cet article donne les clés pour créer les bases d’un module et comprendre à quoi correspond le code utilisé. Dans ton cas, il faudrait utiliser ça comme base, afficher un bouton dans l’administration du module pour exporter les factures en CSV et à l’export, aller chercher les commandes dans la base de données et en générer le détail pour les factures.

      Tu peux utiliser la fonction PHP fputcsv pour générer du CSV en PHP. Et la fonction Order::getOrdersByStatut de PS pour récupérer une liste de commande en fonction de leur état par exemple. Fouille ce fichier sur github tu trouveras certainement plusieurs méthodes qui pourraient t’être utiles pour récupérer la liste des commandes de ta boutique et en faire quelque chose !

      J’espère que ça t’aidera, bon courage. 🙂

      Répondre
  22. Bonjour Thierry,

    Merci pour cette mise à jour de la doc prestashop. Juste une petite remarque pour l’affichage dans le hookDisplayLeftColumn. Tu devrais préciser à tes lecteurs qu’on ne voit pas le module sur la page d’accueil par défaut, qu’il faut aller sur un produit ou une catégorie pour voir le changement.
    Sinon c’est vraiment très bien, comme tout le reste de ton site ! Je ne manquerai pas de revenir !

    Répondre
    • Bonjour Gérgory,

      Merci beaucoup pour les compliments et bien vu ! Certains pourraient effectivement bloquer sur ce détail et penser ne pas parvenir à afficher ce contenu alors qu’il se trouve simplement sur la mauvaise vue. J’ai mis à jour l’article en conséquence, top 😉

      Répondre
  23. bonsoir ,
    Tout d’abord merci pour cet article!

    Je suis débutant dans PrestaShop , je crée mon premier module qui est module de déclinaisons de produits , où quel Hook utilise pour mettre ce module?

    comment on récupère les données de la base de données?
    merci d’avance.

    Répondre
    • Bonjour et merci pour le retour !

      Alors là il s’agit de questions un peu plus techniques que l’article ne couvre pas.

      Au sujet des hooks, j’ai créé cet article où je décris les hooks d’affichage de Prestashop. Mais le mieux est de creuser dans les modèles de Prestashop pour voir si le modèle product-variants.tpl ou avant l’appel de ce modèle, un hook est utilisable par ton module.

      Au sujet de la récupération des données dans la base, il existe plusieurs moyens. Il y a des méthodes spécifiques par type de modèle à récupérer (produit, clients, etc.), par exemple Customer::getCustomers() retourne la liste des clients présents dans la boutique. Ou alors il faut passer par des requêtes en utilisant les méthodes Db::getInstance()->execute() pour exécuter une requête insert, delete ou update ou Db::getInstance()->executeS() pour exécuter une requête de sélection.

      Mais pour tout ça, il va falloir creuser un peu et faire des tests, il n’existe pas de documentation toute faite malheureusement !

      Répondre
      • Merci thierry

        les classe de module de déclinaisons de produits sont-ils administrateur (id_admin, firstName, LastName), catégorie (id_catégory, name) et produit (id_product, name, id_attribute , référence)???
        pourrait tu maider avec le code correspondant pour gérer les déclinaisons , parce que je suis vraiment bloqué .

        Répondre
        • Bonjour !

          Alors là, je ne connais pas toutes les classes de Prestashop par coeur, et je crois n’avoir jamais codé un module spécifique aux déclinaisons donc je ne peux pas te donner le code correspondant d’un coup d’oeil. Mais je te conseille vivement de fouiller le code de Prestashop pour tenter de trouver la classe qui s’en occupe. Tu peux rechercher sur GitHub, je crois que les déclinaisons sont appelées « product variants » dans Prestashop, en recherchant dans le repo Git de Prestashop tu trouveras peut-être ton bonheur !

          Bon courage à toi pour ce projet.

          Répondre
  24. Salut Thierry,

    Merci pour ton tuto qui permet de bien comprendre la structure et le fonctionnement de Prestashop (et du code en général parce que je suis un total débutant 😉

    Du coup, je vais me lancer et essayer de créer un module qui va chercher le nombre total de commandes passées pour une période donnée et qui bloque les commande une fois un nombre défini atteint.

    Je vais essayer de reprendre le code du module statsales qui va récupérer les info et essayer de trouver un moyen en partant d’ici.

    Pour le moment je comprend tout juste comment afficher des trucs dans la back et le front office, donc encore du chemin, mais grâce a toi ça me semble moins impossible.

    A+

    Répondre
    • Bonjour Maik,
      Merci pour le retour ! Très content de pouvoir te donner de bonnes bases et du courage pour ton projet de module ! Et prendre un peu de temps pour fouiller le code de module existant est vraiment une excellente manière de procéder pour apprendre et trouver des techniques pour faire ce dont on a besoin.

      Bon courage 🙂

      Répondre
  25. Bonjour,

    Merci pour ce guide ultra complet, c’est le plus précis que j’ai pu trouvé sur le net !
    J’aurais une question concernant les routes.

    Je suis en train de développer un module et j’accède à l’un des controllers via l’url
    /index.php?fc=module&module=fxcheckout&controller=display

    Comme faire si je veux y accéder via /mycheckout par exemple ?
    J’ai vu des choses à propos de hookModuleRoutes sans que je parvienne à bien m’en servir.

    Merci d’avance de ton aide !
    FX

    Répondre
    • Bonjour François-Xavier,

      Merci du retour ça fait plaisir ! Mais vu les demandes, je pense que mon guide n’est pas encore assez complet 😉
      Pour la modification des routes, je ne l’ai malheureusement jamais fait même si je me suis déjà demandé comment faire ça. J’ai rapidement jeté un oeil à la source du module ps_linklist (Link Widget dans Prestashop) qui génère une URL différente du type :

      /index.php/modules/link-widget/

      Avec apparemment ces propres règles de routage, jette un oeil à la source sur Github pour voir comment il se comporte. Apparemment on a dans le dossier un config un fichier routes.yml qui semble s’occuper d’une partie du job ? Mais je n’ai pas fouillé toutes les classes pour savoir où exactement ces routes étaient utilisées et comment.

      Donc en gros : il faut trouver un module qui le fait et le décortiquer, c’est généralement comme ça que je procède 😉 Mais si je trouve la solution entre-deux, je ne manquerai pas de revenir mettre un petit commentaire.

      Bon courage !

      Répondre
  26. Salut et merci pour l’article, c’était édifiant.
    Mon problème est un peu à côté pour le moment, je dois faire communiquer une boutique créé avec prestashop à une application quelconque (mobile,web,…) Pour faire passer des informations sur la boutique et celui qui achète sur la boutique, je doute entre créér un module et après mettre en place une API ou soit une API qui va faire ça.
    Voilà mon inquiétude, je serai ravis de recevoir votre aide.

    Répondre
    • Bonjour Elie,
      Merci du retour content que l’article vous plaise !
      Si vous devez communiquer avec Prestashop de puis l’extérieur, vous n’avez pas besoin de développer un module, vous pouvez simplement activer le Webservice de Prestashop dans le back-office sous Paramètres avancés et Prestashop met une API à disposition tout seul.
      Il faudra vous créer une clé avec des droits spécifiques, mais rien de bien complexe. Ensuite vous pourrez, depuis votre application, accéder au contenu de la boutique et même le manipuler.

      Voici la doc (en anglais) du Webservice de Prestashop : https://devdocs.prestashop.com/1.7/webservice/

      Bon courage pour ce projet !

      Répondre
  27. Bonjour et merci pour l’article qui met d’une grande aide.

    J’ai pu créer mon module, sur la page configuration dans le champ texte si j’enregistre (mon début de texte et la fin de mon texte), le texte est bien enregistré et pas

    Et si j’enregistre manuellement ce qu’il y a entre les parenthèses dans phpMyAdmin, sur mon site ça affiche mon début de texte et la fin du texte.

    Saviez-vous comment faire pour avoir le code source comme dans les fiches produits ?

    Je serai ravi de votre aide !

    Répondre
    • Bonjour Jean,
      Ravis d’avoir pu vous être d’une grande aide !
      Cependant j’avoue ne pas avoir bien compris votre problème. Donc vous avez déjà une page de configuration pour votre module et si vous modifiez une valeur et que vous enregistrez, il ne reprend pas tout le texte ?

      Répondre
      • Bonjour Thierry,

        J’avoue que mon message n’a pas dû être très compréhensible, le texte posté ici a supprimé les balises HTML. Pour vous tenir informé, j’ai résolu le problème en ajoutant $html = true à updateValue.

        Je rencontre un dernier problème avec la traduction du fichier .tpl dans le dossier hook, celui-ci ne s’affiche pas dans la traduction des modules comme expliqué sur le site, les seules présentes sont celles du fichier php.

        J’ai bien remplacé d=’Modules.par le nom de mon module’, aviez-vous une idée ?

        J’utilise la version de PrestaShop 1.7.8.2

        Passez de bonnes fêtes de fin d’année !

        Répondre
        • Bonjour Jean,

          Content que vous ayez pu régler ce problème ! Pour les traductions, j’ai moi-même eu des problèmes avec ça, il se trouve qu’il y a 2 méthodes de traduction : soit en utilisant un domaine spécifique (comme vous l’avez fait) et qui permet de traduire le contenu au niveau du thème. Mais ces traductions sont plus spécifiques au front-end.

          En cas de problème, vous pouvez essayer d’utiliser l’autre méthode, là vous devrez traduire le module en choisissant « Module » comme type de traduction dans Prestashop, et pas le thème. Cette méthode est la suivante :

          {l s='Votre texte' mod='[nom de votre module]'}

          Attention a bien reprendre le nom définie dans $this->name dans le constructeur du module.

          Et normalement ça devrait le faire 🙂

          Belle fêtes de fin d’année à vous aussi Jean et bon courage avec ce module !

          Répondre
  28. Merci pour votre tuto très instructif!

    Dite moi, est il possible d’acheter un module sur addon.prestashop et de le modifier totalement pour l’adapter à notre projet?

    Bien-sûr il n’y aurait plus de mise à jour externe à notre entreprise.. Je voudrais être sur avant de dépenser beaucoup d’argent dans un des modules.

    Répondre
    • Bonjour Yoann,

      Merci du message et content d’avoir pu vous aider ! Pour la modification d’un module, je vous avoue que je ne sais sous quel type de licence ils sont distribués. Le mieux serait peut-être de demander au développeur du module ?
      Mais dans le fond, si vous avez prévu de l’installer et de ne modifier le code que pour un seul projet, sans avoir prévu de faire de la revente derrière, je ne pense pas que c’est un problème.

      Il m’est arrivé de corriger des bugs dans des modules ou d’ajuster des fonctionnements (en général avec des overrides cependant) sans me poser plus de questions que ça. Et je fais de même sur WordPress en cas de besoin.

      J’espère que c’est clair, bon courage avec ce projet !

      Répondre
  29. Bonjour, merci pour l’article !

    Petite question concernant l’analyse de performance de notre module.
    Y-a-t-il un moyen natif ou pas, de remonter la configuration de notre module ? Eg : cette fonction du module est activée chez 30% des marchands.
    Cela afin de monitorer le succès du produit et d’optimiser son utilisation.

    Merci et bonne journée !

    Répondre
    • Bonjour Romain,
      À ma connaissance, il n’existe pas de moyen natif pour faire remonter les performances du module. Il faudrait que vous développiez un système qui s’occupe ponctuellement de faire remonter l’information sur vos serveurs.
      Cela ne doit pas être excessivement compliqué (envoi de l’info à une API sur vos serveurs) mais le problème, c’est que le code est dispo à tous et si quelqu’un creuse, il pourra potentiellement envoyé des requêtes incorrectes à votre API (cela reste très hypothétique).

      Après il existe une autre solution bien plus simple : créer un sondage Google par exemple et demander gentiment aux utilisateurs un mois ou deux après achat ce qu’ils utilisent dans le module.
      Mais à nouveau, je n’ai pas connaissance de fonctionnalités natives de ce type avec Prestashop.

      Bonne suite à vous !

      Répondre
  30. Bonjour, merci mille fois pour ce tuto hyper clair ! C’est du pain béni ce genre d’article.
    Toutefois, je me demande s’il est possible d’exécuter la méthode registerStylesheet() et registerJavascript() seulement quand les templates ou hooks du module sont appelés ou affichés ?

    Répondre
    • Bonjour Florian,
      Merci pour les compliments pour cet article, c’est un plaisir ! 🙂
      C’est effectivement une bonne question et une bonne pratique de n’inclure les assets que sur les pages concernées, il me semblait avoir déjà fait ça, mais je n’ai pas retrouvé le code. Sur le principe, exécuter ces méthodes depuis le hook d’affichage de votre module par exemple (donc exécuté uniquement au moment où le contenu de votre module est affiché) doit fonctionner également. J’ai juste un doute quand à l’emplacement des JS et CSS dans cette situation, normalement ça doit s’ajouter en ligne au sein du body, ce qui n’est pas idéal.

      Le mieux est de faire des tests ! À ma connaissance, il n’y a pas de moyen de savoir depuis displayHeader si un hook spécifique est exécuté au sein du contenu.
      Et si vous trouvez une solution, n’hésitez pas à la partager ici !

      Répondre
      • Alors ça m’étonne que ce soit aussi simple mais voici comment j’ai procédé :
        Dans Personnaliser/Apparence/Positions, je suis allé dans la partie « header » puis j’y ai modifié le module en question.
        J’ai ensuite mis tous les fichiers en exceptions sauf celui concernant le module lui-même.
        Ça fonctionne comme ça jusqu’à maintenant.

        Répondre
  31. Bonjour, j’ai une nouvelle question 🙂
    J’ai du mal à comprendre concernant la table ps_configuration, si je veux stocker des données que l’administrateur ajoutera depuis un formulaire dans la configuration du module (images, texte, etc..) je dois le faire directement dans cette table ? Ça me paraît vachement fouilli avec ses plus de 1000 lignes.
    Et si oui, je n’arrive pas à le faire de toute façon ^^
    J’aurais peut-être besoin d’un petit coup de main !
    Merci.

    Répondre
    • Petit update, j’arrive finalement à ajouter des données dans cette table avec l’objet configuration.
      Par contre la question de si je dois le faire ici ou dans une nouvelle table persiste, j’ai en plus l’impression que la fonction Configuration::updateValue ne permet pas de remplir un tableau, ça écrase à chaque fois la valeur précédente. Je dois louper un truc peut-être ?

      Répondre
      • Bonjour Florian,

        Première chose : vous n’allez pas enregistrer vos images dans la base de données, vous allez plutôt les enregistrer dans un dossier du module (aller voir comment c’est fait en fouillant le code de ps_imageslider par exemple) et en ajouter une référence dans la base.
        Deuxième chose : rien ne vous empêche à l’installation de créer une table spécifique pour votre module. Mais il n’y a pas de raccourci, il faut écrire du SQL qui va créer la table dont vous aurez besoin. Une fois de plus, rendez-vous dans ps_imageslider, il me semble qu’il crée une table au moment de l’installation. Et à la désinstallation bien sûr, il faut supprimer la table.
        Et pour terminer, dans ps_configuration vous pourriez enregistrer de nombreuses données sous forme de tableau et ensuite les récupérer sous cette forme si vous le souhaitez. Mais il faut le récupérer avant enregistrement, potentiellement ne modifier que ce que vous souhaitez modifier et ensuite le réenregistrer dans sa version modifiée, dans la base, chaque UPDATE écrase la valeur précédente, effectivement.

        Je vous conseille d’aller un peu creuser les autres modules, j’ai beaucoup appris comme ça, en cherchant un module qui fait quelque chose de spécifique dont j’aurais besoin et en allant voir son fonctionnement. Aujourd’hui encore, il m’arrive de le faire, parce que je n’ai pas de solution toute faite à toutes les problématiques qu’un module peut poser 😉

        Répondre
        • Bonjour, merci beaucoup pour votre réponse. J’ai en effet réglé ce petit soucis d’upload d’images.
          J’upload effectivement directement les fichiers images dans un dossier et les noms de ces dernières dans la table ps_configuration sous forme de tableau. Concernant l’écrasement de chaque valeur avec l’update, j’ai aussi réussi à faire en sorte que ça n’arrive pas, j’ai aussi fait en sorte que les doublons ne s’ajoute pas inutilement.
          Je suis allé checké dans ps_imageslider oui et d’autres modules existant, je sais même plus si ça m’a aidé ou pas au final ^^
          J’ai maintenant un autre soucis explicité dans un post stackoverflow, je vous met le lien ici : https://stackoverflow.com/questions/73134972/issues-creating-admin-module-controller-on-prestashop
          Bien entendu libre à vous de m’aider ou pas, j’ai conscience de vous en demander beaucoup à force ^^
          Merci en tout cas !

          Répondre
          • Bonjour Florian,

            Content que ça avance ce module, la progression par l’échec c’est quand même une progression, et on apprend beaucoup !
            Alors pour être sincère je n’ai jamais créé de controller au sein d’un de mes modules Prestashop donc je ne saurais vous aider comme ça. Après je pense juste à un détail, il faut peut-être que Prestashop mette à jour les routes du CMS et, peut-être, que le fichier class_index.php présent dans var/cache/dev et var/cache/prod (je crois que cela dépend du mode debug activé ou non) ne s’est pas mis à jour avec le controller de votre module ? Après c’est vraiment une idée comme une autre, renommer totalement le dossier var/cache en var/cache2 pour reconstruire le cache complètement peut aussi aider, si le problème vient de routes qui ne se mettent pas à jour.

            Sans garantie, mais ça ne coûte rien d’essayer 🙂

  32. Bonjour,
    Tout d’abord merci pour ce tuto qui éclair bien ma lanterne sur différents points. De mon coté je l’ai joué les petits bras n’ayant de toute manière pas l’intégralité des compétences pour me lancer dans la création.
    l’idée c’était de dupliquer le module wire payment, ce qui a priori semble simple.. a priori seulement :).
    j’ai donc dupliqué, modifié les classes et les variables spécifiques, les paramètres d= etc.. etc… Pourtant même si le module s’installe et fonctionne je n’arrive pas a accéder à la traduction, quand je sélectionne le module à traduire dans la liste l’appui sur « modifier » ouvre une page sans aucuns champs pouvant permettre de modifier les textes, juste un menu déroulant en bas avec la liste de tous les modules et l’avertissement au milieu de l’utilisation des syntaxes spéciales.
    ca fait 2 jours que je m’arrache les cheveux la dessus en scannant tous les fichiers afin de trouver les références à wirepayment dans le but de les dupliquer et de les renommées, j’ai même essayé de créer directement les traductions dans la table ps_translate sans réussir à faire matcher les deux…
    Bref, si tu avais une piste de recherche je prendrai bien volontiers.
    d’avance merci

    Répondre
    • Réponse… bah, déclarer la méthode…

      public function isUsingNewTranslationSystem()
      {
      return true;
      }

      ca marche tout de suite mieux 😉

      Répondre
      • Bonjour Jean-Marc,
        Merci pour le retour ! Je vais devoir creuser cette question, j’ai souvent eu des soucis avec les traductions des modules qui ne fonctionnaient pas avec le nouveau système de PS 1.7, mais je n’ai jamais utilisé cette méthode que je découvre avec votre commentaire.
        C’est top, super partage, je vais pouvoir tester ça sur mes modules problématiques 🙂

        Répondre
  33. Bonjour,

    J’ai un soucis depuis plusieurs jours que je n’arrive à résoudre :

    0():Missing ‘$template’ parameter

    Cette erreur s’affiche quand je souhaite ouvrir ma page via le ModuleFrontController :

    public function iniContent()
    {
    parent::initContent();

    $this->setTemplate(‘module:ml_retourmlk/views/templates/front/retourmlkfirst.tpl’);
    }

    tout les noms de fichiers son correcte du coup si quelqu’un à une idée je suis prenneur.

    Merci 🙂

    Répondre
    • Bonjour Ludo,

      Je ne sais pas si c’est une erreur de copier-coller, mais la méthode d’initialisation s’appelle initContent et pas iniContent comme je le vois ici. Le code corrigé :

      public function initContent()
      {
      parent::initContent();
      $this->setTemplate(‘module:ml_retourmlk/views/templates/front/retourmlkfirst.tpl’);
      }

      En croisant les doigts pour vous pour que ça soit simplement cette petite typo 🙂

      Répondre
  34. Bonjour,
    Merci pour la clarté de votre tuto, j’aurai besoin d’un coup de pousse sur mon blocage.
    Je travaille avec la version 1.7.8.5, mais je ne constate pas de mis à jour sur le module après avoir initialisé le constructeur.
    Et quand j’essaye d’installer le module j’ai comme message d’erreur : Cannot install module earth_connexion. The module is invalid and cannot be loaded.
    Merci de votre retour.

    Répondre
    • Bonjour,

      Difficile de pouvoir vous aider sans avoir plus d’informations, le problème de Prestashop à l’installation d’un module, c’est qu’il ne va en général donné aucune info sur l’erreur. Essayez d’aller voir dans les logs de Prestashop (sous Paramètres avancés > Logs) si quelque chose est indiqué. Mais de mémoire, et j’ai développé pas mal de modules pour mes clients, à chaque fois que j’ai eu une erreur de ce type, il a fallu que je revienne à mon code et que j’analyse les erreurs éventuelles.

      Une façon d’analyser ça est d’enlever des parties de code, par exemple enlever le code contenu dans les appels de hooks ou certains contrôles à l’installation. Si ça plante toujours, ça n’est donc pas ce code qui pose problème et on remet le code (copier / coller, CTRL + Z, comme ça vous arrange).

      Contraignant, mais pour isoler ce qui coince c’est plutôt efficace.

      Bon courage à vous !

      Répondre
      • Bonsoir,
        Merci de votre réponse. J’ai fait ce que vous avez suggéré en enlevant toutes les fonctions et recommencer.
        Maintenant en mettant seulement le constructeur, les logs indiquent le message suivant: Syntax error, unexpected \’;\’ on line 4 (ligne 4 correspond à $this->tab = ‘front_office_features’;) sur mon code.

        Répondre
        • Bonjour Awa,
          Dans l’exemple que vous me donnez, est-ce que vous avez conservé les apostrophes de ce type ? C’est un détail, mais si c’est le cas, c’est une erreur de syntaxe. Il faudrait utiliser les apostrophes simples dans le code :
          $this->tab = 'front_office_features';
          Mais sans ça, difficile pour moi de plus vous aider, il y a une erreur de syntaxe dans votre code et il faut creuser pour la trouver !

          Répondre
  35. Bonjour,

    en premier lieu merci pour ce tuto cela m’a bien éclairé. Etant plutôt intégrateur/graphiste avec seulement qques notions de php cela me permet de gérer pas mal de chose au niveau affichage sans passer par autrui ou « n » modules. Donc merci merci et encore merci.

    Par contre là je bute sur une remontée de variable sur le template product_price.tpl
    En gros je dois faire des opérations mathématiques avec qques « taux » pour un affichage supplémentaire sur le prix produit en fonction de certaines caractéristiques hors mes variables smarty remontent bien sur mon module sur un des hook produit mais ne sont pas exploitables pour mes opérations car blocks séparés. Normal.

    La seule solution actuellement que j’ai trouvée c’est de modifier directement le contrôleur ProductController.php sur la fonction assignPriceAndTax() et d’assigner mes variables qui sont entrées par le client via un module créé par ce tuto. Oui je sais, « c’est mal », surtout que j’arrive même pas à l’override 🙁
    Question : comment puis je assigner mes variables directement sur un template comme product_price.tpl afin de les exploiter pour des opérations autres qu’un simple affichage.
    Je pense que la solution doit être simple mais là Je galère depuis 2 jours. Merci d’avance de votre réponse.

    Répondre
    • Bonjour,
      Au contraire, je ne pense pas que la solution soit si simple. Votre méthode n’est pas si sale, si vous faites de l’override, sans quoi effectivement, c’est très problématique.
      Mais d’expérience, il n’est pas toujours aisé d’ajouter du contenu dans un template spécifique à l’aide d’un module sans faire de petites overrides. Beaucoup de modules ajoutent des overrides à la boutique pour faire ce dont ils ont besoins.

      Après, sans connaître parfaitement votre code, il est difficile de vous donner une solution simple. Je peux vous conseiller, comme le développement Prestashop est assez mal documenté, d’essayer de trouver de l’aide sur des groupes, par exemple le groupe Facebook d’entraide Prestashop.

      Bon courage à vous avec ce problème !

      Répondre
  36. Bonjour Thierry,
    Merci beaucoup du temps que vous avez pris pour me répondre.
    Oui, la méthode n’est pas en cause. En fait c’est de ne pas arriver à faire passer mes variables en override sur le block « product_price » du template product_price.tpl et d’attaquer directement le fichier controller de base qui me pose pb.

    Du coup voici la ligne de code que j’ai ajouté (entre les commentaires ABK) dans la fonction assignPriceAndTax() du fichier ProductControler.php de base.
    $this->context->smarty->assign([
    ‘no_tax’ => Tax::excludeTaxeOption() || !$tax,
    ‘tax_enabled’ => Configuration::get(‘PS_TAX’) && !Configuration::get(‘AEUC_LABEL_TAX_INC_EXC’),
    // MODIF AJOUT VAR TAUX ———————————————————
    ‘taux1’ => (float) Configuration::get(‘ABK_TAUX1’),
    // MODIF AJOUT VAR TAUX ———————————————————
    ‘customer_group_without_tax’ => Group::getPriceDisplayMethod($this->context->customer->id_default_group)
    ]);
    Cela fonctionne très bien mais comment passer cette simple instruction de passage de var en override ? Je crois avoir compris que je dois surcharger la class ProductControllerCore mais malgré « n » essais ça ne passe pas.
    J’ai bien été voir vos formations mais aucune ne correspond aux surcharges. Bien dommage.
    Si vous pouviez m’aiguiller sinon encore merci pour votre aide et pour le lien d’entraide presta.

    Répondre
    • Bonjour,
      Pour surcharger un controller, il faut effectivement passer par la création d’un fichier du même nom (ProductController.php) et avec le même chemin au sein du dossier override. Ensuite, il faut surcharger ProductControllerCore en prenant soit d’appeler sa classe autrement. Dans cette classe, reprendre l’entièreté de la fonction assignPriceAndTax() et y ajouter votre code.

      Une fois cela fait, il est impératif d’aller dans cache/class_index.php et de supprimer ce fichier pour que Prestashop recherche la liste des surcharge et tienne compte de votre modification. Une fois cela fait, vous devriez voir fonctionner votre override !

      Désolé du délai de réponse, j’espère que ça vous aidera.

      Répondre
      • Thierry,
        merci pour votre réponse. Je vais donc ré essayer l’override du controller en suivant vos conseils.

        Autre : pensez-vous augmenter vos offres de formations ?
        Une formation concernant la créa de module et leur intégration serait très certainement très demandée pour des personnes qui comme moi aiment avoir la main sur pas mal de chose sans avoir à passer par « n » modules externes pour de simples rajouts (je ne parle pas de modules complexes que je laisse volontier aux programmeurs spécialisés et expérimentés comme vous).
        Actuellement je fais un module de montage de fiche produit complexe (avec « n » champs de gestion pour un montage semi automatique de la fiche produit). Cela fonctionne très bien mais je reste dans le « truc et astuce », donc pas vraiment propre voire peu orthodoxe avec une grosse gestion JS en amont et smarty sur le tpl. Et certaines choses fonctionnent mais restent assez mystérieuses 🙁

        Pour finir, encore merci du temps que vous m’avez accordé.
        Cordialement.

        Répondre
        • Bonjour Yab,
          Avec plaisir, content que ça ait pu vous dépatouiller.
          Je vais être honnête avec vous, j’ai aussi eu ce sentiment de « bidouille » et « trucs et astuces » à la création de certains modules ou lors d’overrides dans Prestashop. J’ai développé des modules de synchro import / export qui me semble solides, mais dès qu’il s’agit de toucher à l’interface et à faire de l’override, c’est souvent la progression par l’échec. Il y a 2 ans, je vous aurais dit que je songeais à une formation plus avancée sur le développement Prestashop, mais plus maintenant.

          Il se trouve que j’ai de moins en moins de projet Prestashop (moins populaire en Suisse), d’abord, car ils ne correspondaient pas toujours à mes prestations et, aujourd’hui, parce que je me sens bien plus à l’aise avec WordPress + WooCommerce, développement compris (la documentation est énorme en comparaison). Donc, je ne me sens pas de faire une formation avancée sur un sujet que je ne maîtrise plus à 100% aujourd’hui.

          Ne serait-ce que pour vous donner ces réponses en commentaires, je dois toujours un peu me re-documenter !

          J’espère en tout cas que vous arriverez à vos fins avec ce module, bon courage à vous.

          Répondre
  37. Thierry,
    oui je comprends votre point de vue, alors tant pis.

    Et oui Wordpress combiné avec WooCommerce sont bien plus accessibles, moins gourmands et bien moins lourds que Presta qui reste une vraie usine à gaz. Mais bon, Presta, même si il est plus opaque à bien des égards, reste actuellement plus complet et surtout on prend ce que nous impose les clients.

    Encore merci et bonne continuation.

    Répondre

Laisser un commentaire

Télécharger cette super ressource gratuite !

Entrez votre adresse e-mail ci-dessous et recevez cette ressource dans votre boîte de réception dans quelques secondes.