0

I want create controller for specific path, but i can't know how i can do this.

My controller must work with path like: site.com/usa/some-review/dynamicParam

My path for controller: site.com/some-review/index/index

How i can create controller for usa/some-review/dynamicParam or forward redirect from usa/some-review/dynamicParam to some-review/index/index?

Thanks)

2 Answers 2

2

You need to create custom router (matcher) for route to your action controller

1. Define your custom router

app/code/Acme/StackExchange/etc/frontend/di.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Magento\Framework\App\RouterList">
        <arguments>
            <argument name="routerList" xsi:type="array">
                <item name="acme_stackexchange" xsi:type="array">
                    <item name="class" xsi:type="string">Acme\StackExchange\Controller\Router</item>
                    <item name="disable" xsi:type="boolean">false</item>
                    <item name="sortOrder" xsi:type="string">50</item>
                </item>
            </argument>
        </arguments>
    </type>
</config>

2. Create Routed and implement your match logic

app/code/Acme/StackExchange/Controller/Router.php

<?php
declare(strict_types=1);

namespace Acme\StackExchange\Controller;

use Magento\Framework\App\Action\Forward as ActionForward;
use Magento\Framework\App\ActionFactory;
use Magento\Framework\App\RequestInterface;
use Magento\Framework\App\ResponseInterface;
use Magento\Framework\DataObject;
use Magento\Framework\Event\ManagerInterface as EventManagerInterface;
use Magento\Store\Model\StoreManagerInterface;

class Router implements \Magento\Framework\App\RouterInterface
{
    protected ActionFactory         $actionFactory;
    protected EventManagerInterface $eventManager;
    protected StoreManagerInterface $storeManager;
    protected ResponseInterface     $response;

    public function __construct(
        ActionFactory $actionFactory,
        EventManagerInterface $eventManager,
        StoreManagerInterface $storeManager,
        ResponseInterface $response
    ) {
        $this->actionFactory = $actionFactory;
        $this->eventManager  = $eventManager;
        $this->storeManager  = $storeManager;
        $this->response      = $response;
    }

    /**
     * @inheritDoc
     */
    public function match(RequestInterface $request)
    {
        $requestPath = $request->getPathInfo();
        if (!str_contains($requestPath, '/some-review/')) {
            return null;
        }

        // optional create event
        $condition = new DataObject(['request' => $request, 'custom' => 'custom_value']);
        $this->eventManager->dispatch(
            'acme_controller_router_match_before',
            ['router' => $this, 'condition' => $condition]
        );

        // example to verify in store if needed
        $store = $this->storeManager->getStore();

        // parse request and set your action if applicable
        $request->setModuleName('acme')
            ->setControllerName('result')
            ->setActionName('review');

        // you can set dynamic variables to request like
        $request->setParam('param_name', 'param_value');

        return $this->actionFactory->create(ActionForward::class);
    }
}
1
  • Thank you very much) I did the router in the same way, but I didn’t go into my class with the help of debugging, maybe I made a mistake somewhere and your code helped me Aug 8, 2022 at 15:51
-1

You can create the Frontend Controller with the specific path by :

Create this file:

app/code///etc/frontend/routes.xml

<?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="standard">
        <route id="VendorName_ModuleName" frontName="path">
            <module name="VendorName_ModuleName" />
        </route>
     </router>
</config>

For Controller we will create this file :

app/code///Controller/Index/Index.php

<?php

namespace VendorName\ModuleName\Controller\Index;

class Index extends \Magento\Framework\App\Action\Action
{
     public function execute()
     {
         echo 'Hello World';
         exit();
     }
}

The File Structure of the Magento is below :

├── app
│   └── code 
│        └── Magefan // назва розробника - VendorName
│            └── Faq // назва модуля - ModuleName
│                ├── etc
│                │   ├──module.xml
│                │   └──frontend
│                │      └── routes.xm
│                │
│                ├── registration.php
│                └── Controller
│                    └── Index
│                        └── Index.php
│

Then run these commands :

php bin/magento s:up

php bin/magento c:f

php bin/magento s:di:c

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.