Intereting Posts
как объявить php-класс с именем переменной Предотвращение повторного выполнения сценария при обновлении страницы Как эффективно заменить (mysql_result (mysql_query ()) в PDO? Можно ли отключить переменную сеанса с определенным и переменным индексом? Как очистить html пользователю от GAE / PHP? Передача массива объектов из WCF в PHP – извлечение информации Как получить разницу в времени для чтения человеком с помощью Laravel 5 Ленивая загрузка из базы данных, когда пользователь прокручивает страницу вниз (аналогично Twitter и Facebook) Как получить значение переменной JavaScript в PHP Может ли внутренняя сеть PHP совместно использовать учетные записи Windows? Symfony и Doctrine – не могут удалить элемент из коллекции (отношение Many-to-Many с дополнительным полем) drupal 7 пользовательская ошибка схемы datetime конвертировать php-ассоциативный массив в объект javascript FPDF, создайте PDF с помощью структуры заголовка таблицы уровня дерева с закругленными углами Как я могу использовать свою учетную запись GMAIL для отправки электронной почты с помощью PHP?

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

Я застрял на этом в течение последних нескольких часов. Я получил его работу, взломав несколько строк в /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). Благодаря!

У меня есть другой способ добавить условие or условие в поле:

 ->addFieldToFilter( array('title', 'content'), array( array('like'=>'%$titlesearchtext%'), array('like'=>'%$contentsearchtext%') ) ) 

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

 $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')) ) 

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

Я также попытался получить field1 = 'a' OR field2 = 'b'

Ваш код не работал для меня.

Вот мое решение

 $results = Mage::getModel('xyz/abc')->getCollection(); $results->addFieldToSelect('name'); $results->addFieldToSelect('keywords'); $results->addOrder('name','ASC'); $results->setPageSize(5); $results->getSelect()->where("keywords like '%foo%' or additional_keywords like '%bar%'"); $results->load(); echo json_encode($results->toArray()); конкретные $results = Mage::getModel('xyz/abc')->getCollection(); $results->addFieldToSelect('name'); $results->addFieldToSelect('keywords'); $results->addOrder('name','ASC'); $results->setPageSize(5); $results->getSelect()->where("keywords like '%foo%' or additional_keywords like '%bar%'"); $results->load(); echo json_encode($results->toArray()); конкретные $results = Mage::getModel('xyz/abc')->getCollection(); $results->addFieldToSelect('name'); $results->addFieldToSelect('keywords'); $results->addOrder('name','ASC'); $results->setPageSize(5); $results->getSelect()->where("keywords like '%foo%' or additional_keywords like '%bar%'"); $results->load(); echo json_encode($results->toArray()); конкретные $results = Mage::getModel('xyz/abc')->getCollection(); $results->addFieldToSelect('name'); $results->addFieldToSelect('keywords'); $results->addOrder('name','ASC'); $results->setPageSize(5); $results->getSelect()->where("keywords like '%foo%' or additional_keywords like '%bar%'"); $results->load(); echo json_encode($results->toArray()); конечные $results = Mage::getModel('xyz/abc')->getCollection(); $results->addFieldToSelect('name'); $results->addFieldToSelect('keywords'); $results->addOrder('name','ASC'); $results->setPageSize(5); $results->getSelect()->where("keywords like '%foo%' or additional_keywords like '%bar%'"); $results->load(); echo json_encode($results->toArray()); конечные $results = Mage::getModel('xyz/abc')->getCollection(); $results->addFieldToSelect('name'); $results->addFieldToSelect('keywords'); $results->addOrder('name','ASC'); $results->setPageSize(5); $results->getSelect()->where("keywords like '%foo%' or additional_keywords like '%bar%'"); $results->load(); echo json_encode($results->toArray()); 

Это дает мне

SELECT name, keywords FROM abc WHERE keywords like '%foo%' OR additional_keywords like '%bar%' .

Возможно, это не «пурпурный путь», но я застрял на нем 5 часов.

Надеюсь, это поможет

Вот мое решение в 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))) 

Для фильтрации по нескольким атрибутам используйте что-то вроде:

 //for AND $collection = Mage::getModel('sales/order')->getCollection() ->addAttributeToSelect('*') ->addFieldToFilter('my_field1', 'my_value1') ->addFieldToFilter('my_field2', 'my_value2'); echo $collection->getSelect()->__toString(); //for OR - please note 'attribute' is the key name and must remain the same, only replace //the value (my_field1, my_field2) with your attribute name $collection = Mage::getModel('sales/order')->getCollection() ->addAttributeToSelect('*') ->addFieldToFilter( array( array('attribute'=>'my_field1','eq'=>'my_value1'), array('attribute'=>'my_field2', 'eq'=>'my_value2') ) ); 

Для получения дополнительной информации проверьте: http://docs.magentocommerce.com/Varien/Varien_Data/Varien_Data_Collection_Db.html#_getConditionSql

Спасибо 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 сначала требует поля, а затем условие -> ссылка.

Здесь немного путаницы, но позвольте мне попытаться прояснить ситуацию:

Допустим, вы хотели, чтобы sql выглядел примерно так:

 SELECT `main_table`.*, `main_table`.`email` AS `invitation_email`, `main_table`.`group_id` AS `invitee_group_id` FROM `enterprise_invitation` AS `main_table` WHERE ( (status = 'new') OR (customer_id = '1234') ) 

Чтобы добиться этого, ваша коллекция должна быть отформатирована следующим образом:

 $collection = Mage::getModel('enterprise_invitation/invitation')->getCollection(); $collection->addFieldToFilter(array('status', 'customer_id'), array( array('status','eq'=>'new'), array('customer_id', 'eq'=>'1234') )); 

Теперь, чтобы понять, как это выглядит, вы всегда можете эхо-запрос, созданный с помощью

 echo $collection->getSelect()->__toString(); 
 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

Чтобы создать простое условие OR для коллекции, используйте следующий формат:

  $orders = Mage::getModel('sales/order')->getResourceCollection(); $orders->addFieldToFilter( 'status', array( 'processing', 'pending', ) ); в  $orders = Mage::getModel('sales/order')->getResourceCollection(); $orders->addFieldToFilter( 'status', array( 'processing', 'pending', ) ); 

Это создаст SQL следующим образом:

 WHERE (((`status` = 'processing') OR (`status` = 'pending'))) 

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

  $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 ) ) );