php magento magento-1.9

php - Magento addFieldToFilter: dos campos, coinciden como OR, no como Y



magento-1.9 (10)

Estuve atascado en esto durante las últimas horas. Lo conseguí trabajando hackeando unas pocas líneas en /lib/Varien/Data/Collection/Db.php , pero prefiero usar la solución adecuada y dejar mi núcleo intacto.

Todo lo que necesito hacer es obtener una colección y filtrarla por dos o más campos. Diga, customer_firstname y remote_ip . Aquí está mi código (disfuncional sin hackear 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)));

Con un stock Db.php , probé esto: (muestra tomada de 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''), ));

Pero eso me da este error:

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

Si envuelvo eso con un try / catch, se mueve a _getConditionSql () y da este error:

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

¿Alguien tiene algún código operativo y funcional para hacer esto? Estoy ejecutando Magento 1.9 (Enterprise). ¡Gracias!


¡Gracias Anda, tu publicación ha sido de gran ayuda! Sin embargo, la oración OR no funcionó para mí y recibí un error: getCollection () "argumento inválido suministrado para foreach" .

Así que esto es lo que terminé con (observe el atributo que se especifica 3 veces en lugar de 2 en este caso):

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

addFieldToFilter primero requiere un campo y luego condición -> link.


Aquí está mi solución en Enterprise 1.11 (debería funcionar en 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), ) );

Lo que resulta en este 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)))


Esta es la verdadera manera magento:

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


Hay un poco de confusión pasando aquí, pero déjame intentar aclarar cosas:

Digamos que querías SQL que se pareciera a algo así:

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

Para lograr esto, su colección debe formatearse así:

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

Ahora, para ver cómo se ve, siempre puede hacerse eco de la consulta que esto crea al usar

echo $collection->getSelect()->__toString();


O las condiciones se pueden generar así:

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

Esto generará una condición SQL DONDE algo así como:

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

Cada matriz anidada (<condición>) genera otro conjunto de paréntesis para una condición OR.


Para crear una condición OR sencilla para la recopilación, use el siguiente formato:

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

Esto producirá SQL así:

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


Para filtrar por atributos múltiples, use algo como:

//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'') ) );

Para obtener más información, consulte: http://docs.magentocommerce.com/Varien/Varien_Data/Varien_Data_Collection_Db.html#_getConditionSql


También traté de obtener el field1 = ''a'' OR field2 = ''b''

Tu código no funcionó para mí.

Aquí está mi solución

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

Me da

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

Tal vez no sea el "camino del magento", pero estuve atrapado 5 horas en eso.

Espero que ayude


Tengo otra forma de agregar una or una condición en el campo:

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


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() ); }

Resultado:

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

Fuente: http://alanstorm.com/magento_collections