La collection Magento a deux méthodes pour filtrer différentes
- Varien_Data_Collection_Db :: addFieldToFilter
addFieldToFilter ($ champ, $ condition = null)
Le premier paramètre de addFieldToFilter
est l'attribut que vous souhaitez filtrer. La seconde est la valeur que vous recherchez. Voici que nous ajoutons un sku
filtre pour la valeur n2610
.
Le deuxième paramètre peut également être utilisé pour spécifier le type de filtrage que vous souhaitez effectuer. C'est là que les choses se compliquent un peu et valent la peine d'être approfondies.
Donc, par défaut, ce qui suit
$collection_of_products->addFieldToFilter('sku','n2610');
est (essentiellement) équivalent à
WHERE sku = "n2610"
Regardez vous même. Exécution de ce qui suit
public function testAction()
{
var_dump(
(string)
Mage::getModel('catalog/product')
->getCollection()
->addFieldToFilter('sku','n2610')
->getSelect());
}
donnera
SELECT `e`.* FROM `catalog_product_entity` AS `e` WHERE (e.sku = 'n2610')'
Gardez à l'esprit que cela peut se compliquer rapidement si vous utilisez un attribut EAV. Ajouter un attribut
var_dump(
(string)
Mage::getModel('catalog/product')
->getCollection()
->addAttributeToSelect('*')
->addFieldToFilter('meta_title','my title')
->getSelect()
);
et la requête devient noueuse.
SELECT `e`.*, IF(_table_meta_title.value_id>0, _table_meta_title.value, _table_meta_title_default.value) AS `meta_title`
FROM `catalog_product_entity` AS `e`
INNER JOIN `catalog_product_entity_varchar` AS `_table_meta_title_default`
ON (_table_meta_title_default.entity_id = e.entity_id) AND (_table_meta_title_default.attribute_id='103')
AND _table_meta_title_default.store_id=0
LEFT JOIN `catalog_product_entity_varchar` AS `_table_meta_title`
ON (_table_meta_title.entity_id = e.entity_id) AND (_table_meta_title.attribute_id='103')
AND (_table_meta_title.store_id='1')
WHERE (IF(_table_meta_title.value_id>0, _table_meta_title.value, _table_meta_title_default.value) = 'my title')
Ne pas insister sur le point, mais essayez de ne pas trop penser au SQL si vous êtes dans les délais.
Autres opérateurs de comparaison Je suis sûr que vous vous demandez «et si je veux autre chose qu'un égal par requête»? Pas égal, supérieur à, inférieur à, etc. Le deuxième paramètre de la méthode addFieldToFilter vous a également couvert. Il prend en charge une syntaxe alternative où, au lieu de passer dans une chaîne, vous passez dans un seul élément Array.
La clé de ce tableau est le type de comparaison que vous souhaitez faire. La valeur associée à cette clé est la valeur que vous souhaitez filtrer. Refaisons le filtre ci-dessus, mais avec cette syntaxe explicite
public function testAction()
{
var_dump(
(string)
Mage::getModel('catalog/product')
->getCollection()
->addFieldToFilter('sku',array('eq'=>'n2610'))
->getSelect()
);
}
Appeler notre filtre
addFieldToFilter('sku',array('eq'=>'n2610'))
Comme vous pouvez le voir, le deuxième paramètre est un tableau PHP. Sa clé est eq, qui signifie égal. La valeur de cette clé est n2610, qui est la valeur sur laquelle nous filtrons.
Magento a un certain nombre de ces filtres de langue anglaise qui apporteront une larme de souvenir (et peut-être de la douleur) à tous les vieux développeurs de Perl dans le public.
Vous trouverez ci-dessous tous les filtres, ainsi qu'un exemple de leurs équivalents SQL.
array("eq"=>'n2610')
WHERE (e.sku = 'n2610')
array("neq"=>'n2610')
WHERE (e.sku != 'n2610')
array("like"=>'n2610')
WHERE (e.sku like 'n2610')
array("nlike"=>'n2610')
WHERE (e.sku not like 'n2610')
array("is"=>'n2610')
WHERE (e.sku is 'n2610')
array("in"=>array('n2610'))
WHERE (e.sku in ('n2610'))
array("nin"=>array('n2610'))
WHERE (e.sku not in ('n2610'))
array("notnull"=>'n2610')
WHERE (e.sku is NOT NULL)
array("null"=>'n2610')
WHERE (e.sku is NULL)
array("gt"=>'n2610')
WHERE (e.sku > 'n2610')
array("lt"=>'n2610')
WHERE (e.sku < 'n2610')
array("gteq"=>'n2610')
WHERE (e.sku >= 'n2610')
array("moreq"=>'n2610') //a weird, second way to do greater than equal
WHERE (e.sku >= 'n2610')
array("lteq"=>'n2610')
WHERE (e.sku <= 'n2610')
array("finset"=>array('n2610'))
WHERE (find_in_set('n2610',e.sku))
array('from'=>'10','to'=>'20')
WHERE e.sku >= '10' and e.sku <= '20'
La plupart d'entre elles sont explicites, mais quelques-unes méritent une légende spéciale
in, nin, find_in_set Les conditions in et nin vous permettent de transmettre un tableau de valeurs. Autrement dit, la partie valeur de votre tableau de filtres est elle-même autorisée à être un tableau.
array("in"=>array('n2610','ABC123')
WHERE (e.sku in ('n2610','ABC123'))
notnull, null Le mot-clé NULL est spécial dans la plupart des versions de SQL. Il ne jouera généralement pas bien avec l'opérateur d'égalité standard (=). Si vous spécifiez notnull ou null comme type de filtre, vous obtiendrez la syntaxe correcte pour une comparaison NULL tout en ignorant la valeur que vous transmettez.
array("notnull"=>'n2610')
WHERE (e.sku is NOT NULL)
from - to filter Il s'agit d'un autre format spécial qui enfreint la règle standard. Au lieu d'un seul tableau d'éléments, vous spécifiez un tableau à deux éléments. Un élément a la clé de, l'autre élément a la clé de. Comme les touches l'indiquent, ce filtre vous permet de construire une plage de / vers sans avoir à vous soucier des symboles supérieur et inférieur à
public function testAction
{
var_dump(
(string)
Mage::getModel('catalog/product')
->getCollection()
->addFieldToFilter('price',array('from'=>'10','to'=>'20'))
->getSelect()
);
}
Les rendements ci-dessus
WHERE (_table_price.value >= '10' and _table_price.value <= '20')'
ET ou OU, ou est-ce que OU et ET? Enfin, nous arrivons aux opérateurs booléens. C'est le moment rare où nous ne filtrons que par un attribut. Heureusement, les collections de Magento nous couvrent. Vous pouvez enchaîner plusieurs appels à addFieldToFilter pour obtenir un certain nombre de requêtes «AND».
function testAction()
{
echo(
(string)
Mage::getModel('catalog/product')
->getCollection()
->addFieldToFilter('sku',array('like'=>'a%'))
->addFieldToFilter('sku',array('like'=>'b%'))
->getSelect()
);
}
En enchaînant plusieurs appels comme ci-dessus, nous produirons une clause where qui ressemble à ce qui suit
WHERE (e.sku like 'a%') AND (e.sku like 'b%')
Pour ceux d'entre vous qui viennent de lever la main, oui, l'exemple ci-dessus retournerait toujours 0 enregistrement. Aucun sku ne peut commencer par les deux a et b. Ce que nous voulons probablement ici, c'est une requête OU. Cela nous amène à un autre aspect déroutant du deuxième paramètre addFieldToFilter.
Si vous souhaitez créer une requête OR, vous devez passer un tableau de tableaux de filtres en tant que deuxième paramètre. Je trouve qu'il est préférable d'attribuer vos tableaux de filtres individuels à des variables
public function testAction()
{
$filter_a = array('like'=>'a%');
$filter_b = array('like'=>'b%');
}
puis attribuer un tableau de toutes mes variables de filtre
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()
);
}
Pour être explicite, voici le tableau de tableaux de filtres susmentionné.
array($filter_a,$filter_b)
Cela nous donnera une clause WHERE qui ressemble à ce qui suit
WHERE (((e.sku like 'a%') or (e.sku like 'b%')))
- Varien_Data_Collection :: addFilter
addFilter($field, $value, $type = 'and')
addFilter()
permet uniquement de filtrer un seul champ par une seule valeur et un type. $type
peut être:
- "et" (par défaut) - ajoute la valeur AND $ field = $ à la clause WHERE
- "ou" - ajoute "OR $ field = $ value à la clause WHERE
Voir plus de détails
addFilter
avecattributes
?