Plonger dans le développement PrestaShop

Table des matières

/*<![CDATA[*/ div.rbtoc1597316603924 {padding: 0px;} div.rbtoc1597316603924 ul {list-style: disc;margin-left: 0px;} div.rbtoc1597316603924 li {margin-left: 0px;padding-left: 0px;} /*]]>*/

Plonger dans le développement PrestaShop

Accéder à la base de données

La structure de la base de données

Les tables de la base de données de PrestaShop sont nommées avec le préfixe ps_. Notez que cet aspect peut être personnalisé durant l'installation initiale.

Tous les noms de table sont en lettres caractères minuscules, et les mots sont séparés par le caractère souligne ("_").

Quand une table crée un lien entre deux entités, les noms des deux entités sont mentionnés dans le nom de la table. Par exemple, ps_category_product fait le lien entre les produits et leur catégorie.

Quelques détails à noter :

  • Utilisez le champ id_lang pour stocker la langue associée à un enregistrement.

  • Utilisez le champ id_shop pour stocker la boutique associée à un enregistrement.

  • Les tables qui contiennent des traductions doivent avoir un nom se terminant par le suffixe _lang. Par exemple, ps_product_lang contient toutes les traductions de la table ps_product.

  • Les tables qui contiennent des enregistrements liés à une boutique spécifique doivent avoir un nom se terminant par le suffixe _shop. Par exemple, ps_category_shop contient la position de chaque catégorie en fonction de la boutique.

La classe ObjectModel

C'est là l'objet principal du modèle objet de PrestaShop. Il peut être surchargé en prenant quelques précautions.

C'est une classe de type Active Record (http://fr.wikipedia.org/wiki/Active_record_%28patron_de_conception%29). Les attributs d'une table ou d'une vue sont encapsulés dans une classe. Ainsi l'objet, instance de la classe, est lié à un enregistrement de la base. Après l'instanciation d'un objet, un nouvel enregistrement est ajouté à la base au moment de l'écriture. Chaque objet récupère ses données depuis la base; quand un objet est mis à jour, l'enregistrement auquel il est lié l'est aussi. La classe implémente des accesseurs pour chaque attribut.

Définir le modèle

Vous devez utiliser la variable statique $definition afin de définir le modèle.

Par exemple :

/**
* Exemple du modèle CMS (CMSCore) 
*/
public static $definition = array(
  'table' => 'cms',
  'primary' => 'id_cms',
  'multilang' => true,
  'fields' => array(
    'id_cms_category'  => array('type' => self::TYPE_INT, 'validate' => 'isUnsignedInt'),
    'position'         => array('type' => self::TYPE_INT),
    'active'           => array('type' => self::TYPE_BOOL),
    // Lang fields
    'meta_description' => 
        array('type' => self::TYPE_STRING, 'lang' => true, 'validate' => 'isGenericName', 'size' => 255),
    'meta_keywords'    => 
        array('type' => self::TYPE_STRING, 'lang' => true, 'validate' => 'isGenericName', 'size' => 255),
    'meta_title'       => 
        array('type' => self::TYPE_STRING, 'lang' => true, 'validate' => 'isGenericName', 'required' => true, 'size' => 128),
    'link_rewrite'     =>
        array('type' => self::TYPE_STRING, 'lang' => true, 'validate' => 'isLinkRewrite', 'required' => true, 'size' => 128),
    'content'          => 
        array('type' => self::TYPE_HTML,   'lang' => true, 'validate' => 'isString', 'size' => 3999999999999),
  ),
);

Un modèle pour de nombreuses boutiques et langues

Pour disposer d'un objet dans plusieurs langues :

'multilang' => true

Pour disposer d'un objet dépendant de la boutique en cours :

'multishop' => true

Pour disposer d'un d'objet dépendant de la boutique en cours, et dans plusieurs langues :

'multilang_shop' => true

Les principales méthodes

La moindre surcharge de ces classes peut avoir une influence sur la manière dont les autres classes et méthodes se comportent. À utiliser avec précaution.

Nom et paramètres de la méthode

Description

__construct($id = NULL, $id_lang = NULL)

Construit l'objet.

