Ajout d'une nouvelle méthode à une classe abstraite dans Magento 2

16

Comme ce fil a dit: Remplacer la classe abstraite dans Magento 2 dans Magento 1 ,

Je peux simplement créer une nouvelle classe complète. Dans Magento 2, nous devons utiliser des plugins, mais les plugins ne me permettent que de modifier les méthodes existantes. Que dois-je faire si je veux ajouter une nouvelle méthode?

Exemple:

Cette classe vendor/magento/module-ui/Component/AbstractComponent.php, a un tableau de composants $components:, il n'y a pas de fonction pour annuler / supprimer des éléments pour ce tableau. Alors, comment puis-je créer cette fonction?

Matias
la source

Réponses:

0

Je ne vois pas comment vous pouvez le faire sans remplacer complètement la classe. Dans le cas de votre exemple, vous pouvez désactiver des composants individuels en définissant l'élément "désactivé" sur l'argument "données" dans le XML. Par exemple:

<?xml version="1.0" encoding="UTF-8"?>

<form xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd">
    <fieldset name="general">
        <field name="title">
            <argument name="data" xsi:type="array">
                <item name="disabled" xsi:type="boolean">true</item>
            </argument>
        </field>
    </fieldset>
</form>

Cela supprime effectivement le «titre» du $components tableau.

Cela est dû à la createChildComponentméthode de la Magento\Framework\View\Element\UiComponentFactoryclasse:

 protected function createChildComponent(
        array $bundleComponents,
        ContextInterface $renderContext,
        $identifier
    ) {
        list($className, $arguments) = $this->argumentsResolver($identifier, $bundleComponents);
        if (isset($arguments['data']['disabled']) && (int)$arguments['data']['disabled']) {
            return null;
        }
        $components = [];
        foreach ($bundleComponents['children'] as $childrenIdentifier => $childrenData) {
            $children = $this->createChildComponent(
                $childrenData,
                $renderContext,
                $childrenIdentifier
            );
            $components[$childrenIdentifier] = $children;
        }
        $components = array_filter($components);
        $arguments['components'] = $components;
        if (!isset($arguments['context'])) {
            $arguments['context'] = $renderContext;
        }

        return $this->objectManager->create($className, $arguments);
    }
Aaron Allen
la source
Ce n'est pas ce que je recherche ... Je veux un moyen d'ajouter de nouvelles méthodes à une classe abstraite ... ce n'est qu'un exemple ... par exemple, que faire si je veux supprimer les éléments dynamiquement? Dans votre commentaire, vous mentionnez "la priorité absolue" sur la façon de procéder?
Matias
Ensuite, vous devrez définir vos nouvelles méthodes dans une classe qui étend la classe abstraite, puis créer des classes pour les sous-classes de la classe abstraite qui héritent de votre classe et définissent les préférences dans di.xml. C'est ce que je veux dire par «remplacer complètement la classe». J'essayais de montrer un exemple de comment éviter cela.
Aaron Allen
Oui, je vous comprends ... mais la solution n'est pas du tout évolutive ... Je ne peux pas croire que M2 ait supprimé la possibilité de surcharger les classes abstraites ... Je pensais qu'ils allaient l'améliorer, au lieu de la supprimer .. .
Matias
0

surcharger une classe dans M1 dans le chargeur automatique via la communauté ou le répertoire local (comme suggéré dans la question que vous avez liée) a été considéré comme une mauvaise pratique dans M1 pour de très bonnes raisons.

La plupart du temps, vous perdez la possibilité de mettre à niveau votre instance Magento si la classe d'origine est modifiée à certains endroits, vous n'avez pas pris en compte dans votre classe surchargée.

En fait, je ne peux penser à aucun cas d'utilisation, où vous devez vraiment ajouter des méthodes à une classe abstraite, car vous pouvez toujours ajouter votre propre logique à une propre classe et l'intégrer dans une configuration plugin / observer / viewModel / xml

La meilleure façon serait d'introduire une nouvelle classe qui étend la classe abstraite pour votre cas d'utilisation spécifique, puis d'utiliser votre classe si nécessaire.

Si vous devez supprimer des éléments d'un composant Ui, il existe probablement un meilleur moyen de le faire via la mise en page / un plugin sur le processeur de mise en page / la modification du fichier js qui le nécessite.

Donc, si vous décrivez votre cas d'utilisation spécifique, il pourrait y avoir une meilleure réponse à cela.

David Verholen
la source
Je sais que faire cela est une mauvaise pratique, mais au moins, vous avez une façon de le faire. Par exemple, considérez le cas où vous souhaitez ajouter un cache pour chaque modèle que vous chargez. Cela pourrait être fait en modifiant la méthode de chargement dans la classe abstraite, puis ce changement sera propagé à toutes les classes. Si vous ne l'avez pas, vous devez modifier chaque modèle que vous possédez, et ce n'est absolument pas évolutif.
Matias
Un deuxième cas d'utilisation, pourrait être si vous voulez faire ce que je dis dans le ticket, supprimer / supprimer des éléments de ce tableau (à titre d'exemple), vous pouvez penser à autre chose ... vous devez créer une nouvelle fonction dans la classe abstraite, sinon, vous serez obligé de créer la même fonction dans chaque classe qui s'étend, et qui encore une fois n'est pas évolutive du tout ... Et pire, parce que les variables dans le noyau Magento sont privées au lieu d'être protégées, donc le la seule façon de le faire est d'ajouter une méthode dans la classe abstraite ...
Matias
le premier exemple est absolument facile en ajoutant simplement un plugin around au modèle abstrait et en cache le résultat de la charge par modèle. Ce qui serait bien mieux que de surcharger la classe abstraite, ce qui interromprait chaque mise à jour future où le modèle abstrait est modifié. Vous deuxième "exemple", je ne peux pas vous en dire beaucoup, parce que vous demandez essentiellement d'ajouter une méthode à la classe abstraite, au lieu d'indiquer votre cas d'utilisation réel
David Verholen
btw c'est toujours possible dans Magento2 car vous pouvez manipuler le chargeur automatique du compositeur, mais fortement déconseillé car vous aurez des problèmes avec les mises à jour magento.stackexchange.com/questions/164455/…
David Verholen
Ce n'est pas une option
Matias