Richard Housham
Richard Housham

Reputation: 864

How do I get the category ids that a product is in with respect to the store that I'm currently on

I'm on a product page and have the product object but when I try to get the category ids using:

$_product->getCategoryIds();

or:

$_product->getResource()->getAttribute('category_ids')->getFrontend()->getValue($_product); 

it gets me all the category ids and I just want the ones for the store I'm on.

It's a multistore environment so hence my problem. Everything else seems ok and the category list works fine. This is my only problem. Can anyone help?

Upvotes: 4

Views: 9365

Answers (3)

TaganPablo
TaganPablo

Reputation: 359

if you have millions of categories or millions of products or need collection of all products with all their categories - you can try next freak way (again works only after categories flat index rebuild):

  • in some installer or cron - create a a new table and keep it up to date with next request

for each store:

CREATE TABLE IF NOT EXISTS categories_X SELECT product_id, CONVERT(GROUP_CONCAT(category_id) USING utf8) as category_id FROM catalog_category_product where category_id in (select entity_id from catalog_category_flat_store_X) GROUP BY product_id
  • where X - is ID of store

  • write a model or direct request again to get all categories for required store and required product

Upvotes: 1

Vinai
Vinai

Reputation: 14182

Pretty similar to Alans answer, maybe a bit less looping:

$rootCategory = Mage::getModel('catalog/category')
    ->load(Mage::app()->getStore()->getRootCategoryId());

$sameStoreCategories = Mage::getResourceModel('catalog/category_collection')
    ->addIdFilter($product->getCategoryIds())
    ->addFieldToFilter('path', array('like' => $rootCategory->getPath() . '/%'))
    ->getItems();

var_dump(array_keys($sameStoreCategories));

This will always work. The ugly thing is that you still need to load the categories.

Here is a variation you can use if the flat category tables are enabled:

$sameStoreCategories = Mage::getResourceModel('catalog/category_flat_collection')
    ->addIdFilter($product->getCategoryIds())
    ->getItems();

var_dump(array_keys($sameStoreCategories));

Why does it work? Because the flat tables are indexed by store, and each flat table only contains the category entity records that are associated with that store groups root category.

So even though you are filtering by all category IDs associated with the product, the collection will only contain the categories present in the current store.

Upvotes: 10

Alana Storm
Alana Storm

Reputation: 166166

This one is a little tricky, so if the following doesn't work it's probably the code and not you.

The problem is, as far as I can tell, Magento doesn't keep track of which categories are in which store. Instead, Magento keeps track of the root category for a particular store.

This means once we have a list of category IDs, we need to grab the root category for each, and then check if that root category matches the root category of the current store.

The following code should do that, but please test this with a variety of products

    //get root category for current store
    $store_root_id = Mage::app()->getStore()->getRootCategoryId();

    //get category IDs from product
    $ids = $product->getCategoryIds();        

    //load full cateogires
    $categories = Mage::getModel('catalog/category')
    ->getCollection()
    ->addIdFilter($ids);

    //filter out categories with different root
    $category_ids = array();
    foreach($categories as $cat)
    {
        //path property is 1/root_id/id/id
        $parts      = explode('/', $cat->getPath());
        $one        = array_shift($parts);
        $root_id    = array_shift($parts);

        if($root_id == $store_root_id)
        {
            $category_ids[] = $cat->getId();    
        }            
    }

    var_dump($category_ids);

Upvotes: 0

Related Questions