add($autodate = true, $nullValues = false)

Enregistre l'objet en cours dans la base de données (ajout ou mise à jour).

delete()

Supprime l'objet en cours de la base de données.

deleteSelection($selection)

Supprime plusieurs objets de la base de données.

getFields()

Prépare les champs pour les classes ObjectModel (ajout, mise à jour).

getValidationRules($className = _CLASS_)

Renvoie les règles de validation objet (validité des champs).

save($nullValues = false, $autodate = true)

Enregistre l'objet en cours dans la base de données (ajout ou mise à jour).

toggleStatus()

Modifie l'état de l'objet dans la base de données.

update($nullValues = false)

Met à jour l'objet en cours dans la base de données.

validateFields($die = true, $errorReturn = false)

Vérifie la validité des champs avant une interaction avec la base de données.

La classe DBQuery

La classe DBQuery permet de construire des requêtes, et donc vous aide à mettre en place vos requêtes SQL. Par exemple :

$sql = new DbQuery();
$sql->select('*');
$sql->from('cms', 'c');
$sql->innerJoin('cms_lang', 'l', 'c.id_cms = l.id_cms AND l.id_lang = '.(int)$id_lang);
$sql->where('c.active = 1');
$sql->orderBy('position');
return Db::getInstance()->executeS($sql);

Voici certaines méthodes de cette classe :

Method name and parameters

Description

__toString()

Générer et récupérer la requête.

string build()

Générer et récupérer la requête.

from(string $table, mixed $alias = null)

Régler la table de la clause FROM.

groupBy(string $fields)

Ajouter une restriction GROUP BY.

having(string $restriction)

Ajouter une restriction sur la clause HAVING (les restrictions seront séparées par une déclaration AND).

innerJoin(string $table, string $alias = null, string $on = null)

Ajouter une clause INNER JOIN, par exemple $this->innerJoin('product p ON ...')

join(string $join)

Ajouter une clause JOIN, par exemple $this->join('RIGHT JOIN'._DB_PREFIX_.'product p ON ...');

leftJoin(string $table, string $alias = null, string $on = null)

Ajouter une clause LEFT JOIN

leftOuterJoin(string $table, string $alias = null, string $on = null)

Ajouter une clause LEFT OUTER JOIN.

limit(string $limit, mixed $offset = 0)

Limiter les résultats de la requête.

naturalJoin(string $table, string $alias = null)

Ajouter une clause NATURAL JOIN.

orderBy(string $fields)

Ajouter une restriction ORDER B.

select(string $fields)

Ajouter des champs à la sélection de la requête.

where(string $restriction)

Ajouter une restriction dans la clause WHERE (les restrictions seront séparées par une déclaration AND).

Le Répartiteur (dispatcher)

Le Répartiteur est l'une des principales nouveautés techniques de la version 1.5. Il gère les redirections d'URL. Au lieu d'utiliser une multitude de fichiers à la racine du dossier de PrestaShop, comme product.php, order.php ou category.php, un seul est utilisé : index.php. Partant de là, les adresses internes auront cet aspect : index.php?controller=category, index.php?controller=product, etc.

Par ailleurs, le Répartiteur a été conçu pour prendre en compte la réécriture d'URL. Ainsi, quand la réécriture d'URL est désactivée, PrestaShop utilisera la forme d'adresse suivante :

http://myprestashop.com/index.php?controller=category&id_category=3&id_lang=1
http://myprestashop.com/index.php?controller=product&id_product=1&id_lang=1

...et lorsque la réécriture d'URL est activée (aussi appelée "URL simplifiées"), le Répartiteur de PrestaShop sera capable d'utiliser la forme suivante :

http://myprestashop.com/en/3-music-ipods
http://myprestashop.com/en/1-ipod-nano.html

Ce système offre plusieurs avantages :

  • Il est plus facile d'ajouter un contrôleur.

  • Vous pouvez utiliser des routes personnalisées pour vos URL simplifiées (ce qui est bien mieux pour le référencement !).

  • Il n'y a qu'un point d'entrée dans le logiciel, ce qui améliore sa fiabilité, et facilite les développements à venir.

