4

According to answer to this related question the AND condition in addAttributeToFilter is added by adding consecutive addAttributeToFilter so my statement is something like;

$_productCollection->addAttributeToSelect('*')->addAttributeToFilter('manufacturer', array(
                    array('nin' => $brands)
                ))->addAttributeToFilter('warehouse1', array(
                    array('nin' => 0)
                ))->addAttributeToFilter('warehouse4', array(
                    array('nin' => 0)
                )); // I want product to be excluded when both warehouse1 and warehouse4 is 0

As in the code above I need the product to be removed from collection when both "warehouse1" and "warehouse4" are simultaneously 0 but instead the code is first filtering collection based on "warehouse1" and then the filtered collection is filtered again for "warehouse4".
As a result I am also excluding products which have 0 for "warehouse1" but not a 0 for "warehouse4".
Please help me resolve this.

EDIT:

The answer by @Murtuza Zabuawala worked for me, it was not working before as some of the attributes had null for them even though they were supposed to be 0 by default. However, this does not answer the core question of how to add AND to addAttributeToFilter but nonetheless I am going to award the bounty.

4
  • is warehouse1 and warehouse4 is type of select or multiselect Commented Aug 10, 2017 at 12:32
  • They are text fields Commented Aug 10, 2017 at 12:34
  • check updated answer and let me know if you still face any problem Commented Aug 11, 2017 at 5:22
  • @MurtuzaZabuawala Your updated answer applies OR condition between the addAttributetoFilter and is not giving desired result. Commented Aug 11, 2017 at 5:28

3 Answers 3

4
+50

try below code for and condition in two or more attribute

    $_productCollection->addAttributeToSelect('*')
    ->addAttributeToFilter('manufacturer', array(
                array('nin' => $brands)
            ))->addAttributeToFilter(
              array(
                array('attribute' => 'warehouse1', 'neq' => 0),
                array('attribute' => 'warehouse4', 'neq' => 0),
            ));

Edit

According TO your answer I have Improved your answer

$cloned_collection = clone $_productCollection;
$product_ids = $cloned_collection->addAttributeToSelect('*')->addAttributeToFilter('warehouse1', array(
                array('eq'=> '0'),
                array('null' => 'this_value_doesnt_matter'),
                array('eq' =>'0.00')    
            ))->addAttributeToFilter('warehouse4', array(
                array('eq'=> '0'),
                array('null' => 'this_value_doesnt_matter'),
                array('eq' =>'0.00')    
            ))->getAllIds();

$_productCollection =  $_productCollection->addAttributeToSelect('*')->addAttributeToFilter('entity_id',array('in' => $product_ids));

Edit2

$_productCollection->addAttributeToSelect('*')
        ->addAttributeToFilter('manufacturer', array(
                array('nin' => $brands)
            ))
        ->addAttributeToFilter('warehouse1',array('neq' => ''))
        ->addAttributeToFilter('warehouse4',array('neq' => ''))  //check wareHouse != null and add innerJoin
        ->getSelect()->where("at_warehouse1 <> 0 AND at_warehouse4 <> 0 ");    
12
  • This gives the same result as my code. Commented Aug 10, 2017 at 13:02
  • @Neo ... this is the solution. It should work. Commented Aug 17, 2017 at 0:10
  • @AlexConstantinescu This applies an OR condition .. Commented Aug 17, 2017 at 5:13
  • 1
    @John , I think its already answered at here, magento.stackexchange.com/questions/11082/… Commented Jun 14, 2018 at 7:11
  • 1
    Ah, yes that's what i found to do it, thank you Murtuza!
    – John
    Commented Jun 14, 2018 at 8:13
1

I have found a workaround though it is not elegant in any way and I still think there should be a way to do it in one step, Instead of filtering and removing the 0 in the first step itself I have made a collection which has both attributes 0 and it works as it is applying filter over the filter before [as I have explained in question].Then I am getting all skus from this collection to filter the required collection like below ;

$cloned_collection = clone $_productCollection;
$cloned_collection = $cloned_collection->addAttributeToSelect('*')->addAttributeToFilter('warehouse1', array(
                    array('eq'=> '0'),
                    array('null' => 'this_value_doesnt_matter'),
                    array('eq' =>'0.00')    
                ))->addAttributeToFilter('warehouse4', array(
                    array('eq'=> '0'),
                    array('null' => 'this_value_doesnt_matter'),
                    array('eq' =>'0.00')    
                ))->getData();
                for($i=0;$i<count($cloned_collection);$i++){
                    $skuArray[$i] = $cloned_collection[$i]['sku']; 
                }
$_productCollection =  $_productCollection->addAttributeToSelect('*')->addAttributeToFilter('sku', array('nin' => $skuArray));

Please let me know if someone has a better working solution.

2
1

In SQL you'd need warehouse1 != 0 OR warehouse4 != 0.

Or conditions are combined like this:

addFieldToFilter(['field1', 'field2'], [$condition1, $condition2]);

So in your case it is:

addAttributeToFilter(
    ['warehouse1', 'warehouse4'],
    [['neq' => 0], ['neq' => 0]],
);

Update: This syntax to combine OR conditions does not work anymore in Magento 2. Th correct way has been described by @MurtuzaZabuawala in his original answer:

addAttributeToFilter(
    [
        [
            'attribute' => 'warehouse1',
            'neq' => 0
        ],
        [
            'attribute' => 'warehouse4',
            'neq' => 0
        ],
    ]
);

This results in (warehouse1 != 0 OR warehouse4 != 0), which is the condition you need according to your description.

3
  • First of all above code gave a parse error on first run because of comma for second array , after fixing that it gives error Warning: Illegal string offset 'attribute' in Magento/Eav/Model/Entity/Collection/AbstractCollection.php on line 362 . Please atleast post working code. Commented Aug 14, 2017 at 8:19
  • Again, I need an AND condition, is that so hard to understand? This community is total garbage. Commented Aug 21, 2017 at 4:20
  • 1
    With personal insults you won't get better help, that's for sure. You need a negated AND which is equivalent to OR : ! ( A && B) == !A || !B. Basic boolean logic. Commented Aug 21, 2017 at 9:46

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.