web-dev-qa-db-fra.com

Magento - Récupérer des produits avec une valeur d'attribut spécifique

Dans mon code de bloc, j'essaie de récupérer par programme une liste de produits ayant un attribut avec une valeur spécifique.

Sinon, si ce n'est pas possible, comment récupérer tous les produits puis les filtrer pour ne répertorier que les produits ayant un attribut spécifique?

Comment effectuer une recherche à l'aide de filtres booléens standard AND ou OR afin de faire correspondre un sous-ensemble de mes produits?

77
Christian

Presque tous les modèles Magento ont 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();

Les produits sont un modèle de style EAV Magento, vous devez donc ajouter tous les attributs supplémentaires que vous souhaitez renvoyer.

$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 les collections. J'utilise toujours le texte détaillé ci-dessous, mais vous voudrez peut-être examiner le code source de Magento pour identifier d'autres méthodes d'utilisation des méthodes de filtrage.

Ce qui suit montre comment filtrer selon une plage de valeurs (supérieure à AND 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'),
));

Alors que cela va filtrer par un nom qui vaut une chose OR 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 conditions brèves prises en charge (eq, lt, etc.) se trouve dans le _getConditionSql méthode dans lib/Varien/Data/Collection/Db.php

Enfin, toutes les collections de Magento peuvent être itérées (la classe de la collection de base est implémentée sur les interfaces de l’itérateur). Voici comment vous allez récupérer 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('attribute'=>'name','eq'=>'Widget A'),
    array('attribute'=>'name','eq'=>'Widget B'),        
));

foreach ($collection as $product) {
    //var_dump($product);
    var_dump($product->getData());
}
160
Alan Storm

Ceci fait suite à ma question initiale pour aider les autres avec le même problème. Si vous devez filtrer en fonction d'un attribut plutôt que de rechercher manuellement l'id, vous pouvez utiliser le code suivant pour extraire toutes les paires id/valeur d'un attribut. Les données sont renvoyées sous forme de tableau avec le nom d'attribut comme 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 identifiant de jeu d'attributs. Récupéré à l'aide de 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;
}
7
Christian
$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>";
}
5
verheesj

Pour obtenir les attributs TEXT ajoutés de l’administrateur au serveur frontal sur la page de liste des produits.

Merci Anita Mourya

J'ai trouvé qu'il y a deux méthodes. Supposons qu'un attribut de produit appelé "na_author" soit ajouté à partir du backend sous forme de champ de texte.

METHODE 1

sur list.phtml

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

POUR CHAQUE PRODUIT CHARGER PAR SKU ET OBTENIR UN ATTRIBUT À L’INTÉRIEUR DE L’APPUI

<?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 "";}
?>

METHODE 2

Mage/Catalog/Block/Product/List.phtml OVER RIDE et défini dans le "dossier local"

c'est-à-dire copier de

Mage/Catalog/Block/Product/List.phtml

et PÂTE À

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

changez 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 .... !!

3
Pragnesh Karia

le nom d'attribut de création est "price_screen_tab_name ". et accédez en utilisant cette formule simple.

<?php $_product = $this->getProduct(); ?>
<?php echo $_product->getData('price_screen_tab_name');?>
2
Pratik Kamani

J'ai ajouté la ligne

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

dans

app/code/noyau/Mage/Catalogue/Bloc/Produit/Liste.php en ligne 95

en fonction _getProductCollection()

puis appelez-le

app/design/frontend/default/hellopress/template/catalogue/product/list.phtml

En écrivant du code

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

Cela fonctionne maintenant dans Magento 1.4.x

0
Anita Mourya