Categories: Мадженто 2

Краткий обзор генерации кода в Magento 2

С появлением Magento 2 многие вопросы требуют объяснения. Сегодня очередь дошла до разбора процесса генерации кода в системе, как одной из новых ключевых концепций в Magento 2. Вас когда-либо волновал вопрос, когда и почему создается код в папке var/generation и какой процесс за это отвечает? Если это так, тогда эта статья для вас.

Генерация кода – краткий обзор

Генерация кода может быть вызвана двумя способами:

  • На лету. Вы объявляете класс с понятным именем, которое следует определенному паттерну. Когда система пытается автозагрузить класс и не находит его, этот класс будет сгенерирован. Это очень полезно в режиме разработки, так как система делает все сама, вам не нужно запускать в консоли команду генерации снова и снова. Однако это замедляет работу системы.
  • Командная строка. Когда вы запускаете генерацию кода из командной строки, система проверит код и сгенерирует все необходимые классы. Данный способ полезен для сайта он-лайн, поскольку он не нагружает систему.

Для второго способа вам нужно запускать команду:

magento setup:di:compile

чтобы создать необходимые файлы. Оба варианта ведут к созданию классов в папке var/generation.

Какие классы генерируются?

Существует несколько типов классов, которые генерируются системой. Мы остановимся на 3-х самых важных:

  • Фабричные
  • Прокси
  • Плагины

А теперь давайте по порядку.

Фабричные

Фабричные классы используются для создания объектов, которые не могут быть вставлены автоматически. Например, объект товара должен быть загружен из базы данных, но для контейнера инъекции зависимостей недостаточно информации для создания этого объекта. Вот почему используются фабрики.

Давайте посмотрим на существующий класс в app/code/Magento/Catalog/Model/Product/Copier.php

/**
* @param CopyConstructorInterface $copyConstructor
* @param \Magento\Catalog\Model\ProductFactory $productFactory
*/public function __construct(
  CopyConstructorInterface $copyConstructor,
  \Magento\Catalog\Model\ProductFactory $productFactory
) {
  $this->productFactory = $productFactory;
  $this->copyConstructor = $copyConstructor;
}

Пояснение рабочего процесса:

  • Разработчик объявляет зависимость от фабрики в конструкторе ($productFactory)
  • Менеджер объектов вводит эту зависимость
  • Разработчик может получить доступ к методу create() (единственному методу на фабричном объекте) для создания как можно большего количества экземпляров Product.

Вот как вы, как разработчик, можете использовать фабрики. В фоновом режиме система сгенерирует файл, расположенный в /var/generation/Magento/Catalog/Model/ProductFactory.php, который выглядит так (упрощенно):

<?php
namespace Magento\Catalog\Model;

class ProductFactory
{
 public function __construct(
  \Magento\Framework\ObjectManagerInterface $objectManager, $instanceName = '\\Magento\\Catalog\\Model\\Product'
 )
 {
  $this->_objectManager = $objectManager;
  $this->_instanceName = $instanceName;
 }

 public function create(array $data = array())
 {
  return $this->_objectManager->create($this->_instanceName, $data);
 }
}

Как мы видим, единственной целью фабричных классов является делегирование инстанциирования объектов объектным менеджерам.

Прокси

Magento 2 использует конструктор инъекций, в котором указываются все требуемые зависимости. Вы не можете создавать объекты без объявления всех зависимостей. Что делать, если вы хотите иметь дополнительные зависимости? Для этого существуют прокси.

<config>
 <type name="Magento\Catalog\Model\Resource\Product\Collection">
  <arguments>
   <argument name="customerSession" xsi:type="object">
     Magento\Customer\Model\Session\Proxy
   </argument>
  </arguments>
 </type>
</config>

Пояснение рабочего процесса:

  • Разработчик никогда не трогает PHP файлы для использования прокси, он использует только файл di.xml
  • Обратите внимание на ключевое слово Proxy, добавленное в Magento\Customer\Model\Session\. Зависимости, отмеченные таким образом, являются необязательными зависимостями.

