SimpleMagento - Magento tutorials, tips and discussions with simplicity in mind
  • Magento 2
  • Frontend
  • Dev Talk
  • Checkout
  • UI components
  • Online Marketing
  • eCommerce Talk
  • Magento 2
  • Frontend
  • Dev Talk
  • Checkout
  • UI components
  • Online Marketing
  • eCommerce Talk
SimpleMagento - Magento tutorials, tips and discussions with simplicity in mind
No Result
View All Result
Home Magento 2

Magento 2 Controllers – Sample 1

by freelancer
April 22, 2022
0 0
Share on FacebookShare on Twitter

Controllers in Magento 2, like on different PHP MVC frameworks, are necessary a part of Mvc flow. In Magento 2 there are many modifications in controllers, for example; how they’re structured and the way they work in contrast with Magento 1. If you’re acquainted with Magento 1 controllers, then you realize they’ll have a number of actions (class methods). In Magento 2 controllers have just one method (execute) that will likely be referred to as by front controller. This article covers controller fundamentals, matching flow, controller types (admin and frontend), modifications on present controllers, directions to create {custom} controllers and an example the right way to create just a few controllers.

Controller

Controller is a class situated in module Controller folder, responsible for particular Url or group of Url’s. It’s completely different than controller in Magento 1 as a result of it has just one referred to as method (in Magento 1 was as many as we needed). All needed data is populated trough DI with object manager. For each action now we have one controller class with execute method. Execute method is known as when router matches controller action class, and it’s responsible for returning response to front controller. All controllers are extending MagentoFrameworkAppActionAction class which has dispatch method which is able to name execute method in controller, however we’ll cover flow later. There are two controller types: frontend and admin. They have related habits however admin has extra methods for permission checks. Controllers are structured in a particular means to allow them to be matched. Url structure for matching is:

www.Simplemagentomagento2.net/frontName/action path/action class/

  • frontName – it’s set in routes.xml configuration, and has unique value which will likely be matched by router
  • action path – folder name inside Controller folder, default is index
  • action class – our action class which we name Controller, default is index

Now, we’ll go trough action controller methods and clarify their functions.

Execute method

This method is “first” referred to as controller action class and it’s inherited from MagentoFrameworkAppActionAction which each controller class extends. It’s referred to as by MagentoFrameworkAppActionAction::dispatch() method. In this method we must always have all of our controllers logic (we are able to, in fact, have logic in extra methods, however execute method will name them) and it’ll return response (largely rendered page).

MagentoFrameworkAppActionAction

This is fundamental Magento framework action class and each controller should extend this class (admin controllers are extending MagentoBackendAppAction which extends MagentoFrameworkAppActionAction). It’s necessary that each controller extends this class to inherit needed methods and to permit front controller to name dispatch method (which is able to name execute method).

Dispatch

This method will likely be referred to as first by Front Controller (MagentoFrameworkAppFrontController)

MagentoFrameworkAppFrontController::dispatch() – calling dispatch in our Action class:

$result = $actionInstance->dispatch($request);

It’s necessary to know that dispatch method in our Action class is used for front controllers. For admin controllers dispatch method is rewritten (in MagentoBackendAppAction), so it will possibly verify is consumer allowed to access. Let’s analyze our dispatch method:

/**
     * Dispatch request
     *
     * @param RequestInterface $request
     * @return ResponseInterface
     * @throws NotFoundException
     */
    public function dispatch(RequestInterface $request)
    {
        $this->_request = $request;
        $profilerKey = 'CONTROLLER_ACTION:' . $request->getFullActionName();
        $eventParameters = ['controller_action' => $this, 'request' => $request];
        $this->_eventManager->dispatch('controller_action_predispatch', $eventParameters);
        $this->_eventManager->dispatch('controller_action_predispatch_' . $request->getRouteName(), $eventParameters);
        $this->_eventManager->dispatch(
            'controller_action_predispatch_' . $request->getFullActionName(),
            $eventParameters
        );
        MagentoFrameworkProfiler::start($profilerKey);
 
        $result = null;
        if ($request->isDispatched() && !$this->_actionFlag->get('', self::FLAG_NO_DISPATCH)) {
            MagentoFrameworkProfiler::start('action_body');
            $result = $this->execute();
            MagentoFrameworkProfiler::start('postdispatch');
            if (!$this->_actionFlag->get('', self::FLAG_NO_POST_DISPATCH)) 
            MagentoFrameworkProfiler::stop('postdispatch');
            MagentoFrameworkProfiler::stop('action_body');
        }
        MagentoFrameworkProfiler::stop($profilerKey);
        return $result ?: $this->_response;
    }

