З появою 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>
Пояснення робочого процесу:
di.xmlProxy, додане в 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);
}
}
}
На відміну від проксі, на цей раз інструмент генерації буде генерувати тільки ті методи, які ви хочете переписати.
Ось і все на сьогодні. Пишіть свої коментарі в формі коментування нижче.
У світі веб-серверів часто говорять про протистояння Nginx vs Apache. Але що, якби я сказав…
Коли я починав свій шлях у веб-розробці, питання "який веб-сервер використовувати?" практично не стояло. Відповідь…
Коли мова заходить про веб-сервери, два імені завжди на слуху: Apache та Nginx. Apache —…
У світі веб-розробки ми постійно стикаємося з проблемою: "А в мене на комп'ютері все працює!".…
На зорі моєї кар'єри веб-розробника все було відносно просто: встановив локальний сервер (пам'ятаєте Denwer?), поклав…
Якщо ви коли-небудь цікавилися, як прискорити свій сайт на WordPress, ви, напевно, чули про "кешування".…