Magento 2 Data Objects são conhecidos como Objeto Varien no Magento 1.x. Neste artigo, vamos analisar o funciomento deles e entender o porquê eles são especial.
Estava analisando o artigo Magento 2 Events – Parte 2 e me deparei com o código que usamos nele:
$message = new \Magento\Framework\DataObject(array('custom_text' => 'That is my FIRST custom text')); echo $message->getCustomText();
E achei interessante explicar o funcionamento do Data Object no Magento 2.
Magento 2 Data Object
Quase todos os Models e Blocks no Magento extende o Data Object. E isso dá maiores poderes para eles e deixa as coisas bem mais interessantes.
Pela imagem abaixo, podemos notar o quanto do ecossistema do Magento 2 usa o Data Object
Você já deve ter visto que podemos usar algo como setName()
, getName()
sem nem mesmo existir esses métodos. Isso só é possível, graças ao Data Object.
Analisando um pouco mais afundo, temos a classe Magento\Framework\DataObject
e nela temos o seguinte método:
/** * Set/Get attribute wrapper * * @param string $method * @param array $args * @return mixed * @throws \Magento\Framework\Exception\LocalizedException */ public function __call($method, $args) { switch (substr($method, 0, 3)) { case 'get': $key = $this->_underscore(substr($method, 3)); $index = isset($args[0]) ? $args[0] : null; return $this->getData($key, $index); case 'set': $key = $this->_underscore(substr($method, 3)); $value = isset($args[0]) ? $args[0] : null; return $this->setData($key, $value); case 'uns': $key = $this->_underscore(substr($method, 3)); return $this->unsetData($key); case 'has': $key = $this->_underscore(substr($method, 3)); return isset($this->_data[$key]); } throw new \Magento\Framework\Exception\LocalizedException( new \Magento\Framework\Phrase('Invalid method %1::%2', [get_class($this), $method]) ); }
O Magento 2 faz uso do método mágico __call()
para fazer esse tratamento. Com o método __call()
nós podemos acessar qualquer método private ou protegido de qualquer classe ou até método que não existe na classe.
Vamos a um exemplo.
No seu projeto, crie uma model, conforme abaixo:
<?php namespace ForMage\Learning\Model; class Person { }
Temos, então, um classe Model vazia.
Agora, crie um Controller, conforme abaixo:
<?php namespace ForMage\Learning\Controller\Page; use Magento\Framework\App\Action\Context; use ForMage\Learning\Model\Person; class Test extends \Magento\Framework\App\Action\Action { protected $person; public function __construct( Context $context, Person $person ) { parent::__construct($context); $this->person = $person; } public function execute() { return $this->person->getName(); } }
O que estamos fazendo em no Controller? No método execute()
estamos acessando o método getName()
da classe Person, método esse que não existe nesta classe. Acessando a nossa rota, temos o seguinte resultado:
2021/06/23 01:13:35 [error] 28806#28806: *1 FastCGI sent in stderr: "PHP message: PHP Fatal error: Uncaught Error: Call to undefined method ForMage\Learning\Model\Person::getName() in /var/www/html/magento23/app/code/ForMage/Learning/Controller/Page/Test.php:22
Temos um erro 500 na página com o resultado acima, por que estamos chamando um método que não existe.
Então, voltando para a nossa Model, vamos fazer o tratamento desse erro:
Beleza. Com a utilização do método __call
temos o tratamento de qualquer método que não exista na classe Person.
Indo um pouco mais afundo, temos o seguinte tratamento:
<?php namespace ForMage\Learning\Model; class Person { public function __call(string $name, array $arguments) { $type = substr($name, 0, 3); $key = strtolower(substr($name, 3)); if ($key == "name") { switch ($type) { case "set": $this->name = $arguments[0]; return $this; case "get": return $this->name; } } return $this; } }
Agora, temos um mini Data Object tratando métodos setName()
e getName()
.
Então, voltamos em nosso Controller e efetuamos a seguinte modificação:
<?php namespace ForMage\Learning\Controller\Page; use Magento\Framework\App\Action\Context; use ForMage\Learning\Model\Person; class Test extends \Magento\Framework\App\Action\Action { protected $person; public function __construct( Context $context, Person $person ) { parent::__construct($context); $this->person = $person; } public function execute() { $this->person->setName("Abraão Marques"); echo $this->person->getName(); } }
Ao acessar a nossa rota, temos o seguinte resultado:
Mesmo sem existir os métodos setName()
e getName()
conseguimos fazer uso deles para passar um determinado nome e retorna o seu valor.
Assim, você teve uma melhor noção do funcionamento do Magento 2 Data Object e como ele trabalha.
Claro, é importante que veja a classe Magento\Framework\DataObject
para um aprofundamento maior.
Para mais informações sobre Magento 2 Data Object