Magento 1
Request Flow
- app/Mage.php (Mage::app()->run())
- app/code/core/Mage/Core/Model/App.php
- Init and Dispatch controller $this->getFrontController()->dispatch();
- app/code/core/Mage/Core/Controller/Varien/Front.php
When the front controller is dispatched, first off, there’s a check whether Url is the link to product or category. Everything starts from Mage_Core_Controller_Varien_Front->dispatch();
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
class Mage_Core_Controller_Varien_Front extends Varien_Object { //... public function dispatch() { $request = $this->getRequest(); // If pre-configured, check equality of base URL and requested URL $this->_checkBaseUrl($request); $request->setPathInfo()->setDispatched(false); $this->_getRequestRewriteController()->rewrite(); //... } //... } //We’re interested in the line: $this->_getRequestRewriteController()->rewrite(); class Mage_Core_Model_Url_Rewrite_Request { ... public function rewrite() { ... $this->_rewriteDb(); ... } } |
Call the rewrite method in Mage_Core_Model_Url_Rewrite_Request in which the _rewriteDb() is called, then the method loadByRequestPath is called. Load rewrite information for request If $path is array — we must load possible records and choose one matching earlier record in array.
1 2 3 4 5 6 7 8 9 10 |
class Mage_Core_Model_Url_Rewrite_Request { ... public function _rewriteDb() { ... $this->_rewrite->loadByRequestPath($requestCases); ... } } |
Request in the database in the method loadByRequestPath:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
class Mage_Core_Model_Resource_Url_Rewrite extends Mage_Core_Model_Resource_Db_Abstract { ... public function loadByRequestPath(Mage_Core_Model_Url_Rewrite $object, $path) { ... $select = $adapter->select() ->from($this->getMainTable()) ->where('request_path IN (:' . implode(', :', array_flip($pathBind)) . ')') ->where('store_id IN(?)', array(Mage_Core_Model_App::ADMIN_STORE_ID, (int)$object->getStoreId())); ... } ... } |
In case there’re Url rewrites in the base, set the redirect header:
1 2 3 4 5 6 7 8 9 10 11 |
class Mage_Core_Model_Url_Rewrite_Request { ... public function _rewriteDb() { ... $targetUrl = $currentStore->getBaseUrl() . $this->_rewrite->getRequestPath(); $this->_sendRedirectHeaders($targetUrl, true); ... } } |
Magento 2
In Magento 2 we have a separate router for processing URL rewrites, that’s why except rewrite mechanism, it’s necessary to understand Routing Mechanism. Each request is sent through the series of routers.
Flow of default routers:
Base Router → CMS Router → UrlRewrite Router → Default Router
Request Flow
index.php -> Bootstrap::create() -> create ObjectManagerFactory -> App::launch() -> FrontController::dispatch() -> router::match() -> Controller::execute()
Routers loop in FrontController::dispatch()
1. Base Router
Magento\Core\App\Router\Base
At base router standard Magento URL (front_name/action_path/action/param_1/etc_params/) is matched.
2. CMS Router
CMS Router is used for handling the CMS Pages and it also sets the module name to “cms”, controller name to “page” and action name to “view” so that makes the full path to execute is /vendor/magento/module-cms/Controller/Page/View.php controller
3. URL Rewrite Router
In Magento 2 UrlRewrite has its own router Magento\UrlRewrite\Controller\Router. using Url Finder to get URL rewrite that matches URL from the database:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
public function match(\Magento\Framework\App\RequestInterface $request) { … $rewrite = $this->urlFinder->findOneByData( [ UrlRewrite::ENTITY_TYPE => $oldRewrite->getEntityType(), UrlRewrite::ENTITY_ID => $oldRewrite->getEntityId(), UrlRewrite::STORE_ID => $this->storeManager->getStore()->getId(), UrlRewrite::IS_AUTOGENERATED => 1, ] ); if ($rewrite && $rewrite->getRequestPath() !== $oldRewrite->getRequestPath()) { return $this->redirect($request, $rewrite->getRequestPath(), OptionProvider::TEMPORARY); } … } |
In case if Url rewrite is found, it is redirected to requertPath found.
4. Default Router (404 Router)
Magento\Framework\App\Router\DefaultRouter
The last in the routers loop. It’s used when every other router doesn’t match. In Magento 2 we can create a custom handle for “Not Found” page to display custom content.
In such a manner, if Url put by the user is Url rewrite, so FrontController::dispatch() doesn’t find Url in Base route firstly, then it doesn’t find in cms route and when it gets URL Rewrite, Router calls the method Magento\UrlRewrite\Controller\Router::match() and using Url Finder to get URL rewrite that matches URL from the database and is redirected to request_path from the database received in url_rewrite table.
All in all, having worked with Magento 1 and Magento 2, you can see the difference in Url rewrites. In fact, it doesn’t look so profound, but there are some minor things that need consideration. Hope the article helps to cope with the issue.