0

we generate a list of $categoryIds like below. The problem is that it also returns some Ids that do not exist in the current store.

$categoryIds = Mage::registry('current_product')->getCategoryIds();

if (!empty($categoryIds)) {
  $categoryId = current($categoryIds);

Question: Now how can I solve this with low overhead. To me it seems like there are two methods.

  • Filter the complete $categoryIds collection and keep only members of current store? (something like: getting all categories from the store and sift out the ones that exisst on both stores)

  • Check the single categoryId from current, and shift to the next value if it does not exist? (something like: check if it can be loaded with a store_id and if not continue)

Reference, not completely similar

https://stackoverflow.com/questions/15505221/how-do-i-get-the-category-ids-that-a-product-is-in-with-respect-to-the-store-tha

3 Answers 3

1

First call category collection:

$Collection=Mage::getModel('catalog/category')->getCollection();

then filter them by setStoreId(Current_Store_Id) and $categoryIds

$filterIds=$Collection
            ->setStoreId(Mage::app()->getStore()->getId())
            ->addIdFilter($product->getCategoryIds())
            -getAllIds(); // get ids of categories

Edited code:

$categoryIds = Mage::registry('current_product')->getCategoryIds();
$filterIds=Mage::getModel('catalog/category')->getCollection()
            ->setStoreId(Mage::app()->getStore()->getId())
            ->addIdFilter($categoryIds)
            -getAllIds(); 

if (!empty($filterIds)) {

.....

2
  • Ay ay, loading an entire collection is shooting yourself in the foot. Commented Sep 18, 2015 at 10:16
  • This does work ....................
    – snh_nl
    Commented Sep 18, 2015 at 14:52
1

It's a bit complicated because unfortunately there is no relation between categories and stores, only the status is relevant. The cleanest way to achieve this, is to override Mage_Catalog_Model_Resource_Product and change this function into:

public function getCategoryIds($product, $storeId = null)
{

    $adapter = $this->_getReadAdapter();

    $select = $adapter->select()
        ->from($this->_productCategoryTable, 'category_id');

    if(!is_null($storeId) && Mage::helper('catalog/category_flat')->isEnabled()) {

        $categoryTable = $this->getTable('catalog_category_flat_store_'.$storeId);  
        if(!is_null($categoryTable))
           $select->join(array('cat_table' => $categoryTable), 'cat_table.entity_id = category_id AND is_active = 1', array());
    }

    $select->where('product_id = ?', (int)$product->getId());

    return $adapter->fetchCol($select);
}

Then you can pass the store ID as an argument to filter the selection. It's a bit less straightforward than loading an entire collection but it's much more efficient. Also it relies on Catalog Category Flat to be enabled, but this should be enabled on your store anyway (if it's not, I recommend you to turn it on)

5
  • Good Works @Mayer ..
    – Amit Bera
    Commented Sep 18, 2015 at 10:18
  • Thanks! I have no means of overriding this ... and that would surpass the scope ... would there be another method to check this? Maybe using array comparison?
    – snh_nl
    Commented Sep 18, 2015 at 10:32
  • As Amit suggested, you could load the collection $categories = Mage::getModel('catalog/category')->getCollection()->setStoreId($storeId)->addAttributeToSelect('entity_id')->getAllIds(); but in terms of performance, it's really not ideal Commented Sep 18, 2015 at 10:36
  • I am trying $categoryIds = Mage::registry('current_product')->getCategoryIds(); $StoreCategories = Mage::getModel('catalog/category') ->getCollection()->setStoreId(Mage::app()->getStore()->getStoreId()) ->addAt‌​tributeToSelect('entity_id')->getAllIds(); $categoryIds = array_intersect($categoryIds, $StoreCategories); but get an error; Fatal error: Call to undefined method Mage_Catalog_Model_Resource_Category_Flat_Collection::addAt‌​tributeToSelect() ... hint?
    – snh_nl
    Commented Sep 18, 2015 at 10:54
  • It should work without the addAttributeToSelect. Although, I would really stress that this will have an impact on performance. Spend an extra half an hour doing your override, and save time on your page load. Commented Sep 18, 2015 at 10:58
0

$categoryIds = Mage::registry('current_product')->getCategoryIds();

Ofcourse: your ASKING a product. "In witch categories are you ?"

The awnser is accurate and exacly what your asked for.

So you have to ask something else: 'Hey, product: can you please give me a collection from all your categories where the category is enabled for a specific store? Yes, ofcourse no problem dude...

<?php

include_once('../initMage.php');
initMage();

// 880 = Test product that is in category that isn't active in default store
$product = Mage::getModel('catalog/product')->load(880);
foreach (array('default', 'german') as $store) {
  $categoriesCollection = $product->getCategoryCollection()
                                  ->setStore($store)
                                  ->addAttributeToFilter('is_active', true);
  foreach ($categoriesCollection as $category) {
    echo $store, PHP_EOL;
    var_dump($category->getData());
    echo PHP_EOL, PHP_EOL;
  }
}

But you can also re-write models or just adjust Magento core files. ;-)

5
  • Are you suggesting that I loop over the stores? 2 remarks: we already have the $store_id + we need the ID's: $categoriesCollection = $product->getCategoryCollection() ->setStore($store) ->addAttributeToFilter('is_active', true); So how would I use setStore to use as an ID? + does addAttributeToFilter work for flat tables?
    – snh_nl
    Commented Sep 18, 2015 at 14:54
  • Would something like this work? CategoryIds = $product->getCategoryCollection()->setStoreId(Mage::app()->getStore()->getId())->addAttributeToFilter('is_active', true)->getCategoryIds();
    – snh_nl
    Commented Sep 18, 2015 at 15:14
  • It's a TEST EXAMPLE ! Ofcourse your not looping over your stores. How else do you know the code works if your not testing it.Open file 'Mage_Catalog_Model_Resource_Collection_Abstract' and look for setStore and setStoreId. Asking questions is good, but don't just ask: "can you please give me code i can copy past and sell to my customers...." Commented Sep 20, 2015 at 12:41
  • Thanks Roger. I will solve it myself. Don't understand your comment about "selling": what do you mean?
    – snh_nl
    Commented Sep 20, 2015 at 12:45
  • You don't have to solve something that is already implemented by the Magento development team. It's Magento not rocket science. Commented Sep 20, 2015 at 13:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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