Magento addFieldToFilter: deux champs, match as OR, not et
je suis coincé sur cette depuis quelques heures. J'ai eu de travail par le piratage de quelques lignes dans /lib/Varien/Data/Collection/Db.php
, mais je préfère utiliser la bonne solution et laisser mon cœur intact.
Tout ce que je dois faire est d'obtenir une collection et filtrer par deux ou plusieurs champs. Dire, customer_firstname
et remote_ip
. Voici mon (dysfonctionnel sans hacking Db.php
) code:
$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)));
avec un stock Db.php
, j'ai essayé ceci: (échantillon prélevé à partir 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'),
));
Mais ça me donne cette erreur:
Warning: Illegal offset type in isset or empty in magento/lib/Varien/Data/Collection/Db.php on line 369
si je l'emballe avec un try / catch, alors il se déplace dans _getConditionSql () et donne cette erreur:
Warning: Invalid argument supplied for foreach() in magento/lib/Varien/Data/Collection/Db.php on line 412
est-ce que quelqu'un a un code fonctionnel pour faire ça? Je dirige Magento 1.9 (Enterprise). Merci!
10 réponses
j'en ai une autre façon d'ajouter un or
condition dans le champ:
->addFieldToFilter(
array('title', 'content'),
array(
array('like'=>'%$titlesearchtext%'),
array('like'=>'%$contentsearchtext%')
)
)
OU conditions peuvent être générés comme ceci:
$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
)
);
cela générera un SQL où la condition quelque chose comme:
... 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'))
)
chaque tableau imbriqué (
j'ai aussi essayé de mettre les field1 = 'a' OR field2 = 'b'
votre code n'a pas fonctionné pour moi.
Voici ma solution
$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());
Il me donne
SELECT name, keywords FROM abc WHERE keywords like '%foo%' OR additional_keywords like '%bar%'
.
ce n'est peut-être pas la "voie de magento" mais j'étais coincé 5 heures là-dessus.
j'Espère que ça aidera
voici ma solution dans L'entreprise 1.11 (devrait fonctionner dans 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),
)
);
ce qui donne ce 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)))
filtrer par plusieurs attributs d'utiliser quelque chose comme:
//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')
)
);
Pour plus d'informations, consultez: http://docs.magentocommerce.com/Varien/Varien_Data/Varien_Data_Collection_Db.html#_getConditionSql
Merci Anda, votre post a été d'une grande aide!! Cependant la phrase ou n'a pas tout à fait fonctionné pour moi et je recevais une erreur: getCollection ()"argument invalide fourni pour foreach".
donc c'est ce que j'ai terminé avec (notez que l'attribut est spécifié 3 fois au lieu de 2 dans ce cas):
$collection->addFieldToFilter('attribute', array(
array('attribute'=>'my_field1','eq'=>'my_value1'),
array('attribute'=>'my_field2','eq'=>'my_value2') ));
addFieldToFilter exige tout d'abord un champ et condition -> lien.
il y a un peu de confusion ici, mais laissez-moi essayer de clarifier les choses:
disons que vous vouliez sql qui ressemblait à quelque chose comme:
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')
)
pour ce faire, votre collection doit être formatée comme ceci:
$collection = Mage::getModel('enterprise_invitation/invitation')->getCollection();
$collection->addFieldToFilter(array('status', 'customer_id'), array(
array('status','eq'=>'new'),
array('customer_id', 'eq'=>'1234') ));
maintenant pour voir à quoi cela ressemble vous pouvez toujours faire écho à la requête que cela crée en utilisant
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()
);
}
Résultat:
WHERE (((e.sku like 'a%') or (e.sku like 'b%')))
http://alanstorm.com/magento_collections
pour créer simple ou condition pour la collecte, utilisez le format ci-dessous:
$orders = Mage::getModel('sales/order')->getResourceCollection();
$orders->addFieldToFilter(
'status',
array(
'processing',
'pending',
)
);
Ceci va produire SQL comme ceci:
WHERE (((`status` = 'processing') OR (`status` = 'pending')))
C'est le réel magento façon:
$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
)
)
);