2009-08-26 9 views
76

Dans mon code de bloc, j'essaie de récupérer par programme une liste de produits qui ont un attribut avec une valeur spécifique.Magento - Récupérer des produits avec une valeur d'attribut spécifique

Alternativement, si ce n'est pas possible, comment récupérer tous les produits, puis les filtrer pour simplement lister les produits avec un attribut spécifique? Comment effectuer une recherche à l'aide des filtres booléens standard AND ou OR pour faire correspondre un sous-ensemble de mes produits?

Répondre

160

Presque tous les modèles Magento possèdent un objet Collection correspondant qui peut être utilisé pour extraire plusieurs instances d'un modèle.

Pour instancier une collection de produits, procédez comme suit

$collection = Mage::getModel('catalog/product')->getCollection(); 

produits sont un modèle de style Magento EAV, vous aurez donc besoin d'ajouter des attributs supplémentaires que vous souhaitez revenir.

$collection = Mage::getModel('catalog/product')->getCollection(); 

//fetch name and orig_price into data 
$collection->addAttributeToSelect('name'); 
$collection->addAttributeToSelect('orig_price');  

Il existe plusieurs syntaxes pour définir des filtres sur des collections. J'utilise toujours le verbose ci-dessous, mais vous voudrez peut-être inspecter la source Magento pour d'autres façons d'utiliser les méthodes de filtrage.

Ce qui suit montre comment filtrer par une plage de valeurs (supérieure et inférieure)

$collection = Mage::getModel('catalog/product')->getCollection(); 
$collection->addAttributeToSelect('name'); 
$collection->addAttributeToSelect('orig_price');  

//filter for products whose orig_price is greater than (gt) 100 
$collection->addFieldToFilter(array(
    array('attribute'=>'orig_price','gt'=>'100'), 
)); 

//AND filter for products whose orig_price is less than (lt) 130 
$collection->addFieldToFilter(array(
    array('attribute'=>'orig_price','lt'=>'130'), 
)); 

Bien que cela filtrera par un nom qui correspond à une chose ou une autre.

$collection = Mage::getModel('catalog/product')->getCollection(); 
$collection->addAttributeToSelect('name'); 
$collection->addAttributeToSelect('orig_price');  

//filter for products who name is equal (eq) to Widget A, or equal (eq) to Widget B 
$collection->addFieldToFilter(array(
    array('attribute'=>'name','eq'=>'Widget A'), 
    array('attribute'=>'name','eq'=>'Widget B'),   
)); 

Une liste complète des courts conditionals pris en charge (éq, lt, etc.) se trouvent dans la méthode _getConditionSql dans lib/Varien/Data/Collection/Db.php

Enfin, toutes les collections Magento peuvent être réitérées sur (la classe de collection de base implémente l'une des interfaces de l'itérateur). C'est ainsi que vous récupérerez vos produits une fois les filtres définis.

$collection = Mage::getModel('catalog/product')->getCollection(); 
$collection->addAttributeToSelect('name'); 
$collection->addAttributeToSelect('orig_price');  

//filter for products who name is equal (eq) to Widget A, or equal (eq) to Widget B 
$collection->addFieldToFilter(array(
    array('name'=>'orig_price','eq'=>'Widget A'), 
    array('name'=>'orig_price','eq'=>'Widget B'),  
)); 

foreach ($collection as $product) { 
    //var_dump($product); 
    var_dump($product->getData()); 
} 
+5

réponse très détaillée. Merci! –

+0

Merci beaucoup pour la réponse détaillée. Tu m'as mis sur le bon chemin. J'ai fait un var_dump des résultats de votre exemple de code. Étant donné que l'attribut avec lequel je travaille est un élément de sélection multiple, j'obtiens un identifiant numérique dans les résultats afin qu'une comparaison de texte ne fonctionne pas. PAR EXEMPLE.$ this-> collection-> addFieldToFilter (array ('attribute' => 'cw_category', 'eq' => 'Aero'), array ('attribute' => 'cw_category', 'eq' => 'Track'), array ('attribute' => 'cw_category', 'eq' => 'Touring') )); EXPEDITEUR « cw_category » => string », 536535534' (longueur = 12) – Christian

+0

Ne peut pas vous aider spécifiquement là-bas sans beaucoup de creuser (représentant StackOverflow est agréable, mais il ne paie pas les factures). Deux avenues à poursuivre. Tout d'abord, comme mentionné, checkout _getConditionSql pour une liste de tous les opérateurs de comparaison possibles. Vous pourriez être en mesure de vous débrouiller avec une clause like ou une entrée. Deuxièmement, si vous extrayez PHPDoc pour la méthode addAttributeToFilter sur Mage_Eav_Model_Entity_Collection_Abstract, vous verrez que l'une des valeurs attendues du premier param est Mage_Eav_Model_Entity_Attribute_Interface. Cela pourrait vous conduire sur le bon chemin. –

7

Ceci est une suite à ma question originale pour aider les autres avec le même problème. Si vous avez besoin de filtrer par un attribut, plutôt que de rechercher manuellement l'identifiant, vous pouvez utiliser le code suivant pour récupérer toutes les paires identifiant/valeur d'un attribut. Les données sont renvoyées sous forme de tableau avec le nom de l'attribut en tant que clé.

