Surcharger une classe native magento2 (Model, Block, Helper, Action...)

Parfois, on veut modifier le comportement natif de magento2, on peu être tenté d'éditer directement les fichiers du module app/code/Magento mais il ne faut ABSOLUMENT PAS le faire car vous ne pourrez plus mettre à jour votre plateforme vers les nouvelles versions de magento2. Comment modifier une classe magento2 proprement alors ?

Réecrire un model natif magento2

Dans cette premiere partie du tutoriel, nous allons voir comment réecrire une classe du Model, plus particuliérement, la classe Product.

Etape 1: Définir la classe à utiliser dans l'injecteur de dépendances

Editez donc votre fichier de configuration d'injections de dépendances /app/code/Pfay/Contacts/etc/di.xml et rajouter une balise "preference" pour dire à magento "prends la classe Pfay\Contacts\Model\Product à la place de Magento\Catalog\Model\Product" :

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    ...
    <preference for="Magento\Catalog\Model\Product" type="Pfay\Contacts\Model\Product" />
</config>

Etape 2: Créer la classe Reécrite

Une fois qu'on a définit à magento de prendre cette nouvelle classe, il faut la créer. Créez donc le fichier /app/code/Pfay/Contacts/Model/Product.php :

<?php
namespace Pfay\Contacts\Model;
use Magento\Cron\Exception;
use Magento\Framework\Model\AbstractModel;
class Product extends \Magento\Catalog\Model\Product
{
    /**
     * Get product name
     *
     * @return string
     * @codeCoverageIgnoreStart
     */
    public function getName()
    {
        return parent::getName().' motherfucker !!';
    }

}

Ici on déclare une nouvelle classe Product comme d'habitude quand on crée un nouveau model. Ensuite on étends la classe native \Magento\Catalog\Model\Product. Afin de ne pas perdre le comportement natif de la classe et de pouvoir surcharger uniquement ce qu'on a besoin. On va surcharger la fonction getName() du model natif de magento, pour cela on récupére le nom du produit (via la fonction native présente dans la classe parente) puis on rajoute "motherfucker !!" à la fin. Allez ensuite sur une fiche produit et vous devriez voir s'afficher comme nom du produit "mother fuckers !!" à la fin. Cela fonctionne donc parfaitement bien :)

Réecrire un Block magento2

Pour réecrire un block c'est la même chose, on va créer notre "preference" dans le di.xml et on va créer la classe concernée, ici on va essayer de surcharger le block product view de magento (/app/code/Magento/Catalog/Block/Product/View.php). Donc on commence par créer notre "preference", éditez le fichier /app/code/Pfay/Contacts/etc/di.xml

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    
    ...
    
    <preference for="Magento\Catalog\Block\Product\View" type="Pfay\Contacts\Block\Product\View" />
    
</config>

Puis créer la classe :

<?php
namespace Pfay\Contacts\Block\Product;

class View extends \Magento\Catalog\Block\Product\View
{
    /**
     * Retrieve current product model
     *
     * @return \Magento\Catalog\Model\Product
     */
    public function getProduct()
    {
       die('test rewrite block product view');
    }
}

Si vous rechargez votre page, vous devriez voir une page blanche avec "test rewrite block product view" (résultat du die() ici présent).

Réecrire un Helper magento2

Pour réecrire un helper c'est la même chose, on va encore créer notre "preference" dans le di.xml et on va encore créer la classe du Helper, ici on va réecrore le helper catalog data de magento (/app/code/Magento/Catalog/Helper/Data.php). Donc comme d'hab maintenant, éditez le fichier /app/code/Pfay/Contacts/etc/di.xml pour créer la preference :

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    
    ...
    
    <preference for="Magento\Catalog\Helper\Data" type="Pfay\Contacts\Helper\Data" />
    
</config>

Ensuite on créer notre classe /app/code/Pfay/Contacts/Helper/Data.php qui rewrite la méthode getProduct() pour y placer un die().

<?php
namespace Pfay\Contacts\Helper;

class Data extends \Magento\Catalog\Helper\Data
{
    public function getProduct()
    {
        die('rewrite helper');
        return $this->_coreRegistry->registry('current_product');
    }
}

Si vous rechargez votre page produit, vous devriez voir une page blanche avec "rewrite helper" (résultat du die() ici présent).

Réecrire une Action magento2

Vous voulez changer le fonctionnement natif d'une action magento2, comme par exemple l'affichage du panier pour y faire et vous pourriez être tenté de modifier directement l'action correspondante dans le dossier app/code/Magento/ mais comme vous vous en doutez...ce n'est pas une bonne idée. En effet, le régle N°1 du magento club: on ne parles pas du magento club ON NE MODIFIE JAMAIS LE CORE DE MAGENTO (app/code/Magento).
Donc maintenant que c'est dit, on va pouvoir voir modiifer notre di.xml et ajouter la préférence...Comme pour les autres rewrites :)
Donc comme d'hab maintenant, éditez le fichier /app/code/Pfay/Contacts/etc/di.xml pour créer la preference :

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    
    ...
    
    <preference for="Magento\Checkout\Controller\Cart\Index" type="Pfay\Contacts\Controller\Cart\Index" />
    
</config>

Puis on créer notre classe \Pfay\Contacts\Controller\Cart\Index comme ceci :

<?php
namespace Pfay\Contacts\Controller\Cart;

class Index extends \Magento\Checkout\Controller\Cart\Index
{
    public function execute()
    {
      die('test cart');
    }
}

et si vous allez sur votre panier, vous voyez une page blanche "test cart". Donc ca marche ;)
Voilà c'est la fin de ce tutoriel sur les rewrites magento, vous avez vu comment réecrire / surcharger un helper, un block, un model et une action sous magento2.
Si ce la ne fonctionne pas chez vous, vous pouvez Télécharger le code en bas de ce tutoriel pour le comparer avec le votre.
Documents disponibles pour cet article :
Questions sur cette leçon
Pas de questions pour cette leçon. Soyez le premier !

Vous devez etre connecté pour demander de l'aide sur une leçon.