2

Can somebody explain why setCategoryIds($ids) changes the product's visibility to Catalog,Search from whatever else it was (in my encounter, I was working with Search-view products)?

Here's the code that makes all of the products in $categoryId to have visibility Catalog,Search after the save() when they originally had Search. I restored all of my products and tested it to verify as well.

$productCollection = Mage::getModel('catalog/category')->load($categoryId)
    ->getProductCollection() 
    ->addAttributeToSelect(array('name','price','special_price','sku','small_image'));

foreach($productCollection as $product) {
    $catIds = $product->getCategoryIds();
    $product->setCategoryIds($catIds);
    $product->save();
}

1 Answer 1

7

The reason is that you're saving the product but you've not loaded the visibility as part of the product collection. Catalog, Search is the default visibility.

Try this:

$productCollection = Mage::getModel('catalog/category')->load($categoryId)
    ->getProductCollection() 
    ->addAttributeToSelect(array('name','price','special_price','sku','small_image'))
    ->joinAttribute('visibility', 'catalog_product/visibility', 'entity_id', null, 'inner');

Now when you save the product it should retain its original visibility setting.

6
  • Ah.. Is there anything else that is "required" I need to set before the save? So that I don't unintentionally override current values with default values.
    – laketuna
    Commented Sep 5, 2013 at 17:46
  • Visibility is the main culprit - however if you're trying to do things in the future like saving URL keys you need to join the attribute to the collection to be able to explicitly create rewrites, etc.
    – philwinkle
    Commented Sep 5, 2013 at 17:48
  • So, the joinAttribute is bringing the data that the given product already has when you do the inner join, right? Could you do setVisibility(...) instead?
    – laketuna
    Commented Sep 5, 2013 at 17:51
  • Also, I implemented Mage::getSingleton('catalog/category_api')->removeProduct(..)/assignProduct(..) meanwhile, and this seems to work just in the category scope. Is this method safe with other data?
    – laketuna
    Commented Sep 5, 2013 at 17:52
  • To my knowledge setVisibility would work but you really shouldn't have to re-set the visibility if it's joined already as part of the collection. The category API question is probably beyond the scope of the comments section but that sounds feasible.
    – philwinkle
    Commented Sep 5, 2013 at 19:17

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.