Tutoriel Prestashop – Créer un module avec onglet

Introduction

Beaucoup de développeuses et développeurs se demandent comment créer un module sous Prestashop contenant un onglet.

Nous allons donc détailler pas à pas la création de ce fameux module.

Architecture d’un module

Le véritable schéma de construction d’un module dans Prestashop devrai toujours s’apparenter à ceci:

Arborescence d'un module

Comme vous pouvez le voir, le module dispose de trois dossiers :

  • img : pour les images
  • js : pour le javascript
  • css : pour les styles

Le module dispose aussi de divers fichiers :

  • logo.gif : icône du module (dimensions 16×16 pixels)
  • AdminTutorial.gif : icône de l’onglet (depuis la v1.2.0.4, non implémentation résolue avec Philippe S.)
  • tutorial.php : fichier cœur du module (expliqué ci-après)
  • tutorial.tpl : fichier modèle (ou dit template) utile pour l’affichage de notre hook
  • AdminTutorial.php
  • fr.php : pour la traduction française (peut-être décliné en es.php, de.php, etc.)

Note
Le mot « tutorial » dans le nom des fichiers doit-être remplacer par le nom de votre module ou onglet.
Par convention, ce nom est en anglais (et pas Franglais…)

Le fichier cœur du module (tutorial.php)

Le fichier cœur du module est le fichier qui régit l’installation, la désinstallation, la configuration et
l’exécution dans les hooks (ou hameçons en français).

Une classe

Ce fichier est composé d’une seule classe portant le nom de votre module et étendant la classe Module.

<?php
class tutorial extends Module
{
  // Méthodes & Membres
}
?>

Un constructeur : __construct()

Le constructeur de cette classe ayant pour nom de méthode __construct() (je vous renvoie aux cours sur l’objet PHP5) permet au module d’être identifié et classé dans la liste des modules du backoffice.

public function __construct()
{
  $this->name = 'tutorial';
  $this->tab = 'Blocks';
  $this->version = '1.0';
 
  parent::__construct();
 
  $this->displayName = $this->l('Tutorial Module');
  $this->description = $this->l('I&#39;m a tutorial module, thanks to Julien Breux');
  $this->confirmUninstall = $this->l('Are you sure you want to delete your details ?');
}

Comme vous pouvez le voir, la méthode __construct() permet d’attribuer des valeurs à certains membres.
(petit rappel de base, les variables à l’intérieur des classes sont appelées des membres)
Les membres sont les suivants :

  • name : nom du module (sans accents, espaces, caractères spéciaux…)
  • tab : catégorie du module (other, stats, products, tools, advertisement, blocks, etc.)
  • version : version du module (rappelons qu’actuellement il n’existe aucune gestion de mise à jour)
  • displayName : nom pour l’affichage du module (xHTML court autorisé)
  • description : description pour l’affichage du module (xHTML court autorisé)
  • confirmUninstall : message de confirmation avant désinstallation du module (xHTML non autorisé, message affiché en alerte javascript)

Important
La pseudo-variable $this est une référence à votre module (ou objet), autrement dit, pour appeler une méthode ou un membre dans votre classe,
vous pouvez l’utiliser comme ceci : $this->myMethod(); / $this->myProperty;

Le mot clé parent permet quant à lui via l’opérateur de résolution de portée (::) d’appeler la méthode parente contenue dans la classe Module (rappelez-vous le mot clé extends permet à votre module d’hériter des méthodes et membres de la classe Module).

Une méthode pour la traduction : l($string)

Cette méthode permet donc de traduire du texte, par défaut le texte passé en paramètre doit-être en anglais (car cette langue ne contient pas d’accents, et l’anglais est la langue internationale ;) )

C’est grâce à l’héritage que l’on peut appeler la méthode nommée l($string) de la classe mère Module.
De cette façon $this->l(‘My Translation’);

Note
Dans le constructeur de votre module, vous devez appeler la méthode parent::__construct() avant de traduire du texte (d’utiliser la méthode l($string)) et après avoir déclaré le membre $this->name. (la méthode de traduction se sert de $this->name pour trouver les fichiers de traduction)

Une méthode pour l’installation : install()

La méthode pour l’installation est très simpliste, elle permet d’enregistrer le module, d’effectuer les actions que vous voulez et aussi d’enregistrer des hooks.
Tout se qui est dans cette méthode est exécuté lors de l’installation de votre module.

Pour l’exemple, j’ai choisi d’installer un hook, d’ajouter une variable de configuration stockée dans la base de donnée et la fameuse installation de l’onglet (que nous verrons plus tard)