Le Répartiteur utilise trois nouvelles classes abstraites : Controller, FrontController et AdminController (ces deux dernières héritant de la première).

De nouvelles routes peuvent être créées en surchargeant la méthode loadRoutes(). L'administrateur de la boutique peut changer l'URL d'un contrôleur en passant par la page de préférences "SEO & URLs".

Contrôleurs

Dans l'architecture MVC, un contrôleur gère la synchronisation des évènements entre la Vue et le Modèle, et les garde à jour. Il reçoit les évènements de tous les utilisateurs, et déclenche les actions à accomplir. Si une action a besoin de voir des données modifiées, le contrôleur "demandera" au Modèle de modifier ces données, et en retour le Modèle notifiera la Vue que les données ont été changées, afin que la Vue puisse se mettre à jour.

Tous les contrôleurs de PrestaShop sont en fait des surcharges de la classe Controller par le biais d'une autre classe qui en hérite, comme AdminController, ModuleAdminController, FrontController ou ModuleFrontController.

La classe FrontController

Quelques-unes des propriétés de la classe :

Propriété

Description

$template

Nom du modèle pour le contenu de la page.

$css_files

Tableau contenant une liste des fichiers CSS.

$js_files

Tableau contenant une liste des fichiers JavaScript.

$errors

Tableau des erreurs qui ont survenu.

$guestAllowed

Indique si le client qui s'est déconnecté peut accéder à cette page.

$initialized

Indique si la fonction init() a été appelée.

$iso

Le code ISO de la langue actuellement sélectionnée.

$n

Le nombre d'éléments par page.

$orderBy

Le champ à utiliser pour le tri.

$orderWay

Indique si le tri doit être ascendant ou descendant ("ASC" ou "DESC").

$p

Le numéro de la page actuelle.

$ajax

Si le paramètre ajax est détecté dans la requête, cette variable sera à true.

Ordre d'exécution des fonctions du contrôleur

  1. __contruct() : configure toutes les variables des membres du contrôleur.

  2. init() : initialise le contrôleur.

  3. setMedia() ou setMobileMedia() : ajoute tous les détails liés à JavaScript et aux CSS à la page, afin qu'ils puissent être combinés, compressés et mis en cache (voire l'outil CCC de PrestaShop, dans la page "Performances" du back-office).

  4. postProcess() : gère ajaxProcess.

  5. initHeader() : appelé avant initContent().

  6. initContent() : initialise le contenu.

  7. initFooter() : appelé après initContent().

  8. display() ou displayAjax() : affiche le contenu.

Contrôleurs existants

Nom de fichier du contrôleur

Description

AddressController.php

Utilisé par address.php pour modifier l'adresse d'un client.

AddressesController.php

Utilisé par addresses.php pour récupérer les adresses d'un client.

AuthController.php

Utilisé par authentication.php pour la connexion d'un client.

BestSalesController.php

Utilisé par best-sales.php pour récupérer les meilleures ventes.

CartController.php

Utilisé par cart.php pour gérer le panier du client.

CategoryController

Utilisé par category.php pour récupérer les catégories de produits.

CMSController.php

Utilisé par cms.php pour récupérer une page CMS.

CompareController.php

Utilisé par products-comparison.php pour comparer les produits.

ContactController.php

Utilisé par contact-form.php pour envoyer des messages.

DiscountController.php

Utilisé par discount.php pour récupérer les réductions d'un client.

GuestTrackingController.php

Utilisé par guest-tracking.php pour gérer les commandes de clients non-inscrits (guest).

HistoryController.php

Utilisé par history.php pour récupérer les commandes d'un client.

IdentityController.php

Utilisé par identity.php pour récupérer les informations personnelles d'un client.

IndexController.php

Utilisé par index.php pour afficher la page d'accueil.

ManufacturerController.php

Utilisé par manufacturer.php pour récupérer les fabricants.

MyAccountController.php

Utilisé par my-account.php pour gérer le compte d'un client.

NewProductsController.php

Utilisé par new-products.php pour récupérer les nouveaux produits.

OrderConfirmationController.php

Utilisé par order-confirmation.php pour confirmer une commande.

OrderController.php

