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?

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.

  • 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? – Robbie Averill Sep 20 '16 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. – Fabian Schmengler Sep 20 '16 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!) – Robbie Averill Sep 20 '16 at 19:25
  • @RobbieAverill i run into this problem today .... anything new from support? – sv3n Jun 9 '17 at 17:09
  • No, I believe it came under a "won't fix" category – Robbie Averill Jun 9 '17 at 20:18

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.