4

I've got a simple varchar product attribute, let's call it "badge".

If I set values for it programmatically for a set of products like this:

Mage::getModel('catalog/product_action')
    ->updateAttributes($productIds, ['badge' => 123, $store->getId());

... then I inspect the catalog_product_entity_varchar table for that attribute value, I correctly see that 123 has been assigned to the badge attribute for those products, at the given store level. Great!

Now, if I create an EAV product collection by getting child products from a configurable and try and select the value, I can't:

$collection = $configurable->getTypeInstance(true)->getUsedProductCollection();
$collection->addAttributeToSelect('badge');

foreach ($collection as $product) { /** @var Mage_Catalog_Model_Product $product */
    var_dump($product->getBadge()); // NULL
}

On closer inspection the varchar attribute values are assigned at the store level, but there's no default level value. If I manually insert a value at the global/admin level (doesn't matter what the value is), then the same code above works as it should.

Examining app/code/core/Mage/Catalog/Model/Resource/Collection/Abstract.php I see that it selects attribute values from the default store level then does a left join to the specified store level to get the store value. It returns whichever exists from store -> default priority.

I understand that setting values via $product->setBadge(123)->save() would also create a default value, but that's much slower, and not really the point of this question anyway.

FYI if I edit the abstract collection and switch the order around, i.e. select from the store level value and left join the default value it returns the value in my example code correctly - that was just to test the point, it's obviously not sustainable.

Question: This methodology obviously doesn't work due to a limitation in the core catalog collection. How can I efficiently set store level attribute values for large numbers of products (using vanilla Magento) while still being able to retrieve their values in a child product (EAV) collection?

1 Answer 1

3

Oh, I love this bug... the only reasonable way I found to get around it was to always make sure that there is a NULL default value (for example in the product import)

If this helps you: setting a NULL default value for existing products can be easily done in the backend:

  1. open product grid
  2. select all
  3. update attributes
  4. submit
  5. check "change" checkbox for "badge" attribute but leave input field empty
  6. save

This immediately updates the index as well.

5
  • Thanks Fabian. I'm doing that at the moment as a workaround using the same product action call just with null and admin store ID. I guess it's a "bug" in terms of the magento framework but not because you couldn't (?) reproduce it from the admin interface?
    – scrowler
    Commented Sep 20, 2016 at 19:21
  • I consider this a bug in the framework, yes. Just from the admin interface I don't think it's possible to run into it. Commented Sep 20, 2016 at 19:25
  • Cool. I've logged a EE support ticket with magento, will update with any info they provide (if I'm allowed to!)
    – scrowler
    Commented Sep 20, 2016 at 19:25
  • @RobbieAverill i run into this problem today .... anything new from support?
    – sv3n
    Commented Jun 9, 2017 at 17:09
  • No, I believe it came under a "won't fix" category
    – scrowler
    Commented Jun 9, 2017 at 20:18

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.