Utilisé par order.php pour gérer la commande en cinq étapes.

OrderDetailController.php

Utilisé par order-detail.php pour récupérer la commande d'un utilisateur.

OrderFollowController.php

Utilisé par order-follow.php pour récupérer les retours d'un client.

OrderOpcController.php

Utilisé par order-opc.php pour gérer la commande en une étape.

OrderReturnController.php

Utilisé par order-return.php pour récupérer un retour marchandise.

OrderSlipController.php

Utilisé par order-slip.php pour récupérer les bons d'achat d'un client.

PageNotFoundController.php

Utilisé par 404.php pour gérer la page "page introuvable".

ParentOrderController.php

Gère le code de commande partagé.

PasswordController.php

Utilisé par password.php pour mettre à zéro un mot de passe perdu.

PricesDropController.php

Utilisé par prices-drop.php pour obtenir les produits ayant une réduction.

ProductController.php

Utilisé par product.php pour récupérer un produit.

SearchController.php

Utilisé par search.php pour obtenir des résultats de recherche.

SitemapController.php

Utilisé par sitemap.php pour récupérer le sitemap.

StoresController.php

Utilisé par stores.php pour récupérer les informations de la boutique.

StoresController.php

Utilisé par supplier.php pour récupérer les fournisseurs.

Surcharger un contrôleur

Grâce à l'héritage objet, vous pouvez modifier le comportement d'un contrôleur, ou en ajouter de nouveaux.

Les contrôleurs de PrestaShop sont tous stockés dans le dossier /controllers, et utilisent le suffixe "Core".

Par exemple, lorsque vous travaillez avec le contrôleur de catégorie :

  • Fichier : /controllers/CategoryController.php

  • Classe : CategoryControllerCore

Si vous souhaitez modifier un contrôleur, vous devez d'abord créer une nouvelle classe sans le suffixe "Core", et placer ce fichier dans le dossier /override/controllers.

Par exemple, lorsque vous surchargez le contrôleur de catégorie :

  • Fichier : /override/controllers/front/CategoryController.php

  • Classe : CategoryController

Vues

PrestaShop utilise le moteur de template Smarty pour générer ses vues : http://www.smarty.net/

Les vues sont stockées dans des fichiers .tpl.

Le nom d'une vue est généralement le même que le nom du code qui l'utilise. Par exemple, 404.php utilise 404.tpl.

Surcharger une vue

Il n'y a pas de concept d'héritage dans les vues, donc pas moyen de surcharger une vue.

Si vous souhaitez modifier un vue, vous devez réécrire son fichier template, et le placer dans le dossier du thème.

Cookies

PrestaShop utilise des cookies cryptés pour stocker toutes ses informations de session, pour les visiteurs/clients comme pour les employés/administrateurs.

La classe Cookie (/classes/Cookie.php) est utilisée pour lire et écrire les cookies.

Pour accéder aux cookies depuis le code de PrestaShop, vous pouvez faire comme suit :

$this->context->cookie;

Toutes les informations stockées dans le cookie sont disponibles par le biais de ce code :

$this->context->cookie->variable;

Si vous avez besoin d'accéder au cookie de PrestaShop depuis du code en dehors de PrestaShop, vous pouvez utiliser ce code :

include_once('chemin_vers_prestashop/config/config.inc.php');
include_once('chemin_vers_prestashop/config/settings.inc.php');
include_once('chemin_vers_prestashop/classes/Cookie.php');
$cookie = new Cookie('ps'); // Utilisez "psAdmin" pour accéder au cookie d'un employé.

Données stockées dans le cookie d'un visiteur/client

Token

Description

date_add

L'heure et la date de création du cookie (au format YYYY-MM-DD HH:MM:SS).

id_lang

L'identifiant de la langue sélectionnée.

id_currency

L'identifiant de la devise sélectionnée.

last_visited_category

L'identifiant de la dernière catégorie de produits visitée.

ajax_blockcart_display

Indique si le block panier est ouvert ou fermé.

viewed

Les identifiants des derniers produits vus, séparés par une virgule.

id_wishlist

L'identifiant de la liste d'idées cadeaux actuellement affichée dans le bloc.

checkedTOS

