2009-08-26 10 views
76

In meinem Blockcode versuche ich programmatisch eine Liste von Produkten abzurufen, die ein Attribut mit einem bestimmten Wert haben.Magento - Produkte mit einem bestimmten Attributwert abrufen

Alternativ, wenn das nicht möglich ist, wie würde man alle Produkte abrufen und dann filtern, um nur die Produkte mit einem bestimmten Attribut aufzulisten?

Wie würde ich eine Suche mit standardmäßigen booleschen Filtern AND oder OR durchführen, um eine Untergruppe meiner Produkte zu finden?

Antwort

160

Fast alle Magento-Modelle verfügen über ein entsprechendes Collection-Objekt, das zum Abrufen mehrerer Instanzen eines Modells verwendet werden kann.

Um eine Produktsammlung, gehen Sie wie folgt

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

Produkte sind ein Magento EAV Stil Modell instanziiert, so dass Sie auf zusätzliche Attribute hinzufügen müssen werden, die Sie zurückgeben möchten.

Es gibt mehrere Syntaxen zum Festlegen von Filtern für Sammlungen. Ich verwende immer die ausführliche unten, aber vielleicht möchten Sie die Magento-Quelle für zusätzliche Möglichkeiten untersuchen, wie die Filtermethoden verwendet werden können.

Im Folgenden wird gezeigt, wie durch eine Reihe von Werten filtern (größer und kleiner als)

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

Während dies durch einen Namen auswählen, wird die eine oder andere gleich.

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

Eine vollständige Liste der unterstützten kurzen conditionals (eq, lt, etc.) können in dem Verfahren in _getConditionSqllib/Varien/Data/Collection/Db.php

Schließlich werden alle Magento Sammlungen iteriert werden kann (der Basisklasse gefunden werden Sammel implementiert eine der Iterator-Schnittstellen). So greifen Sie Ihre Produkte an, sobald Filter eingestellt sind.

$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

sehr detaillierte Antwort. Vielen Dank! –

+0

Vielen Dank für die ausführliche Antwort. Du hast mich auf den richtigen Weg gesetzt. Ich habe einen var_dump der Ergebnisse von Ihrem Beispielcode gemacht. Da das Attribut, mit dem ich arbeite, ein Mehrfachauswahlelement ist, erhalte ich eine numerische ID in den Ergebnissen, sodass ein Textvergleich nicht funktioniert. Z.B.$ this-> Sammlung-> addFieldToFilter (Array ( Array ('Attribut' => 'cw_category', 'eq' => 'Aero'), Array ('Attribut' => 'cw_category', 'eq' => 'Track'), Array ('Attribut' => 'cw_category', 'eq' => 'Touring') )); kehrt ‚cw_category‘ => string‘, 536535534' (Länge = 12) – Christian

+0

nicht speziell Sie Kann es helfen, ohne viel Graben (rep Stackoverflow ist schön, aber es lohnt sich nicht, die Rechnungen). Zwei Möglichkeiten, die Sie verfolgen können. Zuerst, wie bereits erwähnt, checkout _getConditionSql für eine Liste aller möglichen Vergleichsoperatoren. Sie können vielleicht mit einer Like-Klausel oder vielleicht einem In auskommen. Zweitens, wenn Sie das PHPDoc für die addAttributeToFilter-Methode in Mage_Eav_Model_Entity_Collection_Abstract auschecken, sehen Sie, dass einer der erwarteten Werte des ersten Parameters ein Mage_Eav_Model_Entity_Attribute_Interface ist. Das könnte Sie auf den richtigen Weg führen. –

7

Dies ist ein Follow-up zu meiner ursprünglichen Frage, um anderen mit dem gleichen Problem zu helfen. Wenn Sie nach einem Attribut filtern müssen, anstatt manuell nach der ID zu suchen, können Sie den folgenden Code verwenden, um alle ID-, Wert-Paare für ein Attribut abzurufen. Die Daten werden als Array mit dem Attributnamen als Schlüssel zurückgegeben.

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

Hier ist eine Funktion, die Sie verwenden können, um Produkte über ihre Attributsatz-ID zu erhalten. Mit der vorherigen Funktion abgerufen.

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

Ich habe Linie

hinzugefügt
$this->_productCollection->addAttributeToSelect('releasedate'); 

in

app/code/core/Mage/Katalog/Block/Produkt/Liste.php on line 95

in Funktion _getProductCollection()

und dann rufen sie in

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

Durch das Schreiben von Code

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

Jetzt funktioniert es in Magento 1.4.x

3

Um TEXT Attribute zu erhalten, die von admin zum Frontend auf Produktlistseite hinzugefügt werden.

Dank Anita Mourya

Ich habe festgestellt, gibt es zwei Methoden. Nehmen wir an, das Produktattribut "na_author" wird vom Backend als Textfeld hinzugefügt.

METHODE 1

auf list.phtml

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

für jedes Produkt LOAD BY SKU UND VIRTUELLE ATTRIBUTE INSIDE 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 "";} 
?> 

METHOD 2

Mage/Catalog/Block/Product/List.phtml OVER Fahrt und gesetzt in ' lokaler Ordner '

d.h. Kopieren von

Mage/Catalog/Block/Product/List.phtml 

und Paste

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

Änderung der Funktion von 2 Zeilen Zugabe unten fett dargestellt.

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; 

} 

und Sie werden sich freuen, es zu sehen .... !!

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

Attributnamen erstellen ist "price_screen_tab_name". und Zugriff mit dieser einfachen Formel.

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