Cómo crear un Adminhtml Controller en Magento2

Por distintos motivos había dejado olvidado al pobre Barbanet_SampleModule. El módulo comenzó como una forma de ir probando pequeñas porciones de código, como aprendizaje, pero también como un recordatorio a futuro.

Intentaré de aquí en más continuar documentando el módulo, a manera de ejercicio (más allá que hoy día existe una buena cantidad de documentación bastante clara y ya una parte del propio core de Magento ha sido, finalmente, reescrito).

Otro detalle que vale la pena recordar, y que ha funcionado también como disparador del post, es la promesa (por ahora) incumplida de Arturo aquél sábado 7 de mayo en Mar del Plata, cuando se comprometiera a continuar lo que había sido su charla, en forma de posts en el blog.

Como eso aún no sucede, hoy voy a seguir abriendo las distintas secciones del módulo. Hoy tocan los Controllers de Adminhtml.

A diferencia de los controllers del frontend, pero de la misma forma que lo hacíamos en Magento 1, los controllers para Adminhtml irán dentro del directorio Controller/Adminhtml. Además, cómo ya vimos, cada Action será una clase independiente.

Vayamos entonces a escribir el controller en si.

namespace Barbanet\SampleModule\Controller\Adminhtml\First;

use Magento\Backend\App\Action\Context;
use Magento\Framework\View\Result\PageFactory;

class Index extends \Magento\Backend\App\Action
{

    /**
     * Authorization level of a basic admin session
     *
     * @see _isAllowed()
     */
    const ADMIN_RESOURCE = 'Barbanet_SampleModule::samplemodule_first';

    /**
     * @var PageFactory
     */
    protected $resultPageFactory;

    /**
     * @param Context $context
     * @param PageFactory $resultPageFactory
     */
    public function __construct(
        Context $context,
        PageFactory $resultPageFactory
    ) {
        parent::__construct($context);
        $this->resultPageFactory = $resultPageFactory;
    }

    /**
     * Index action
     *
     * @return \Magento\Backend\Model\View\Result\Page
     */
    public function execute()
    {
        /** @var \Magento\Backend\Model\View\Result\Page $resultPage */
        $resultPage = $this->resultPageFactory->create();
        $resultPage->setActiveMenu('Barbanet_SampleModule::samplemodule');
        $resultPage->addBreadcrumb(__('Barbanet SampleModule'), __('Barbanet SampleModule'));
        $resultPage->addBreadcrumb(__('First'), __('First'));
        $resultPage->getConfig()->getTitle()->prepend(__('First Adminhtml Controller'));

        return $resultPage;
    }

}

¿Diferencias con el controller del frontend?

Claramente, se hereda y se inyectan otras clases:

use Magento\Backend\App\Action\Context;
use Magento\Framework\View\Result\PageFactory;

class Index extends \Magento\Backend\App\Action

Otra diferencia es que tenemos la constante ADMIN_RESOURCE, la cual nos servirá para controlar los permisos de acceso sobre el controller.

Si miramos el método execute(), lo que veremos es bastante descriptivo. A pesar que no todo funcionará por el momento (pero no importa, ya que no es el objetivo específico de este post).

Ahora, antes de probar si el código de nuestro controller funciona, no tenemos que olvidar de definir nuestro routes.xml.

En este caso, el archivo se ubicará dentro de etc/adminhtml y se verá, para este ejemplo, de la siguiente manera.

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd">
    <router id="admin">
        <route id="samplemodule" frontName="samplemodule">
            <module name="Barbanet_SampleModule" before="Magento_Backend" />
        </route>
    </router>
</config>

Ahora si, la prueba de fuego.

Si todo lo hubiéramos hecho bien, deberíamos ver:

Claramente, es lo que definimos.

Y listo.

Ya tenemos y entendemos cómo definir nuestro primer y básico controller de backend/adminhtml.

El código de este ejemplo se encuentra en el tag 2.24.0 en Github.