As we are able to see, our dispatch method will return outcomes or response from context. It will verify if request is dispatched and than name execute method in controller action class which extends MagentoFrameworkAppActionAction:

$result = $this→execute();

There are two extra necessary methods that we’ll want in our action classes: _forward and _redirect. Let’s clarify that methods:

Forward method

This protected method will switch control to a different action controller, controller path and module. This will not be redirect and it’ll run yet another router loop to cross control to a different controller action. For extra detailed flow it’s best to verify our “Routing in Magento 2” article.

Redirect method

It will redirect consumer on new Url by setting response headers and redirect url.

Controller action match flow

FrontController::dispatch() → Router::match() → Controller::dispatch() -> Controller::execute()

Above you’ll be able to see excessive stage flow, however since flow is a bit more sophisticated than this, let’s go quick trough extra detailed stage:

FrontController::dispatch()

while (!$request->isDispatched() && $routingCycleCounter++ < 100) {
            /** @var MagentoFrameworkAppRouterInterface $router */
            foreach ($this->_routerList as $router) {
                try {
                    $actionInstance = $router->match($request);

It will first match router, as you’ll be able to see within the code above, and router match will return action class (MagentoFrameworkAppActionManufacturing unit) instance. After that, front controller will name dispatch method on action class instance:

$result = $actionInstance->dispatch($request);

As we’ve already covered dispatch method, it is going to name action class execute method:

$result = $this->execute();

This is shortly how application flow will get in our action class execute method.

Difference between admin and front controller

Main distinction between these two controllers is in extra verify and extra methods in admin controller. Both controllers finally extend MagentoFrameworkAppActionAction class, however admin controller extend MagentoBackendAppAction class, which extends MagentoFrameworkAppActionAction. In admin controller dispatch, redirect and rewrite methods are rewritten to offer logic for checking ACL (Access control list).

Admin controller

It extends MagentoBackendAppAction class and has _isAllowed method which checks access control. In dispatch method it is going to verify if consumer is allowed to access present Url and it’ll redirect to login (if consumer will not be allowed) or it is going to set response with status 403 (forbidden):

public function dispatch(MagentoFrameworkAppRequestInterface $request)
    {
        if (!$this->_processUrlKeys()) {
            return parent::dispatch($request);
        }
 
        if ($request->isDispatched() && $request->getActionName() !== 'denied' && !$this->_isAllowed()) {
            $this->_response->setStatusHeader(403, '1.1', 'Forbidden');
            if (!$this->_auth->isLoggedIn()) {
                return $this->_redirect('*/auth/login');
            }
            $this->_view->loadLayout((*2*), true, true, false);
            $this->_view->renderLayout();
            $this->_request->setDispatched(true);
            return $this->_response;
        }
 
        if ($this->_isUrlChecked()) {
            $this->_actionFlag->set('', self::FLAG_IS_URLS_CHECKED, true);
        }
 
        $this->_processLocaleSettings();
 
        return parent::dispatch($request);
    }

If you’re creating admin controller and need to add some {custom} permission, it is advisable to add access verify in _isAllowed method, for example:

protected function _isAllowed()
{
     return $this->_authorization->isAllowed('Magento_EncryptionKey::crypt_key');
}

Changes on present controllers

For altering present controller, there are couple of methods how they are often modified. You can do this by desire, plugin or use “old” style after/before like Magento 1. Preference will change full controller along with your controller code (we are able to name that like full rewrite). Plugins will change solely desired managed method. Lastly, after and before will change location of controller for {custom} front name. Example for this is the way you add new controller on admin space:

<router id="admin">
        <route id="catalog" frontName="catalog">
            <module name="Magento_Catalog" before="Magento_Backend" />
        </route>
    </router>

Action wrapper class

Action wrapper class is a class in Controller folder which extends MagentoFrameworkAppActionAction, after which our action class extends that action wrapper. If you have widespread logic for a number of action classes, than we are going to write logic in action wrapper class and apply it to each action class we need.

Let’s see, for example, MagentoCatalogControllerProduct which is action wrapper class, and it’s utilized in many action classes situated in CatalogController* folder (action classes: MagentoCatalogControllerProductCompare, MagentoCatalogControllerProductGallery etc), all of them use _initProduct which is responsible for loading the product by helper.

/**
 * Product controller.
 *
 * Copyright © 2015 Magento. All rights reserved.
 * See COPYING.txt for license details.
 */
namespace MagentoCatalogController;
 
use MagentoCatalogControllerProductViewViewInterface;
use MagentoCatalogModelProduct as ModelProduct;
 
abstract class Product extends MagentoFrameworkAppActionAction implements ViewInterface
{
    /**
     * Initialize requested product object
     *
     * @return ModelProduct
     */
    protected function _initProduct()
    {
        $categoryId = (int)$this->getRequest()->getParam('category', false);
        $productId = (int)$this->getRequest()->getParam('id');
 
        $params = new MagentoFrameworkDataObject();
        $params->setCategoryId($categoryId);
 
        /** @var MagentoCatalogHelperProduct $product */
        $product = $this->_objectManager->get('MagentoCatalogHelperProduct');
        return $product->initProduct($productId, $this, $params);
    }
}

How to create {custom} controller

  1. Create routes.xml in etc/frontend or etc/adminhtml folder (first one is for frontend and second one is for admin controller).
  2. Add your {custom} configuration for controller in routes.xml, for example:
    – router: id – standard(frontend)/admin
    – route: id – your unique route id
    – route: frontName – unique name in url, this is first a part of url in base router (www.Simplemagento.com/frontName/actionpath/actionclass/)
    – module name – your module name
  3. Create your action class following the url structure above:
    Controller/Actionpath/Actionclass.php

Examples – Admin and Front controllers

We will create example module for {custom} controllers demonstration. So first, let’s create a module:

etc/module.xml:

<?xml version="1.0"?>
<!--
/**
 * Copyright © 2015 Simplemagento d.o.o.
 * created by Zoran Salamun(zoran.salamun@Simplemagento.net)
 * Module is created for Custom Controllers demonstration
 */
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/Module/etc/module.xsd">
    <module name="Simplemagento_CustomControllers" setup_version="2.0.0"></module>
</config>

etc/frontend/routes.xml – routes configuration for frontend; for demonstration we are going to match “Simplemagentofronttest” as frontname (a part of url after area name – for example: www.Simplemagentotest.net/inchoofronttest/)

<?xml version="1.0"?>
<!--
/**
 * Copyright © 2015 Simplemagento d.o.o.
 * created by Zoran Salamun(zoran.salamun@Simplemagento.net)
 * Module is created for Custom Controllers demonstration
 */
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../lib/internal/Magento/Framework/App/etc/routes.xsd">
    <router id="standard">
        <route id="Simplemagentotestfrontend" frontName="Simplemagentofronttest">
            <module name="Simplemagento_CustomControllers" />
        </route>
    </router>
</config>

etc/adminhtml/routes.xml – routes configuration for admin, for demonstration we are going to match “Simplemagentoadmintest” as frontname (a part of url after /admin/)

<?xml version="1.0"?>
<!--
/**
 * Copyright © 2015 Simplemagento d.o.o.
 * created by Zoran Salamun(zoran.salamun@Simplemagento.net)
 * Module is created for Custom Controllers demonstration
 */
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../lib/internal/Magento/Framework/App/etc/routes.xsd">
    <router id="admin">
        <route id="Simplemagentoadmintest" frontName="Simplemagentoadmintest">
            <module name="Simplemagento_CustomControllers" before="Magento_Backend" />
        </route>
    </router>
</config>

Now we are going to create action classes for each of the controllers configuration. On frontend let’s create action path and action class for url siteurl/Simplemagentofronttest/demonstration/sayhello/. You can see that we need Demonstration folder (this is known as action path) within our Controller folder, and inside that folder we need Sayhello.php controller action class:

Controller/Demonstration/Sayhello.php:

<?php
/**
 * Copyright © 2015 Simplemagento d.o.o.
 * created by Zoran Salamun(zoran.salamun@inchoo.net)
 */
namespace SimplemagentoCustomControllersControllerDemonstration;
 
class Sayhello extends MagentoFrameworkAppActionAction
{
    /**
     * say hello text
     */
    public function execute()
    {
        die("Hello ;) - Simplemagento\CustomControllers\Controller\Demonstration\Sayhello - execute() method");
    }
}

For admin controller let’s match url siteurl/admin/Simplemagentoadmintest/demonstration/sayadmin/. For that we need Demonstration folder in Controller/Adminhtml, and inside that action class we need to create Sayadmin.php

Controller/Adminhtml/Demonstration/Sayadmin.php

<?php
/**
 * Copyright © 2015 Simplemagento d.o.o.
 * created by Zoran Salamun(zoran.salamun@inchoo.net)
 */
namespace SimplemagentoCustomControllersControllerAdminhtmlDemonstration;
 
class Sayadmin extends MagentoBackendAppAction
{
    /**
     * say admin text
     */
    public function execute()
    {
        die("Admin ;) - Simplemagento\CustomControllers\Controller\Adminhtml\Demonstration\Sayadmin - execute() method");
    }
}

Note that by default _isAllowed will return true, and for creating {custom} permission you could add verify beneath that method. For demonstration we are going to preserve default value so consumer can access that controller.

Note: after you add new controller, flush everything from console in Magento root:

php bin/magento setup:upgrade

You can pull this example and install from github.

Here is the installation instruction:

Add repository to composer configuration:

composer config repositories.Simplemagentocustomcontroller vcs git@github.com:zoransalamun/magento2-custom-controllers.git

Require new package with composer:

composer require Simplemagento/custom-controllers:dev-master

Enable Simplemagento CustomControllers module:

php bin/magento module:enable Simplemagento_CustomControllers

Flush everything:

php bin/magento setup:upgrade

I hope this article helped you perceive Controllers in Magento 2.

It appears like a sophisticated matter, however when you create few take a look at controllers it turns into straight ahead job to do. Please go away a remark, suggestion or ask questions. 🙂

If you’re having questions or need assistance relating to Magento development, we’d be pleased that can assist you out by making a detailed {custom} report primarily based on our technical audit. Feel free to get in contact!

Tags: Magento 2ProgrammingMVC Magen
Previous Post

How to create a basic module in Magento 2 – Sample 1

Next Post

Routing in Magento 2 – Sample 1

freelancer

freelancer

Related Posts

Magento 2 Payment

Implementing payment gateway in Magento 2 – Sample 1

April 22, 2022
Integration

Implementing payment gateway in Magento 2 Spinned – Sample 1

April 22, 2022
Magento 2

Implementing payment gateway in Magento 2 – Sample 1

April 22, 2022
Magento 2

Routing in Magento 2 – Sample 1

April 22, 2022
Magento 2

How to create a basic module in Magento 2 – Sample 1

April 22, 2022
Magento 2

Magento 2 frontend architecture – Sample 1

April 22, 2022

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Categories

  • Administration
  • Search
  • Configuration
  • Starting Up
  • Extensions
  • News
  • PWA
  • Magento 2 API
  • Programming
  • MVC Magento 2
  • UX/UI Design
  • Shipping Magento 2
  • Database
  • Magento 2 Payment
  • Magento 2
  • Cache
  • Frontend
  • Integration
  • Dev Talk
  • Life at Inchoo
  • Checkout
  • Tips
  • UI components
  • Products
  • Online Marketing
  • Debugging
  • Magento
  • Search Magento 2
  • Upgrading Magento 2
  • Marketing
  • eCommerce Talk
  • Events & Observers
  • Uncategorized

Popular Post

Magento 2

Magento 2 frontend architecture – Sample 1

April 22, 2022
UX/UI Design

Magento 2 Luma Theme Under The Scope

March 27, 2022
Magento 2

Implementing payment gateway in Magento 2 – Sample 1

April 22, 2022
Magento 2

Moving the validation error message, this time globally

March 25, 2022
No Result
View All Result
[vc_row full_width="stretch_row" vc_row_background="" css=".vc_custom_1516082354216{margin-top: 30px !important;padding-top: 22px !important;padding-bottom: 22px !important;}"][vc_column el_class=".footer_center" offset="vc_col-lg-offset-3 vc_col-lg-6"]
[vc_empty_space height="15px"][vc_column_text css=".vc_custom_1516083863519{margin-bottom: 0px !important;}" el_class=".copyright"]Copyright © 2018 JNews. Photography Blog theme by Jegtheme.[/vc_column_text][/vc_column][/vc_row]
No Result
View All Result
  • Magento 2
  • Frontend
  • Dev Talk
  • Checkout
  • UI components
  • Online Marketing
  • eCommerce Talk

© 2023 JNews - Premium WordPress news & magazine theme by Jegtheme.

Welcome Back!

Login to your account below

Forgotten Password?

Retrieve your password

Please enter your username or email address to reset your password.

Log In