public function install()
{
  if(!parent::install()
    || !$this->registerHook('leftColumn')
    || !Configuration::updateValue('MOD_TUTORIAL_IMG', 'http://julien.breux.free.fr/logo.jpg') 
    || !$this->installModuleTab('AdminTutorial', array(1=>'My Tutorial Tab', 2=>'Mon onglet tutoriel'), 2))
    return false;
  return true;
}

Pour faire bref, la méthode registerHook($hookName) permet d’enregistrer (référencer) un hook dans Prestashop. (Vue plus tard)
La méthode statique updateValue($key, $value) de la classe Configuration permet de mettre à jour une variable de configuration ou bien de créer celle-ci si elle n’existe pas :) et enfin la méthode installModuleTab($tabClass, $tabName, $idTabParent) et une méthode de ma sauce permettant d’enregistrer un ou plusieurs onglets.

Si la méthode install() renvoie false, le module n’est pas installé. (enfin en théorie…)

Une méthode pour la désinstallation : uninstall()

La méthode pour la désinstallation est toute aussi simple, la méthode deleteByName($key) de la classe Configuration permet de supprimer une variable de configuration de la base de données. La méthode uninstallModuleTab($tabClass) est aussi une méthode de ma sauce pour supprimer un onglet.
Les hooks quant à eux sont désinstallés automatiquement.

public function uninstall()
{
  if(!parent::uninstall()
    || !Configuration::deleteByName('MOD_TUTORIAL_IMG') 
    || !$this->uninstallModuleTab('AdminTutorial'))
    return false;
  return true;
}

Une méthode pour la configuration : getContent()

Liste des modules - Configurer
Cette méthode permet de configurer votre module via un lien (>> Configurer) dans la liste des modules. Elle se charge simplement de faire un echo du xHTML que vous mettrez dedans :

public function getContent()
{
  $html = '';
  if(Tools::isSubmit('submitTutorial'))
  {
    if(Validate::isUrl(Tools::getValue('tutorial_img')))
    {
      Configuration::updateValue('MOD_TUTORIAL_IMG', Tools::getValue('tutorial_img'));
      $html .= $this->displayConfirmation($this->l('Settings updated.'));
    }
    else
    {
      $html .= $this->displayError($this->l('Invalid URL.'));
    }
  }
  $tutorial_img = Configuration::get('MOD_TUTORIAL_IMG');
  $html .= '<h2>'.$this->l('Tutorial Module').'</h2>
  <form action="'.$_SERVER['REQUEST_URI'].'" method="post">
    <fieldset>
      <legend>'.$this->l('Settings').'</legend>
      <label>'.$this->l('Image URL').'</label>
      <div class="margin-form">
        <input type="text" name="tutorial_img" value="'.$tutorial_img.'" />
      </div>
      <div class="clear center">
        <p>&nbsp;</p>
        <input class="button" type="submit" name="submitTutorial" value="'.$this->l('   Save   ').'" />
      </div>
    </fieldset>
  </form>';
  return $html;
}

Tools::isSubmit($post_get_var_name) : Méthode statique outils qui renvoie true si l’élément de formulaire est envoyé.
Validate::isUrl($var) : Méthode statique validateur qui renvoie true si la variable passé est un URL.
Tools::getValue($post_get_var_name) : Méthode statique outils qui renvoie la valeur d’un élément de formulaire.
displayConfirmation($message) : Méthode qui permet d’afficher un message de succès.
displayError($message); : Méthode qui permet d’afficher un message d’erreur.
Module - Configuration

Une méthode pour le hook : hookXXX() (XXX étant le nom du hook)

Comme pour nous le hook sera accroché à leftColumn, la méthode porte donc le nom : hookleftColumn($params)

Nous reviendrons dans un autre tutoriel sur les différents types de hook existant dans Prestashop et les différents paramètres qu’ils acceptent.

Ce hook permet simplement d’afficher l’image de notre tutoriel dans la colonne de gauche grâce au fichier modèle tutorial.tpl en lui assignant une variable nommée TUTORIAL_IMG. (affin de lui donner l’url de l’image)

public function hookleftColumn($params)
{
  global $smarty;
  $smarty->assign('TUTORIAL_IMG', Configuration::get('MOD_TUTORIAL_IMG'));
  return $this->display(__FILE__, 'tutorial.tpl');
}

Hook Left
Le fichier modéle contiendra donc le code suivant :

<div class="block">
  <h4>{l s='Tutorial' mod='tutorial'}</h4>
  <div class="block_content center">
    <img src="{$TUTORIAL_IMG}" alt="{l s='Tutorial' mod='tutorial'}" />
  </div>
</div>

