Un detalle que creo no tuvo la amplificación suficiente con el lanzamiento de Magento 2.4, es un cambio que se introdujo de cara a los controllers.
No, no se va a romper nada, no aún.
El post no se trata sobre explicar los puntos a favor y en contra de la herencia y la composición. Simplemente voy a crear un ejemplo basado en el código que deberíamos empezar a adaptar y algunos ejemplos de referencia.
Supongamos que tengo mi módulo que sólo es un controller y su layout para inyectar el título (además de los archivos mínimos que se necesitan para que un módulo pueda existir).
El archivo de layout estará ubicado dentro de view/frontend/layout/sample_test_index.xml. Y contendrá:
<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<body>
<referenceBlock name="page.main.title">
<action method="setPageTitle">
<argument translate="true" name="title" xsi:type="string">Controller con Composición y sin Herencia</argument>
</action>
</referenceBlock>
</body>
</page>
Si escribiera el controller como lo hacíamos/hacemos hasta ahora, el código sería algo así.
<?php
declare(strict_types=1);
namespace Barbanet\Sample\Controller\Test;
use Magento\Framework\App\Action\Action;
use Magento\Framework\App\Action\Context;
use Magento\Framework\App\Action\HttpGetActionInterface;
use Magento\Framework\App\ResponseInterface;
use Magento\Framework\Controller\ResultInterface;
use Magento\Framework\View\Result\Page;
use Magento\Framework\View\Result\PageFactory;
/**
* Class Index
*/
class Index extends Action implements HttpGetActionInterface
{
/**
* @var PageFactory
*/
private $pageFactory;
/**
* @param Context $context
* @param PageFactory $pageFactory
*/
public function __construct(
Context $context,
PageFactory $pageFactory
) {
parent::__construct($context);
$this->pageFactory = $pageFactory;
}
/**
* @return ResponseInterface|ResultInterface|Page
*/
public function execute()
{
return $this->pageFactory->create();
}
}
Si hacen eso ahora verán que la clase Action está deprecada. La forma adecuada ha de ser:
<?php
declare(strict_types=1);
namespace Barbanet\Sample\Controller\Test;
use Magento\Framework\App\Action\HttpGetActionInterface;
use Magento\Framework\App\ResponseInterface;
use Magento\Framework\Controller\ResultInterface;
use Magento\Framework\View\Result\Page;
use Magento\Framework\View\Result\PageFactory;
/**
* Class Index
*/
class Index implements HttpGetActionInterface
{
/**
* @var PageFactory
*/
protected $resultPageFactory;
public function __construct(
PageFactory $resultPageFactory
) {
$this->resultPageFactory = $resultPageFactory;
}
/**
* @return ResponseInterface|ResultInterface|Page
*/
public function execute()
{
return $this->resultPageFactory->create();
}
}
Y si ahora accedo a www.dominio.com/sample/test, debería ver esta pantalla.
Vale aclarar que aún no está implementado en el core ya que se busca evitar la aparición de problemas de incompatibilidad con módulos de terceros debido a que los controllers no son parte de la API pública.
Según la hoja de ruta se comenzará el refactoring del core a partir de 2.5, lo cual no quita que desde hoy nuestros controllers puedan quitarse la pesada e innecesaria herencia.
Para leer más sobre este cambio y sobre las mejoras de performance, se puede repasar el post del Dev Blog en los Community Forums (de comienzos de este año).