Skip to content
intermediate Phase 51 · Admin Basics

Admin Controllers

Action classes, ACL checks, form handling, and grid actions in admin controllers

45m
0 problems
Topic Progress 0%

Admin Controller Actions

Backend Action Base Class

namespace Vendor\Module\Controller\Adminhtml\Order;

use Magento\Backend\App\Action;
use Magento\Backend\App\Action\Context;

class Index extends Action
{
    /**
     * Check admin access
     */
    protected function _isAllowed(): bool
    {
        return $this->_authorization->isAllowed('Vendor_Module::order_view');
    }

    /**
     * Execute action
     */
    public function execute()
    {
        // Get order data
        $orderId = $this->getRequest()->getParam('id');

        $resultPage = $this->resultPageFactory->create();
        $resultPage->getConfig()->getTitle()->prepend(__('Order View'));

        return $resultPage;
    }
}

Action Types

Action Type Purpose Return
Index Grid/list view ResultPage
Edit Form view ResultPage
Save Process form Redirect
Delete Remove item Redirect
MassDelete Bulk delete Redirect

ACL Permission Checks

ACL Check Implementation

namespace Vendor\Module\Controller\Adminhtml\Order;

class Edit extends \Magento\Backend\App\Action
{
    /**
     * Check if user is allowed to access this action
     */
    protected function _isAllowed(): bool
    {
        return $this->_authorization->isAllowed('Vendor_Module::order_edit');
    }

    /**
     * Check ACL before execute
     */
    public function execute()
    {
        if (!$this->_isAllowed()) {
            $this->_actionFlag->set('', self::FLAG_NO_DISPATCH, true);
            $this->_redirect('adminhtml/dashboard/index');
            return $this->resultRedirectFactory->create()
                ->setUrl($this->_url->getUrl('adminhtml/dashboard/index'));
        }

        // Proceed with action
    }
}

ACL Resource Definition

<!-- etc/acl.xml -->
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:framework:Acl/etc/acl.xsd">
    <acl>
        <resources>
            <resource id="Magento_Backend::admin">
                <resource id="Magento_Backend::stores">
                    <resource id="Magento_Backend::stores_settings">
                        <resource id="Magento_Config::config"/>
                    </resource>
                </resource>
                <resource id="Magento_Sales::sales">
                    <resource id="Magento_Sales::orders"/>
                </resource>
                <resource id="Vendor_Module::order">
                    <resource id="Vendor_Module::order_view"/>
                    <resource id="Vendor_Module::order_edit"/>
                    <resource id="Vendor_Module::order_delete"/>
                </resource>
            </resource>
        </resources>
    </acl>
</config>

Form Handling

Save Controller

namespace Vendor\Module\Controller\Adminhtml\Item;

class Save extends \Magento\Backend\App\Action
{
    protected function _isAllowed(): bool
    {
        return $this->_authorization->isAllowed('Vendor_Module::item_save');
    }

    public function execute()
    {
        $data = $this->getRequest()->getPost();

        if (!$data) {
            return $this->_redirect('*/*/index');
        }

        try {
            $model = $this->itemFactory->create();
            $model->setData($data)->save();

            $this->messageManager->addSuccessMessage(__('Item saved successfully.'));

            return $this->_redirect('*/*/edit', ['id' => $model->getId()]);
        } catch (\Exception $e) {
            $this->messageManager->addErrorMessage($e->getMessage());

            return $this->_redirect('*/*/edit', ['id' => $this->getRequest()->getParam('id')]);
        }
    }
}

Delete Controller

namespace Vendor\Module\Controller\Adminhtml\Item;

class Delete extends \Magento\Backend\App\Action
{
    protected function _isAllowed(): bool
    {
        return $this->_authorization->isAllowed('Vendor_Module::item_delete');
    }

    public function execute()
    {
        $id = $this->getRequest()->getParam('id');

        try {
            $model = $this->itemFactory->create();
            $model->load($id);
            $model->delete();

            $this->messageManager->addSuccessMessage(__('Item deleted successfully.'));
        } catch (\Exception $e) {
            $this->messageManager->addErrorMessage($e->getMessage());
        }

        return $this->_redirect('*/*/index');
    }
}

Grid Actions

Mass Action Controller

namespace Vendor\Module\Controller\Adminhtml\Item\Mass;

class MassDelete extends \Magento\Backend\App\Action
{
    protected function _isAllowed(): bool
    {
        return $this->_authorization->isAllowed('Vendor_Module::item_delete');
    }

    public function execute()
    {
        $selected = $this->getRequest()->getParam('selected');
        $massStatus = $this->getRequest()->getParam('mass_status');

        try {
            foreach ($selected as $itemId) {
                $item = $this->itemFactory->create();
                $item->load($itemId);
                $item->delete();
            }

            $this->messageManager->addSuccessMessage(
                __('%1 items deleted successfully.', count($selected))
            );
        } catch (\Exception $e) {
            $this->messageManager->addErrorMessage($e->getMessage());
        }

        return $this->_redirect('*/*/index');
    }
}

Grid Action URL

<!-- Action column in grid -->
<column name="actions" class="Magento\Ui\Component\Listing\Columns\Column\ActionColumn">
    <settings>
        <bodyTmpl>ui/grid/cells/actions</bodyTmpl>
    </settings>
    <action name="edit">
        <settings>
            <url path="vendor_module/item/edit"/>
            <label translate="true">Edit</label>
        </settings>
    </action>
    <action name="delete">
        <settings>
            <url path="vendor_module/item/delete"/>
            <label translate="true">Delete</label>
            <confirm>
                <message translate="true">Are you sure you want to delete this item?</message>
                <title translate="true">Delete Item</title>
            </confirm>
        </settings>
    </action>
</column>

Quiz

1. What does _isAllowed() check?

Question 1 options

2. What should a Save controller return?

Question 2 options

3. How do mass actions get selected items?

Question 3 options

Flashcards

Question

Admin controller base class?

Answer

Magento\Backend\App\Action

Question

ACL check method?

Answer

_isAllowed() using _authorization->isAllowed()

Question

Save controller pattern?

Answer

Get POST data → create model → save → redirect

Question

Mass action data source?

Answer

$this->getRequest()->getParam('selected')

Revision Notes

Key Takeaways

  • 1. Admin controllers extend Magento\Backend\App\Action
  • 2. _isAllowed() implements ACL permission checks
  • 3. Save actions redirect to edit on success, form on error
  • 4. Mass actions receive item IDs in the 'selected' POST parameter
  • 5. ACL resources are defined in etc/acl.xml

Interview Tips

  • Explain the admin controller lifecycle and ACL integration
  • Describe proper error handling and redirect patterns
  • Discuss mass action implementation and security

Cheat Sheet

Admin Controllers:
  extends Backend\App\Action
  _isAllowed() → ACL check
  execute() → action logic

Actions:
  Index: ResultPage (grid)
  Edit: ResultPage (form)
  Save: POST → save → redirect
  Delete: load → delete → redirect
  MassDelete: selected → loop → redirect

ACL:
  _authorization->isAllowed($resource)
  Resource: Vendor_Module::action_name