Skip to content

Instantly share code, notes, and snippets.

@vovsky
Last active August 29, 2015 14:09
Show Gist options
  • Save vovsky/f3e22da0baa60b8fab6f to your computer and use it in GitHub Desktop.
Save vovsky/f3e22da0baa60b8fab6f to your computer and use it in GitHub Desktop.
magento, url, rewrite

How product Url is generated

On product list page to get product urls Magento performs the following query to assign request_path to every item in product collection:

SELECT
  `e`.`entity_id`                                           AS `product_id`,
  IFNULL(url_rewrite.request_path, default_ur.request_path) AS `request_path`
FROM `catalog_product_entity` AS `e`
  LEFT JOIN `enterprise_catalog_product_rewrite` AS `url_rewrite_product`
    ON url_rewrite_product.product_id = e.entity_id AND url_rewrite_product.store_id = 1
  LEFT JOIN `enterprise_url_rewrite` AS `url_rewrite`
    ON url_rewrite_product.url_rewrite_id = url_rewrite.url_rewrite_id AND url_rewrite.is_system = 1
  LEFT JOIN `enterprise_catalog_product_rewrite` AS `default_urp`
    ON default_urp.product_id = e.entity_id AND default_urp.store_id = 0
  LEFT JOIN `enterprise_url_rewrite` AS `default_ur` ON default_ur.url_rewrite_id = default_urp.url_rewrite_id
WHERE (e.entity_id IN ('549', '551', '552', '553', '554', '555'))

sample output:

product_id request_path
549 blue-horizons-bracelets
551 pearl-stud-earrings
552 swing-time-earrings
553 silver-desert-necklace
554 swiss-movement-sports-watch-h
555 pearl-necklace-set-test

Then Magento checks if there is current_category in registry to get category_id, the same time it checks if category path should be used in Product URLs at all. If it should be used then category 'request_path' is taken from DB as result of using \Enterprise_Catalog_Model_Resource_Category::loadByCategory method, query looks like this:

SELECT
  IFNULL(url_rewrite_cat.id, default_urc.id)                AS `id`,
  IFNULL(url_rewrite.request_path, default_ur.request_path) AS `request_path`
FROM `catalog_category_entity` AS `main_table`
  LEFT JOIN `enterprise_catalog_category_rewrite` AS `url_rewrite_cat`
    ON url_rewrite_cat.category_id = main_table.entity_id AND url_rewrite_cat.store_id = 1
  LEFT JOIN `enterprise_url_rewrite` AS `url_rewrite` ON url_rewrite.url_rewrite_id = url_rewrite_cat.url_rewrite_id
  LEFT JOIN `enterprise_catalog_category_rewrite` AS `default_urc`
    ON default_urc.category_id = main_table.entity_id AND default_urc.store_id = 0
  LEFT JOIN `enterprise_url_rewrite` AS `default_ur` ON default_ur.url_rewrite_id = default_urc.url_rewrite_id
WHERE (main_table.entity_id = 19)

sample output:

id request path
34 accessories/jewelry

Request path is being concatenated with product's 'request_path'

 $requestPath = $categoryRewrite->getRequestPath() . '/' . $requestPath;
 ...
 $product->setRequestPath($requestPath);

The result string is product's URL

Reversed transformation

In \Mage_Core_Controller_Varien_Front::dispatch method there is a line of code that rewrite process start with:

$this->_getRequestRewriteController()->rewrite();

Request path is divided on pathes using '/'. Rewrites are being loaded for those pathes from enterprise_url_rewrite table. Sample query:

SELECT `m`.*
FROM `enterprise_url_rewrite` AS `m`
WHERE (m.request_path IN
       ('accessories/jewelry/swiss-movement-sports-watch-h.html', 'swiss-movement-sports-watch-h', 'accessories/jewelry/swiss-movement-sports-watch-h'))
ORDER BY `m`.`store_id` DESC

Result rows then are being sorted by priority using special matcher class. If rewrite is not system then Magento tries to get redirect for this rewrite, if there is a RP option for redirect than appropriate headers will be sent for redirection. Rewrite object has target_path field that will be used to determine controller, action and product id.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment