In questo articolo abbiamo parlato dei plugin (interceptor) di Magento 2. Abbiamo visto che gli interceptor forniscono uno strumento molto potente per modificare i dati di ingresso e di uscita di un metodo di una classe. Nel modulo che abbiamo creato abbiamo utilizzato un plug in per ogni tipo di interceptor. (Before, After, Around). Ora vedremo uno schema più complesso.

Plugin In APlug In BPlugin CNative method
sort order102030
beforePluginAPluginBPluginC
aroundPluginBPluginC
originalget(string name,
array log)
aroundPluginBPluginC
afterPluginAPluginBPluginC

Come nell’esempio precedente la classe da osservare è la MG\PlayPlugin\Model\Player della quale osserveremo il metodo get con parametri string name e array log.

Iniziamo a strutturare il primo plugin con ordine 10. Lo creiamo per convenienza nella cartella ComplexScenario e lo chiameremo PluginA

<?php
declare(strict_types=1);

namespace MG\PlayPlugin\Plugin\ComplexScenario;

use MG\PlayPlugin\Model\Player;

/**
 * Class PluginA
 * @package MG\PlayPlugin\Plugin\ComplexScenario
 */
class PluginA
{
    public function beforeGet(Player $subject, $name, $log)
    {
        $log[] = "Before PluginA (sort order: 10): Changing name from " . $name . " to 'Joseph'";
        return ['Joseph', $log];
    }

    public function afterGet(Player $subject, $output, $name, $log)
    {

        $output['log'][] = "After PluginA (sort order: 10): Adding name, Mike.";
        $output['statement'] .= ' (and Mike)';

        return $output;
    }
}

Nel nostro file etc/di.xml inseriamo la definizione del plugin.

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Magento\Framework\Console\CommandListInterface">
        <arguments>
            <argument name="commands" xsi:type="array">
                <item name="test_plugin" xsi:type="object">MG\PlayPlugin\Console\PlayerCommand</item>
            </argument>
        </arguments>
    </type>

    <type name="MG\PlayPlugin\Model\Player">
        <plugin name="PluginA" type="MG\PlayPlugin\Plugin\ComplexScenario\PluginA" sortOrder="10" />
    </type>

</config>

Come si vede dalla definizione, in un unico plugin abbiamo sia il before che l’after.

Ora creiamo la classe PluginB che conterrà tutti i tipi di interceptor (before, around , after).

<?php
declare(strict_types=1);
namespace MG\PlayPlugin\Plugin\ComplexScenario;

use MG\PlayPlugin\Model\Player;

class PluginB
{
    public function beforeGet(Player $subject, $name, $log)
    {
        $log[] = "Before : PluginB (sort order: 20): Changing name from " . $name . " to 'Maria'";
        return ['Joseph', $log];
    }

    public function afterGet(Player $subject, $output, $name, $log)
    {
        $output['log'][] = "After : PluginB (sort order: 20): Adding name, Robert.";
        $output['statement'] .= ' and Robert ';

        return $output;
    }

    public function aroundGet(Player $subject, callable $proceed, string $name, array $log)
    {
        $log[] = 'Around PluginB (sort order: 20, before): Changing name to "Emily".';
        $output = $proceed('Emily', $log);
        $output['log'][] = 'Around PluginB (sort order: 20, after): Adding log entry.';

        return $output;
    }
}

Ora andiamo a creare seguendo il nostro schema il PluginC.

<?php
declare(strict_types=1);
namespace MG\PlayPlugin\Plugin\ComplexScenario;

use MG\PlayPlugin\Model\Player;

class PluginC
{
    public function beforeGet(Player $subject, $name, $log)
    {
        $log[] = "Before : PluginC (sort order: 30): Changing name from " . $name . " to 'Maria'";
        return ['Joseph', $log];
    }

    public function afterGet(Player $subject, $output, $name, $log)
    {
        $output['log'][] = "After : PluginC(sort order: 30): Adding name, Robert.";
        $output['statement'] .= ' and Leone ';

        return $output;
    }

    public function aroundGet(Player $subject, callable $proceed, string $name, array $log)
    {
        $log[] = 'Around PluginC (sort order: 30, before): Changing name to "Alexander".';
        $output = $proceed('Alexander', $log);
        $output['log'][] = 'Around PluginC (sort order: 30, after): Adding log entry.';

        return $output;
    }
}

Anche in questo caso abbiamo tutti i tipi di interceptor. (Before, Around, After). Il nostro etc/di.xm completo sarà dunque:

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Magento\Framework\Console\CommandListInterface">
        <arguments>
            <argument name="commands" xsi:type="array">
                <item name="test_plugin" xsi:type="object">MG\PlayPlugin\Console\PlayerCommand</item>
            </argument>
        </arguments>
    </type>

    <type name="MG\PlayPlugin\Model\Player">
        <plugin name="PluginA" type="MG\PlayPlugin\Plugin\ComplexScenario\PluginA" sortOrder="10" />
    </type>

    <type name="MG\PlayPlugin\Model\Player">
        <plugin name="PluginB" type="MG\PlayPlugin\Plugin\ComplexScenario\PluginB" sortOrder="20" />
    </type>

    <type name="MG\PlayPlugin\Model\Player">
        <plugin name="PluginC" type="MG\PlayPlugin\Plugin\ComplexScenario\PluginC" sortOrder="30" />
    </type>

</config>

Ora svuotiamo le cache e lanciamo il nostro programma console il risultato è il seguente:

[statement] => Hello, Alexander and Leone  (and Mike) and Robert 
    [log] => Array
        (
            [0] => Valore array chiamata metodo
            [1] => Before PluginA (sort order: 10): Changing name from Filippo to 'Joseph'
            [2] => Before : PluginB (sort order: 20): Changing name from Joseph to 'Maria'
            [3] => Around PluginB (sort order: 20, before): Changing name to "Emily".
            [4] => Before : PluginC (sort order: 30): Changing name from Emily to 'Maria'
            [5] => Around PluginC (sort order: 30, before): Changing name to "Alexander".
            [6] => Around PluginC (sort order: 30, after): Adding log entry.
            [7] => After : PluginC(sort order: 30): Adding name, Robert.
            [8] => Around PluginB (sort order: 20, after): Adding log entry.
            [9] => After PluginA (sort order: 10): Adding name, Mike.
            [10] => After : PluginB (sort order: 20): Adding name, Robert.
        )

)

Vediamo meglio la sequenza mediante l’utilizzo di una tabella.

Plugin In APlug In BPlugin CNative method
sort order102030
beforePluginA (1)PluginB (2)PluginC (4)
aroundPluginB (3)PluginC (5)
originalget(string name,
array log)
aroundPluginB (8)PluginC (6)
afterPluginA (9)PluginB (10)PluginC (7)

Come abbiamo visto il sistema processa nell’ordine prima i before poi eventuali around before poi gli around after poi gli after.

Ora andiamo ad analizzare le classi che si occupano di gestire gli interceptor.

Summary
Article Name
Magento 2 Plugin uno scenario complesso
Description
In questo articolo vediamo come utilizzare i plugin in uno scenario più complesso. Analizziamo in come vengono chiamati plugin che contengono più definizioni, before, around, after.
Author
Publisher Name
magedevel.com