Magento 2 Argument Types – Parte 2

No último post, demos início aos estudos Magento 2 Argument Types. Neste post, daremos continuidade em Magento 2 Argument Types – Parte 2.

Já vimos como usar o Argument Types para interceptarmos objetos que estão sendo passados pelo __construct() de uma classe e modificá-lo. Agora, falaremos em como interceptar e modificar dados do tipo string, number, array e constant.

Então, criamos a nossa classe ForMage\Learning\Model\Product\Shirt

<?php

namespace ForMage\Learning\Model\Product;

class Shirt
{
    protected $typeText;
    protected $typeNumber;
    protected $typeArray = [];
    protected $typeInitParameter;

    const MY_CONSTANT = 'MY CUSTOM CONSTANT';

    public function __construct(
        $typeText = 'my string',
        $typeNumber = 2010,
        $typeArray = ['customName' => 'Abraao Marques', 'customColor' => 'Orange']
    ) {
        $this->typeText = $typeText;
        $this->typeNumber = $typeNumber;
        $this->typeArray = $typeArray;
    }
}

Como vemos acima, é uma classe simples onde adicionamos diversos parâmetros a nosso __construct().

Em nosso controller, fizemos as seguintes modificações para executar a nossa classe:

<?php

namespace ForMage\Learning\Controller\Page;

use Magento\Framework\App\Action\Context;
use Magento\Framework\App\ResponseInterface;
use ForMage\Learning\Api\SizeInterface;
use ForMage\Learning\Api\ColorInterface;
use ForMage\Learning\Model\Product\Shoe;
use ForMage\Learning\Model\Product\Shirt;

class Index extends \Magento\Framework\App\Action\Action
{
    protected $size;
    protected $color;
    protected $product;
    protected $shirt;

    public function __construct(
        Context $context,
        SizeInterface $size,
        ColorInterface $color,
        Shoe $product,
        Shirt $shirt
    ) {
        parent::__construct($context);
        $this->size = $size;
        $this->color = $color;
        $this->product = $product;
        $this->shirt = $shirt;
    }

    public function execute()
    {
        var_dump($this->shirt);
    }
}

Ao acessarmos a nossa rota, temos o seguinte resultado:

Utilizando o Argument Types, poderemos interceptar e alterar os seus valores.

Magento 2 Argument Types – Parte 2

Para entender melhor quais são os tipos de dados que poderemos tratar no Argument Type, vamos em vendor/magento/framework/Data/etc/argument/types.xsd

<?xml version="1.0" encoding="UTF-8"?>
<!--
/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */
-->
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

    <xs:complexType name="argumentType" abstract="true" mixed="true">
        <xs:attribute name="name" use="required"/>
    </xs:complexType>

    <xs:complexType name="array" mixed="true">
        <xs:complexContent>
            <xs:extension base="argumentType">
                <xs:sequence>
                    <xs:element name="item" type="argumentType" minOccurs="0" maxOccurs="unbounded">
                        <xs:key name="itemName">
                            <xs:selector xpath="item"></xs:selector>
                            <xs:field xpath="@name"></xs:field>
                        </xs:key>
                    </xs:element>
                </xs:sequence>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>

    <xs:complexType name="asoc" mixed="true">
        <xs:sequence>
            <xs:element name="item" type="argumentType" minOccurs="0" maxOccurs="unbounded"/>
        </xs:sequence>
    </xs:complexType>

    <xs:complexType name="string">
        <xs:complexContent>
            <xs:extension base="argumentType">
                <xs:attribute name="translate" use="optional" type="xs:boolean"/>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>

    <xs:complexType name="boolean">
        <xs:complexContent>
            <xs:extension base="argumentType"/>
        </xs:complexContent>
    </xs:complexType>

    <xs:complexType name="object">
        <xs:complexContent>
            <xs:extension base="argumentType"/>
        </xs:complexContent>
    </xs:complexType>

    <xs:complexType name="configurableObject" mixed="true">
        <xs:complexContent>
            <xs:extension base="argumentType">
                <xs:sequence>
                    <xs:element name="argument" type="argumentType" minOccurs="1" maxOccurs="unbounded">
                        <xs:key name="argumentConfigurableObjectName">
                            <xs:selector xpath="argument"/>
                            <xs:field xpath="@name"/>
                        </xs:key>
                    </xs:element>
                </xs:sequence>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>

    <xs:complexType name="number">
        <xs:complexContent>
            <xs:extension base="argumentType"/>
        </xs:complexContent>
    </xs:complexType>

    <xs:complexType name="null">
        <xs:complexContent>
            <xs:restriction base="argumentType"/>
        </xs:complexContent>
    </xs:complexType>

    <xs:complexType name="argumentsType">
        <xs:sequence>
            <xs:element name="argument" type="argumentType" minOccurs="1" maxOccurs="unbounded">
                <xs:key name="argumentItemName">
                    <xs:selector xpath="item"></xs:selector>
                    <xs:field xpath="@name"></xs:field>
                </xs:key>
            </xs:element>
        </xs:sequence>
    </xs:complexType>