В фоновом режиме система сгенерирует файл, расположенный в /var/generation/Magento/Customer/Model/Session/Proxy.php, который выглядит так (упрощенно):

<?php
namespace Magento\Customer\Model\Session;

class Proxy extends \Magento\Customer\Model\Session
{
 protected function _getSubject()
 {
  if (!$this->_subject) {
   $this->_subject = true === $this->_isShared
   ? $this->_objectManager->get($this->_instanceName)
   : $this->_objectManager->create($this->_instanceName);
  }
  return $this->_subject;
 }
 ...
}

Как мы видим, это расширяет исходный класс и переопределяет каждый метод, который делегирует вызов к исходному образцу. Это означает, что при первом вызове прокси метода исходный экземпляр создается со всеми его зависимостями. Поэтому единственной целью прокси является отсрочка создания экземпляра (и его зависимостей) до самого первого использования.

Плагины (перехватчики)

Проще говоря, плагины являются основными механизмами кастомизации Magento 2. Больше не нужно перезаписывать класс. Плагин позволяет вам подключаться и делать что-то до, после или вокруг любого public метода приложения.

Давайте посмотрим на системный плагин:

<?php
namespace Magento\Store\App\Action\Plugin;

class StoreCheck
{
 public function aroundDispatch(
  \Magento\Framework\App\Action\Action $subject,
  \Closure $proceed,
  \Magento\Framework\App\RequestInterface $request
 ) {
  if (!$this->_storeManager->getStore()->getIsActive()) {
   throw new \Magento\Framework\Exception\State\InitException(
   __('Current store is not active.')
  );
  }
  return $proceed($request);
 }
}

Пояснение рабочего процесса:

  • Разработчик пишет класс плагина в зависимости от требований (ознакомьтесь с официальной документацией)
  • Разработчик регистрирует плагин в файле di.xml, например, так:

<config>
 <type name="Magento\Framework\App\Action\Action">
  <plugin name="storeCheck"
   type="Magento\Store\App\Action\Plugin\StoreCheck"
   sortOrder="10"/>
 </type>
</config>

В результате система сгенерирует класс Interceptor в /var/generation/Magento/Framework/App/Action/Interceptor.php

<?php
namespace Magento\Framework\App\Action\Action;

class Interceptor extends \Magento\Framework\App\Action\Action
{
 public function dispatch(\Magento\Framework\App\RequestInterface $request)
 {
  $pluginInfo = $this->pluginList->getNext('\\Magento\\Framework\\App\\Action\\Action', 'dispatch');
  if(!$pluginInfo) {
   return parent::dispatch($request);
  } else {
   return $this->__callPlugins('dispatch', func_get_args(), $pluginInfo);
  }
 }
}

В отличие от прокси, на этот раз инструмент генерации будет генерировать только те методы, которые вы хотите переписать.

Вот и все на сегодня. Пишите свои комментарии в форме комментирования ниже.

Tags: Magento2

Recent Posts

Инструкция по скачиванию видео с сервиса TikTok (бесплатно и без watermark)

Если вы еще не слышали о TikTok, тогда рекомендуем вам сначала ознакомиться с этим кратким… Read More

17/09/2020

Что есть в бюджетном ноутбуке – на какие характеристики рассчитывать?

Прошли те времена, когда приличный ноутбук стоил от 1000 долларов. Сегодня можно купить довольно неплохой… Read More

16/09/2020

Что лучше – цифровое телевидение Т2 или интернет-телевидение?

Современную жизнь невозможно представить без телевидения. Оно позволяет узнавать о событиях в Украине и мире,… Read More

02/09/2020

Гипоаллергенная подушка. Для чего она важна?

Сейчас найдется мало людей, у которых нет аллергии на продукты или пыльцу растений. Считается, что… Read More

28/08/2020

Футбольный Инстаграм: что нового у топовых футболистов

Некоторые известные футболисты тщательно скрывают свои личную жизнь, а другие - активно постят фотографии с… Read More

24/08/2020

Виды и типы компрессионных чулков

Изделия называют компрессионными, когда их применяют для лечения, а также профилактики нарушений кровотока в нижних… Read More

22/08/2020