Indique si la case "Conditions générales de vente" a bien été cochée (oui : 1 ; non : 0).

id_guest

L'identifiant invité du visiteur non connecté.

id_connections

L'identifiant de connexion de la session en cours du visiteur.

id_customer

L'identifiant du visiteur une fois connecté.

customer_lastname

Le nom de famille du client.

customer_firstname

Le prénom du client.

logged

Indique si le client est connecté ou non.

passwd

Le hash MD5 de _COOKIE_KEY_ dans config/settings.inc.php, et le mot de passe utilisé par le client pour se connecter.

email

L'adresse e-mail que le client a utilisé pour se connecter.

id_cart

L'identifiant du panier actuellement affiché dans le bloc Panier.

checksum

Le checksum Blowfish utilisé pour déterminer si le cookie a été modifié par un tiers. Si ce checksum ne correspond pas, le client sera déconnecté et son cookie effacé.

Données stockées dans le cookie d'un employé/administrateur

Token

Description

date_add

L'heure et la date de création du cookie (au format YYYY-MM-DD HH:MM:SS).

id_lang

L'identifiant de la langue sélectionnée.

id_employee

L'identifiant de l'employé.

lastname

Le nom de famille de l'employé.

firstname

Le prénom de l'employé.

email

L'adresse e-mail que l'employé a utilisé pour se connecter.

profile

L'identifiant du profil qui détermine les menus auxquels l'employé à accès.

passwd

Le hash MD5 de _COOKIE_KEY_ dans config/settings.inc.php, et le mot de passe utilisé par l'employé pour se connecter.

checksum

Le checksum Blowfish utilisé pour déterminer si le cookie a été modifié par un tiers. Si ce checksum ne correspond pas, le client sera déconnecté et son cookie effacé.

Les hooks

Les hooks sont une manière d'associer du code à des évènements PrestaShop spécifiques.

La plupart du temps, ils sont utilisés pour insérer du contenu dans une page.

Par exemple, la page d'accueil du thème par défaut de PrestaShop dispose des hooks suivants :

Hook name

Description

displayHeader

Affiche le contenu dans l'en-tête de la page.

displayTop

Affiche le contenu dans la zone supérieure de la page.

displayLeftColumn

Affiche le contenu dans la colonne latérale gauche de la page.

displayHome

Affiche le contenu dans la zone centrale de la page.

displayRightColumn

Affiche le contenu dans la colonne latérale droite de la page.

displayFooter

Affiche le contenu dans le pied de page de la page.

Les hooks peuvent également être utilisés pour lancer des actions spécifiques en fonction des circonstances (ex. : envoyer un e-mail au client).

Vous pouvez obtenir une liste complète des hooks disponibles dans PrestaShop 1.5 en lisant le chapitre "Les hooks de PrestaShop 1.5" de ce Guide du Développeur.

Utiliser les hooks

...au sein d'un contrôleur

Un hook peut facilement s'appeler depuis un contrôleur : vous devez simplement utiliser son nom dans la méthode hookExec() : Module::hookExec('NomDuHook');

Par exemple :

$this->context->smarty->assign('HOOK_LEFT_COLUMN', Module::hookExec('leftColumn'));

...au sein d'un module

Pour associer votre code à un hook, vous devez créer une méthode publique, commençant par le mot-clé "hook" suivi, au choix, de "display" ou "action", et le nom du hook que vous souhaitez utiliser.

Cette méthode doit ne recevoir qu'un argument : un tableau des informations contextuelles envoyées au hook.

public function hookDisplayNomDuHook($params)
{
    // Votre code.
}

Pour que votre module réponde à l'appel du hook, ce hook doit être enregistré dans PrestaShop. L'enregistrement de hook se fait avec la méthode registerHook(). L'enregistrement se fait généralement pendant l'installation du module.

public function install()
{
    return parent::install() && $this->registerHook('NomDuHook');
}

Créer votre propre hook

Vous pouvez créer de nouveaux hooks pour PrestaShop en ajoutant un enregistrement de hook comme vu précédemment. Il n'est plus nécessaire de réaliser une insertion en base de données comme pour les versions précédentes.

Last updated