Vous remarquerez simplement que dans un template la traduction se fait avec la fonction {l s=’Tutorial’ mod=’tutorial’},
My Tutorial étend le texte à traduire et tutorial étend le nom du module.
De plus l’affichage d’une variable assignée s’utilise comme ceci : {$my_var} / {$myVar} / …
C’est tout pour … le hook et les templates…

Installation / Désinstallation d’un onglet

Jusqu’ici, vous pouvez maintenant faire un module qui tient la route !
Voyons maintenant comment installer un onglet. Voici ma méthode:

private function installModuleTab($tabClass, $tabName, $idTabParent)
{
  @copy(_PS_MODULE_DIR_.$this->name.'/logo.gif', _PS_IMG_DIR_.'t/'.$tabClass.'.gif');
  $tab = new Tab();
  $tab->name = $tabName;
  $tab->class_name = $tabClass;
  $tab->module = $this->name;
  $tab->id_parent = $idTabParent;
  if(!$tab->save())
    return false;
  return true;
}

Voyons maintenant comment désinstaller un onglet. Voici ma méthode: (<- copier/coller ;) )

private function uninstallModuleTab($tabClass)
{
  $idTab = Tab::getIdFromClassName($tabClass);
  if($idTab != 0)
  {
    $tab = new Tab($idTab);
    $tab->delete();
    return true;
  }
  return false;
}

Le fichier onglet

Voici le fichier onglet :
Onglet Tutoriel
Et voici son code :

<?php
include_once(PS_ADMIN_DIR.'/../classes/AdminTab.php');
class AdminTutorial extends AdminTab
{
  public function display()
  {
    echo $this->l('This is my tab ! A big big thanks to Julien Breux').'<br /><p class="center"><img src="'.Configuration::get('MOD_TUTORIAL_IMG').'" alt="-" /></p>';
  }
}
?>

La classe de votre onglet doit hériter la classe AdminTab, c’est pour ceci qu’il faut inclure cette tab (avant la fonction __autoload()).
La méthode display() permet d’afficher un contenu directement dans un onglet du backoffice de Prestashop ;)
Et c’est ce que l’exemple démontre.

Le problème avec la traduction des onglets et l’icône

Comme vous avez surement du le remarquer la traduction fonctionne très mal. C’est pour cela que je vais vous passer un tuyau!
De plus, l’icône ne fonctionne pas dans le fil d’Ariane…
Mais nous sommes entrain de palier aux problèmes avec Philippe S. (actuellement en vacances, comme moi, mais loin :) )

Pour le premier problème, il vous suffit d’utiliser ce constructeur pour votre onglet :

private $module = 'tutorial';
public function __construct()
{
  global $cookie, $_LANGADM;
  $langFile = _PS_MODULE_DIR_.$this->module.'/'.Language::getIsoById(intval($cookie->id_lang)).'.php';
  if(file_exists($langFile))
  {
    require_once $langFile;
    foreach($_MODULE as $key=>$value)
      if(substr(strip_tags($key), 0, 5) == 'Admin')
        $_LANGADM[str_replace('_', '', strip_tags($key))] = $value;
  }
  parent::__construct();
}

Pour le second problème, voici une ligne à ajouter dans la méthode installModuleTab()

@copy(_PS_MODULE_DIR_.$this->name.'/logo.gif', _PS_IMG_DIR_.'t/'.$tabClass.'.gif');

Attention, n’oubliez pas de modifier le membre module.

Conclusion

Vous voici en possession d’un module complet qui permet juste d’afficher une image dans un onglet mais aussi dans la colonne de gauche de votre site.
J’espère que vous aurez pris autant de plaisir à consulter ce tutoriel que moi à le rédigé.
N’hésitez pas à poster au moins un commentaire par visite, ça fait toujours plaisir. (Même pour les développeurs les plus « perso » qui se disent : « Pfff je l’savais ça ! »)
A l’occasion, n’hésitez pas à mettre un lien vers mon site… ou me demandez du développement, je suis pas très cher et travail bien :)
Merci à Anne-So pour certaines corrections

Temps de réalisation du tutoriel: 4h (je vais me coucher !)

Vous allez gagner de l’argent avec mon tutoriel, faites moi en gagner :)

Téléchargement

Module tutorial

Cette entrée a été publiée dans Tutoriels Prestashop. Vous pouvez la mettre en favoris avec ce permalien.

