I have created a new product eav attribute, assume it is created correctly. Now I write something in this attribute in some products (5 for example), and I delete it from some of them (4). So this attribute only exist in 5 products, one is written and other 4 are null, but it doesn't exist yet in rest of products.
How do I get all product which don't have that attribute set or have it null?
I can do it with ones that have this value set:
$_products = Mage::getModel('catalog/product')
->getCollection()
->addAttributeToSelect(array('sku', 'name', 'newfield'))
->addAttributeToFilter(
array(
array('attribute'=> 'newfield','null' => true),
array('attribute'=> 'newfield','eq' => '')
));
But it returns me only the 4 products that I have written and erased 'newfield', and not rest of products that doesn't have it set yet.
Edit:
I found a half solution (Filter collection by existence of attribute).
$_products = Mage::getModel('catalog/product')
->getCollection()
->addAttributeToSelect(array('sku', 'name', 'gtin'))
->addAttributeToFilter('newfield', array('null' => true), 'left');
I do not understand the third argument 'left', but this one returns me all the products with NULL in the newfield or where it does not exist yet (more than 13000 products), but I want to make an OR condition, I also want the products that contains string(0) "" or string(8) "NO FIELD"
I tried
$_products = Mage::getModel('catalog/product')
->getCollection()
->addAttributeToSelect(array('sku', 'name', 'newfield'))
->addAttributeToFilter(
array(
array('attribute'=> 'newfield','null' => true, 'left'),
array('attribute'=> 'newfield','eq' => ''),
array('attribute'=> 'newfield','eq' => 'NO FIELD')
));
But it is not acting like an OR condition and I only get back 3 results instead of more than 13000, probably it is because i'm not using the third argument 'left' properly.
Edit2:
I finally found something about the third parameter 'left' here (http://blog.adin.pro/2013-03-07/left-join-on-addattributetofilter-with-eav-tables/). But I see that I'm using like this in my OR condition and still getting only 3 results instead of more than 13000. What am I doing wrong here?
Edit3: Seems a definitive solution
I finally found this (https://hannah.wf/snippet-magento-using-or-and-left-join-in-addattributetofilter/), and then I made it:
$_products = Mage::getModel('catalog/product')
->getCollection()
->addAttributeToSelect(array('sku', 'name', 'newfield'))
->addAttributeToFilter(
array(
array('attribute'=> 'newfield','null' => true),
array('attribute'=> 'newfield','eq' => ''),
array('attribute'=> 'newfield','eq' => 'NO FIELD')
),
'',
'left');
It seems to return all the products I'm looking for, but I don't understand why it has to end with:
[...]
,
'',
'left');
My own logic says it should be
[...]
,
'left', //for the first condition
'', //for the second condition
''); //for the thrid condition
but my logic is returning only 3 results, so it's not working. The first one seems to work fine, but I don't understand why '', 'left'
.
array('attribute'=> 'newfield','eq' => '')
from filterarray('attribute'=> 'newfield','eq' => '')
it's not working. Leavingarray('attribute'=> 'newfield','null' => true) only
only returns the products where thenewfield
is set and isNULL
, the only difference is that the products where the fields contain a string(0) "" are not returned.