DI et extension d'un bloc sur Magento 2


15

Je semble avoir du mal à saisir l'injection de dépendance Magento 2 avec des blocs, chaque fois que j'essaie d'étendre un bloc qui n'est pas \ Magento \ Framework \ View \ Element \ Template, je me retrouve avec des erreurs.

Je veux créer un bloc qui étend la classe de blocs très basique de Magento \ Theme \ Block \ Html \ Header \ Logo - tout fonctionne bien jusqu'à ce que j'essaie l'injection de dépendance dans la méthode de construction:

<?php

namespace Creare\Test\Block\Header;

class Logo extends \Magento\Theme\Block\Html\Header\Logo
{

    protected $_creareHelper;

    public function __construct(
        \Magento\Framework\View\Element\Template\Context $context,
        \Creare\Seo\Helper\Data $creareHelper,
        array $data = []
    )
    {
        $this->_creareHelper = $creareHelper;
        parent::__construct($context, $data);
    }
}

Dès que j'essaie d'injecter ma classe d'assistance (ou toute autre chose d'ailleurs, j'obtiens une trace de pile commençant par l'erreur suivante:

Recoverable Error: Argument 2 passed to Magento\Theme\Block\Html\Header\Logo::__construct() must be an instance of Magento\MediaStorage\Helper\File\Storage\Database, array given, called in /Users/adammoss/PhpstormProjects/Magento2/app/code/Creare/Test/Block/Header/Logo.php on line 17 and defined in /Users/adammoss/PhpstormProjects/Magento2/app/code/Magento/Theme/Block/Html/Header/Logo.php on line 33

Si j'ajoute les mêmes dépendances à ma __construct que le fichier que j'étends, cela fonctionne, mais c'est sûrement une façon à l'envers de faire les choses car le point d'héritage de classe est que j'absorbe toutes les méthodes et propriétés du parent?

Je pense que j'ai juste besoin d'une explication de base 101 de quelqu'un sur l'extension des cours et l'utilisation de DI avec Magento 2. Toute aide très appréciée!


"c'est sûrement une façon de faire les choses à l'envers" .
James

Réponses:


19

La classe que vous essayez d'étendre a ce constructeur:

public function __construct(
    \Magento\Framework\View\Element\Template\Context $context,
    \Magento\MediaStorage\Helper\File\Storage\Database $fileStorageHelper,
    array $data = []
) {
    $this->_fileStorageHelper = $fileStorageHelper;
    parent::__construct($context, $data);
}

vous devez donc faire ressembler votre constructeur à ceci

public function __construct(
    \Magento\Framework\View\Element\Template\Context $context,
    \Magento\MediaStorage\Helper\File\Storage\Database $fileStorageHelper,
    \Creare\Seo\Helper\Data $creareHelper,
    array $data = []
)
{
    $this->_creareHelper = $creareHelper;
    parent::__construct($context, $fileStorageHelper, $data);
}

Conclusion ...
Dans vos classes enfants, vous devez spécifier tous les paramètres du constructeur de classe parent ainsi que vos nouveaux paramètres. Je ne pense pas que l'ordre soit important et je ne sais pas quelle est la meilleure pratique.
Ensuite, dans le constructeur, vous affectez vos nouveaux objets injectés aux variables membres et appelez le constructeur parent avec le même nombre de paramètres qu'il requiert.


2
Cela a du sens merci pour votre réponse. Je suppose que j'espérais juste que c'était plus élégant que ça.
Adam Moss

L'ordre des arguments @Marius doit être le même que celui des arguments de la méthode parent __construct, vos arguments personnalisés doivent passer à la fin.
Chirag Dodia

@chiragdodia Pourquoi? Je ne pense pas. Tout ce que j'ai construit jusqu'à présent sur M2, j'ai construit en utilisant les arguments de construction personnalisés ajoutés au hasard. Et ça a marché. la seule contrainte est que les arguments avec une valeur par défaut durent en dernier.
Marius

@Marius oui, cela fonctionne dans certains cas, mais dans mon cas, lorsque j'ai étendu \ Magento \ Catalog \ Block \ Product \ View, cela ne fonctionne pas, j'ai besoin de faire le même ordre d'arguments que dans le constructeur parent et d'ajouter enfin des arguments personnalisés. Jetez un oeil à mon code ici magento.stackexchange.com/questions/95697/…
chirag dodia

Cela ne fonctionne pas pour moi lorsque j'ai essayé de remplacer \ Magento \ Customer \ Block \ Form \ Register Block
DEEP JOSHI
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.