5

I have a product object and I need to get product URL of it that will include all its categories e.g. - http://example.com/category/subcategory/product_name

I've managed to find a way that will return to me such type of url. Here is is:

// $product - is defined

$categoryIds = $product->getCategoryIds();
$cats_collection = Mage::getModel('catalog/category')->getCollection()
        ->addAttributeToFilter('entity_id', $categoryIds)
        ->addAttributeToFilter('is_active', 1);
// I filter the categories by their level, so they always go cat/sub-cat/sub-sub-cat 
$cats_collection->getSelect()->order('level DESC')->limit(1);

// I get a product URL that looks like http://example.com/product_name
$productURL = $product->getProductUrl();

// I get just product_name part
$productSlug = substr( $productURL, strrpos( $productURL, '/' )+1 );

// http://example.com/cat/sub-cat/sub-sub-cat 
$categoryUrl = $cats_collection->getFirstItem()->getUrl();


// Final result: http://example.com/cat/sub-cat/sub-sub-cat/product_name
echo  $categoryUrl . '/' . $productSlug;

But my guts are telling me that this can be done simpler.

Is there any simpler way of getting such URL? Or is it possible to optimize some part of my code?

Thank you.

7

The product URL is generated in this method

Mage_Catalog_Model_Product_Url::getUrl(
    Mage_Catalog_Model_Product $product, $params = array()
)

To make sure that the category key is included in the url you have to make sure that $product->getCategoryId() returns a category id and $product->getDoNotUseCategoryId() returns false.
The method getCategoryId() looks like this:

public function getCategoryId()
{
    if ($category = Mage::registry('current_category')) {
        return $category->getId();
    }
    return false;
}

This means that you need to register a category so you can get the id from it in this method. (off topic a little: the model should not know the environment it's in. This way of getting the category id from the product seams wrong, but that's the way it works in Magento).

So the code could look like this:

// assuming the variable $product exists.

$product->setDoNotUseCategoryId(false);
$categoryIds = $product->getCategoryIds();

// if you are sure that the product is in one category and only 
// one skip the next lines. If not, you can get the id of the 
// lowest level:
$cats_collection = Mage::getModel('catalog/category')->getCollection()
        ->addAttributeToFilter('entity_id', $categoryIds)
        ->addAttributeToFilter('is_active', 1);

// filter the categories by their level, so they always go 
// cat/sub-cat/sub-sub-cat 
$cats_collection->getSelect()->order('level DESC')->limit(1);

// no register the category so it can be used in the product url:
$registeredCategory = Mage::registry('current_category');
Mage::unregister('current_category'); //use this to avoid registry errors
Mage::register('current_category', $cats_collection->getFirstItem());
$url = $product->getProductUrl(); //this is the product url.
Mage::unregister('current_category'); //reset the registry to previous state.

if (registeredCategory) {
    Mage::register('current_category', registeredCategory);
}
  • 1
    Hey @Marius, any idea why Magento core sets $product->setDoNotUseCategoryId(true) in Mage_Catalog_Block_Product_List_Related on line 69 (1.9.0.1)? Is it because of performance reasons? – Erfan Apr 17 '15 at 4:08
  • You also need a $product->setRequestPath(null);, so that it works in any case. – Simon Mar 30 '16 at 11:54
1

To configure product and category URLs:

  • From the Admin menu, select System > Configuration.

  • In the Configuration panel on the left, select Catalog. Click to expand the Search Engine Optimizations section. Then, do the following:

    • To remove the suffix from product URLs, clear the default “.html” setting from the Product URL Suffix field.

    • To remove the suffix from category URLs, clear the default “.html” setting from the Category URL Suffix field.

    Note: For an existing catalog, you will need to refresh the Search Indexing (Catalog > Search Indexing) and browser cache (F5).

    • To omit the category path from product URLs, set Use Categories Path for Product URLs to “No.”
  • When complete, click the Save Config button.

Source : http://www.magentocommerce.com/knowledge-base/entry/catalog-url-options

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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