function getAttributeOptions($attributeName) { 
    $product = Mage::getModel('catalog/product'); 
    $collection = Mage::getResourceModel('eav/entity_attribute_collection') 
       ->setEntityTypeFilter($product->getResource()->getTypeId()) 
       ->addFieldToFilter('attribute_code', $attributeName); 

    $_attribute = $collection->getFirstItem()->setEntity($product->getResource()); 
    $attribute_options = $_attribute->getSource()->getAllOptions(false); 
    foreach($attribute_options as $val) { 
     $attrList[$val['label']] = $val['value']; 
    } 

    return $attrList; 
} 

Voici une fonction que vous pouvez utiliser pour obtenir des produits en fonction de leur ID d'ensemble d'attributs. Récupéré en utilisant la fonction précédente.

function getProductsByAttributeSetId($attributeSetId) { 
    $products = Mage::getModel('catalog/product')->getCollection(); 
    $products->addAttributeToFilter('attribute_set_id',$attributeSetId); 

    $products->addAttributeToSelect('*'); 

    $products->load(); 
    foreach($products as $val) { 
    $productsArray[] = $val->getData(); 
    } 

    return $productsArray; 
} 
0

J'ai ajouté la ligne

$this->_productCollection->addAttributeToSelect('releasedate'); 

dans

app/code/core/Mage/Catalogue/Bloc/produit/Liste.php sur la ligne 95

en fonction _getProductCollection()

puis appelez dans

app/design/frontend/default/hellopress/modèle/catalogue/produit/list.phtml

Par code écrit

<div><?php echo $this->__('Release Date: %s', $this->dateFormat($_product->getReleasedate())) ?> 
</div> 

Maintenant, il fonctionne dans Magento 1.4.x

3

Pour obtenir TEXT attributs ajoutés de l'administrateur à l'extrémité avant sur la page de liste des produits.

Merci Anita Mourya

J'ai trouvé il y a deux méthodes. Disons que l'attribut de produit appelé "na_author" est ajouté à partir du backend comme champ de texte.

MÉTHODE 1

sur list.phtml

<?php $i=0; foreach ($_productCollection as $_product): ?> 

POUR CHAQUE CHARGE DU PRODUIT PAR SKU ET GET ATTRIBUTE DANS FOREACH

<?php 
$product = Mage::getModel('catalog/product')->loadByAttribute('sku',$_product->getSku()); 
$author = $product['na_author']; 
?> 

<?php 
if($author!=""){echo "<br /><span class='home_book_author'>By ".$author ."</span>";} else{echo "";} 
?> 

MÉTHODE 2

Mage/Catalog/Block/Product/List.phtml SUR RIDE et mis en ' dossier local '

à-dire Copie De

Mage/Catalog/Block/Product/List.phtml 

coller pour

app/code/local/Mage/Catalog/Block/Product/List.phtml 

changer la fonction en ajoutant 2 lignes en gras ci-dessous.

protected function _getProductCollection() 
{ 
     if (is_null($this->_productCollection)) { 
      $layer = Mage::getSingleton('catalog/layer'); 
      /* @var $layer Mage_Catalog_Model_Layer */ 
      if ($this->getShowRootCategory()) { 
       $this->setCategoryId(Mage::app()->getStore()->getRootCategoryId()); 
      } 

      // if this is a product view page 
      if (Mage::registry('product')) { 
       // get collection of categories this product is associated with 
       $categories = Mage::registry('product')->getCategoryCollection() 
        ->setPage(1, 1) 
        ->load(); 
       // if the product is associated with any category 
       if ($categories->count()) { 
        // show products from this category 
        $this->setCategoryId(current($categories->getIterator())); 
       } 
      } 

      $origCategory = null; 
      if ($this->getCategoryId()) { 
       $category = Mage::getModel('catalog/category')->load($this->getCategoryId()); 

       if ($category->getId()) { 
        $origCategory = $layer->getCurrentCategory(); 
        $layer->setCurrentCategory($category); 
       } 
      } 
      $this->_productCollection = $layer->getProductCollection(); 

      $this->prepareSortableFieldsByCategory($layer->getCurrentCategory()); 

      if ($origCategory) { 
       $layer->setCurrentCategory($origCategory); 
      } 
     } 
     **//CMI-PK added na_author to filter on product listing page// 
     $this->_productCollection->addAttributeToSelect('na_author');** 
     return $this->_productCollection; 

} 

et vous serez heureux de le voir .... !!

5
$attribute = Mage::getModel('eav/entity_attribute') 
       ->loadByCode('catalog_product', 'manufacturer'); 

$valuesCollection = Mage::getResourceModel('eav/entity_attribute_option_collection') 
      ->setAttributeFilter($attribute->getData('attribute_id')) 
      ->setStoreFilter(0, false); 

$preparedManufacturers = array();    
foreach($valuesCollection as $value) { 
    $preparedManufacturers[$value->getOptionId()] = $value->getValue(); 
} 


if (count($preparedManufacturers)) { 
    echo "<h2>Manufacturers</h2><ul>"; 
    foreach($preparedManufacturers as $optionId => $value) { 
     $products = Mage::getModel('catalog/product')->getCollection(); 
     $products->addAttributeToSelect('manufacturer'); 
     $products->addFieldToFilter(array(
      array('attribute'=>'manufacturer', 'eq'=> $optionId,   
     )); 

     echo "<li>" . $value . " - (" . $optionId . ") - (Products: ".count($products).")</li>"; 
    } 
    echo "</ul>"; 
} 
2

Le nom de l'attribut create est "price_screen_tab_name". et l'accès en utilisant cette formule simple.

<?php $_product = $this->getProduct(); ?> 
<?php echo $_product->getData('price_screen_tab_name');?> 
Questions connexes