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
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.