69 réponses à Tutoriel Prestashop – Créer un module avec onglet

  1. Julien dit :

    Merci pour le tutoriel, je cherchais comment intégrer un tabs, avec un module, et j’ai trouvé la réponse ici.

  2. maniT4c dit :

    Bonjour et merci pour ce super tuto qui m’a permis de réaliser mon premier module sur prestashop.

    Je rencontre par contre un problème concernant la traduction, en effet malgré l’utilisation du second constructeur proposé (pour justement régler ce prob de trad). Mes textes ne sont toujours pas traduit.

    Auriez-vous des pistes à creuser pour régler ce problème ? Merci d’avance

  3. maniT4c dit :

    Autant pour moi, j’ai finalement réussi à intégrer ma traduction. Je n’avais pas copier le constructeur au bon endroit (je l’avais mis dans mon module et pas dans AdmonMonModule).

    Encore merci pour le tuto !

  4. Julien dit :

    Il suffit de modifier le $idTabClient (voir la table tabs de la base de données)

  5. Julien dit :

    Il est impossible de modifier ce comportement sans modifier le cœur de Prestashop.

  6. matthieu dit :

    Bonjour,

    tres bon tuto. juste une question pour l’onglet : on doit creer un autre fichier ou inclure directement la classe dans le fichier coeur ?

    deuxio, je vais peut etre faire appel à un pro de prestashop pour creer un template perso (avec charte graphique et blocs modifiés) . quels sont vos tarifs ?

    enfin, je cherche à rendre privé quelques pages cms de la boutique : est ce qu’il y a un moyen simple sur prestashop (en faisant ça avec les utilisteurs enregistres en back ?)

    tenez moi au courant meme par tel pour les tarifs/ dispo pour le dev
    cdlt

    Matthieu CHOLIN
    06 26 34 13 35

  7. Sylvain dit :

    Super ! tutoriel génial ! Merci !

  8. ndav92 dit :

    Salut julien,
    sais tu comment faire re-apparaitre
    dans dans le BO la liste des modules je n’ai que la position des modules.
    Et aussi dans le BO/paiements , plus de liste de modules.
    Je n’ai pas fais de modif , j’ai vidé les cookies.
    Je me suis delogué et relogué toujours pareil.
    cdt
    David

  9. lolo dit :

    bonjour, merci tout d’abord pour cet excellent tuto
    je suis newbie sur prestashop et je comprend pas bien où se situe le fichier onglet ?
    serait ce le AdminTutorial.php?
    ce doit être évident pour tous…sauf pour moi
    merci encore

  10. Damien dit :

    De mon retour de congé, j’ai le passage de notre site à prestashop qui m’attend, avec quelques modules monstrueux en vue… Merci de m’avoir fait découvrir les bases!

  11. dev21 dit :

    Merci pour le tuto,
    j’ai un problème de mon coté, quand je veux utiliser des classes (Order par exemple) j’ai une erreur qui m’indique que la classe n’est pas accessible.
    J’ai pourtant bien etendu ma classe (… extends AdminTab)

    merci pour ton aide

  12. dev21 dit :

    désolé,
    le problème vient du fait que j’utilise la librairie PHPEXCEL qui comporte un autoload:
    spl_autoload_register(array(‘PHPExcel_Autoloader’, ‘Load’));
    et qui rentre en conflit avec l’autoload de prestashop …

    Comment faire cohabiter ces autoload svp ?
    merci beaucoup

  13. Franck dit :

    Bonjour
    Merci pour ce tuto, pour info si comme moi vous faite quelques essais avant de réussir et que votre onglet accumule les liens. Pour les effacer aller dans la base de données de Presta shop et effacez vos liens, table ps_tab et ps_lang. Attention n’effacez que vos infos.
    Franck

  14. Georges dit :

    Bonjour
    Merci SUPER tuto !

    Ces informations sont-elles toujours valable pour la version 1.4 de PS ?

    Ou que faut-il changer ?

    Georges

  15. Julien dit :

    Ces informations sont toujours valables mais un nouveau tuto est en cours d’écriture ;)

  16. Georges dit :

    Bonjour
    merci Julien pour cette information, je vais donc attendre le nouveau tuto pour réaliser mon petit module ;-)

  17. jean dit :

    Bonjour,

    tout d’abord merci pour ce tuto qui m’a permis de mieux comprendre le fonctionnement de prestashop et de créer mon premier module…

    Dans le haut du tuto il est évoqué l’architecture idéale d’un module et j’aimerai la respecter. J’ai donc une petite question (sans doute évidente), où et comment dois-je faire l’include de mon fichier css placé dans le dossier/css?

    Merci d’avance

  18. Julien dit :

    Bonjour,

    Héhé, c’est en cours dans le nouveau tutoriel justement ;)

    Cordialement

  19. Yorky dit :

    Tutoriel intéressant et bien fait. Merci!

Laisser un commentaire

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

*

Vous pouvez utiliser ces balises et attributs HTML : <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="" highlight="">