[php] Magento addFieldToFilter: два поля, совпадающие с OR, а не AND


Answers

ИЛИ могут быть сгенерированы следующим образом:

$collection->addFieldToFilter(
    array('field_1', 'field_2', 'field_3'), // columns
    array( // conditions
        array( // conditions for field_1
            array('in' => array('text_1', 'text_2', 'text_3')),
            array('like' => '%text')
        ),
        array('eq' => 'exact'), // condition for field 2
        array('in' => array('val_1', 'val_2')) // condition for field 3
    )
);

Это создаст условие SQL WHERE:

... WHERE (
         (field_1 IN ('text_1', 'text_2', 'text_3') OR field_1 LIKE '%text')
      OR (field_2 = 'exact')
      OR (field_3 IN ('val_1', 'val_2'))
    )

Каждый вложенный массив (<условие>) генерирует другой набор круглых скобок для условия ИЛИ.

Question

Я застрял на этом в течение последних нескольких часов. Я получил его работу, взломав несколько строк в /lib/Varien/Data/Collection/Db.php , но я предпочел бы использовать правильное решение и оставить свое ядро ​​нетронутым.

Все, что мне нужно сделать, это собрать коллекцию и отфильтровать ее двумя или более полями. Скажем, customer_firstname и remote_ip . Вот мой код (disfunctional without hacking Db.php ):

$collection = Mage::getModel('sales/order')->getCollection()->
addAttributeToSelect("*")->
addFieldToFilter(array(array('remote_ip', array('eq'=>'127.0.0.1')),
array('customer_firstname', array('eq'=>'gabe'))), array('eq'=>array(1,2,3)));

С запасом Db.php я попробовал это: (образец взят из http://magentoexpert.blogspot.com/2009/12/retrieve-products-with-specific.html )

$collection->addFieldToFilter(array(
    array('name'=>'orig_price','eq'=>'Widget A'),
    array('name'=>'orig_price','eq'=>'Widget B'),           
));

Но это дает мне эту ошибку:

Warning: Illegal offset type in isset or empty  in magento/lib/Varien/Data/Collection/Db.php on line 369

Если я обернуть это с помощью try / catch, то он переместится в _getConditionSql () и даст следующую ошибку:

Warning: Invalid argument supplied for foreach()  in magento/lib/Varien/Data/Collection/Db.php on line 412

У кого-нибудь есть рабочий, функциональный код для этого? Я запускаю Magento 1.9 (Enterprise). Благодаря!




Это реальный пурпурный путь:

    $collection=Mage::getModel('sales/order')
                ->getCollection()
                ->addFieldToFilter(
                        array(
                            'customer_firstname',//attribute_1 with key 0
                            'remote_ip',//attribute_2 with key 1
                        ),
                        array(
                            array('eq'=>'gabe'),//condition for attribute_1 with key 0
                            array('eq'=>'127.0.0.1'),//condition for attribute_2
                                )
                            )
                        );



public function testAction()
{
        $filter_a = array('like'=>'a%');
        $filter_b = array('like'=>'b%');
        echo(
        (string) 
        Mage::getModel('catalog/product')
        ->getCollection()
        ->addFieldToFilter('sku',array($filter_a,$filter_b))
        ->getSelect()
        );
}

Результат:

WHERE (((e.sku like 'a%') or (e.sku like 'b%')))

Источник: http://alanstorm.com/magento_collections




Вот мое решение в Enterprise 1.11 (должно работать в CE 1.6):

    $collection->addFieldToFilter('max_item_count',
                    array(
                        array('gteq' => 10),
                        array('null' => true),
                    )
            )
            ->addFieldToFilter('max_item_price',
                    array(
                        array('gteq' => 9.99),
                        array('null' => true),
                    )
            )
            ->addFieldToFilter('max_item_weight',
                    array(
                        array('gteq' => 1.5),
                        array('null' => true),
                    )
            );

Что приводит к этому SQL:

    SELECT `main_table`.*
    FROM `shipping_method_entity` AS `main_table`
    WHERE (((max_item_count >= 10) OR (max_item_count IS NULL)))
      AND (((max_item_price >= 9.99) OR (max_item_price IS NULL)))
      AND (((max_item_weight >= 1.5) OR (max_item_weight IS NULL)))



Спасибо Anda, ваш пост был отличной помощью! Однако предложение OR не работало для меня, и я получал ошибку: getCollection () «недопустимый аргумент, предоставленный foreach» .

Так вот что я закончил (обратите внимание, что в этом случае атрибут указывается 3 раза вместо 2):

  $collection->addFieldToFilter('attribute', array(  
    array('attribute'=>'my_field1','eq'=>'my_value1'),            
    array('attribute'=>'my_field2','eq'=>'my_value2') ));

addFieldToFilter сначала требует поля, а затем условие -> link.




Related