</xs:schema>

Alguns dos tipos vistos acima:

<xs:complexType name=”string”> –> tipo String

<xs:complexType name=”array” mixed=”true”> –> tipo Array

<xs:complexType name=”number”> –> tipo Number

Tendo isso em vista, voltamos ao nosso di.xml e adicionamos:

<type name="ForMage\Learning\Model\Product\Shirt">
    <arguments>
        <argument name="typeText" xsi:type="string">MY STRING IN ARGUMENT TYPE</argument>
        <argument name="typeNumber" xsi:type="number">19.80</argument>
        <argument name="typeArray" xsi:type="array">
            <item name="customName" xsi:type="string">Antonio da Silva</item>
            <item name="customColor" xsi:type="string">Purple</item>
        </argument>
    </arguments>
</type>

<type name=”ForMage\Learning\Model\Product\Shirt”> A classe que vamos interceptar o seu __construct()

<argument name="typeText" xsi:type="string">MY STRING IN ARGUMENT TYPE</argument> 

Acima, interceptamos o parâmetro typeText do __construct(), especificamos que o seu tipo é string em xsi:type="string" e passamos o vamor que ele deve ter agora MY STRING IN ARGUMENT TYPE.

Na utilização de Argument Types no Dependency Injection do Magento 2 é obrigatório que seja específico o tipo do dado que está sendo interceptador. Não é só informar qual o parâmetro que está sendo atacado, mas também o seu tipo.

<argument name="typeNumber" xsi:type="number">19.80</argument>

Atacamos o parâmetro typeNumber e específicamos o seu tipo como Number. No tipo Number temos números inteiros assim como float também.

<argument name="typeArray" xsi:type="array">
    <item name="customName" xsi:type="string">Antonio da Silva</item>
    <item name="customColor" xsi:type="string">Purple</item>
</argument>

Já no tipo Array, temos mais alguns detalhes a observar. Assim como dizemos ao Magento 2 que vamos atacar um elemento array xsi:type="array" o mesmo precisaremos fazer para cada um dos itens do array que atacaremos

<item name="customName" xsi:type="string">Antonio da Silva</item>
<item name="customColor" xsi:type="string">Purple</item>

Assim, ao executarmos a nossa rota novamente, temos o seguinte resultado:

 

Ainda, temos o tipo init_parameter. Voltando a nossa classe, adicionamos a modificação em nosso __construct() abaixo:

<?php

namespace ForMage\Learning\Model\Product;

class Shirt
{
    protected $typeText;
    protected $typeNumber;
    protected $typeArray = [];
    protected $typeInitParameter;

    const MY_CONSTANT = 'MY CUSTOM CONSTANT';

    public function __construct(
        $typeText = 'my string',
        $typeNumber = 2010,
        $typeArray = ['customName' => 'Abraao Marques', 'customColor' => 'Orange'],
        $typeInitParameter = self::MY_CONSTANT
    ) {
        $this->typeText = $typeText;
        $this->typeNumber = $typeNumber;
        $this->typeArray = $typeArray;
        $this->typeInitParameter = $typeInitParameter;
    }
}

Em nosso di.xml

<type name="ForMage\Learning\Model\Product\Shirt">
    <arguments>
        <argument name="typeText" xsi:type="string">MY STRING IN ARGUMENT TYPE</argument>
        <argument name="typeNumber" xsi:type="number">19.80</argument>
        <argument name="typeArray" xsi:type="array">
            <item name="customName" xsi:type="string">Antonio da Silva</item>
            <item name="customColor" xsi:type="string">Purple</item>
        </argument>
        <argument name="typeInitParameter" xsi:type="init_parameter">ForMage\Learning\Model\Product\Shirt::MY_CONSTANT</argument>
    </arguments>
</type>

Agora, também estamos trabalhando com o xsi:type=”init_parameter”

<argument name="typeInitParameter" xsi:type="init_parameter">ForMage\Learning\Model\Product\Shirt::MY_CONSTANT</argument>

Acessando a nossa rota agora, temos o seguinte resultado:

Assim, entendemos como poderemos utilizar o Dependency Injection do Magento 2 com Argument Types para interceptarmos o __construct() de uma classe e modificar os valores dos parâmetros que estão sendo passados nela.

Para mais informações sobre Argument Types

Dúvidas? Posta aí!

Um abraço!

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *