Magento - Ruft Produkte mit einem bestimmten Attributwert ab

78

In meinem Blockcode versuche ich, programmgesteuert eine Liste von Produkten abzurufen, die ein Attribut mit einem bestimmten Wert haben.

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

Wie würde ich eine Suche mit Standard-Booleschen Filtern durchführen ANDoder OReine Teilmenge meiner Produkte abgleichen?

Christian
quelle

Antworten:

160

Fast alle Magento-Modelle verfügen über ein entsprechendes Collection-Objekt, mit dem mehrere Instanzen eines Modells abgerufen werden können.

Gehen Sie wie folgt vor, um eine Produktsammlung zu instanziieren

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

Bei den Produkten handelt es sich um ein Magento EAV-Modell. Sie müssen daher alle zusätzlichen Attribute hinzufügen, die Sie zurückgeben möchten.

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

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

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 auf zusätzliche Möglichkeiten untersuchen, wie die Filtermethoden verwendet werden können.

Im Folgenden wird gezeigt, wie nach einem Wertebereich gefiltert wird (größer als 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'),
));

Dabei wird nach einem Namen gefiltert, der der einen oder anderen Sache entspricht.

$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 Bedingungen (Gl., Lt usw.) finden Sie in der _getConditionSqlMethode inlib/Varien/Data/Collection/Db.php

Schließlich können alle Magento-Sammlungen iteriert werden (die Basissammlungsklasse implementiert eine der Iterator-Schnittstellen). So greifen Sie auf Ihre Produkte zu, sobald die 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('attribute'=>'name','eq'=>'Widget A'),
    array('attribute'=>'name','eq'=>'Widget B'),        
));

foreach ($collection as $product) {
    //var_dump($product);
    var_dump($product->getData());
}
Alan Storm
quelle
Vielen Dank für die ausführliche Antwort. Du hast mich auf den richtigen Weg gebracht. Ich habe einen var_dump der Ergebnisse aus Ihrem Beispielcode erstellt. Da das Attribut, mit dem ich arbeite, ein Mehrfachauswahlelement ist, wird in den Ergebnissen eine numerische ID angezeigt, sodass ein Textvergleich nicht funktioniert. EG $ this-> collection-> addFieldToFilter (Array (Array ('Attribut' => 'cw_category', 'eq' => 'Aero')), Array ('Attribut' => 'cw_category', 'eq' => ' Track '), Array (' attribute '=>' cw_category ',' eq '=>' Touring '))); Gibt 'cw_category' => string ', 536,535,534' (Länge = 12) zurück
Christian
Ich kann Ihnen dort nicht speziell helfen, ohne viel zu graben (StackOverflow rep ist nett, aber es bezahlt nicht die Rechnungen). Zwei Wege, die Sie verfolgen können. Wie bereits erwähnt, überprüfen Sie zunächst _getConditionSql auf eine Liste aller möglichen Vergleichsoperatoren. Möglicherweise können Sie mit einer like-Klausel oder einer in-Klausel 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_nttribute_nttribute_nttribute_nttribute_nttribute_nt. Das könnte Sie auf den richtigen Weg führen.
Alan Storm
1
Im letzten Codebeispiel beginnen Ihre Arrays mit 'name' => 'orig_price'- ist das richtig? Sollte es nicht sein 'attribute' => 'name'?
Andy
1
@johnsnails das ist sehr gut möglich, dieser Beitrag in 9 Jahren alt. Meine Antwort enthält möglicherweise ungenaue Informationen, oder die API hat sich darunter geändert. Ich arbeite heutzutage nicht genug mit Magento, um es genau zu wissen.
Alan Storm
1
@AlanStorm Es sieht so aus, als wäre es nur ein Fehler beim Kopieren / Einfügen aus einem anderen Codebeispiel in Ihrer Antwort. Ich werde die Antwort bearbeiten und korrigieren.
Andy
7

Dies ist eine Fortsetzung meiner ursprünglichen Frage, um anderen mit dem gleichen Problem zu helfen. Wenn Sie nach einem Attribut filtern müssen, anstatt die ID manuell nachzuschlagen, können Sie den folgenden Code verwenden, um alle ID-Wertepaare 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, mit der Sie Produkte anhand ihrer Attributsatz-ID abrufen können. 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;
}
Christian
quelle
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>";
}
verheesj
quelle
3

So erhalten Sie TEXTAttribute, die vom Administrator zum Front-End auf der Produktlistenseite hinzugefügt wurden.

Danke Anita Mourya

Ich habe festgestellt, dass es zwei Methoden gibt. Angenommen, 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 LADEN NACH SKU UND ERHALTEN SIE ATTRIBUT INNEN

<?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 und in 'lokaler Ordner' setzen

dh Kopieren von

Mage/Catalog/Block/Product/List.phtml

und PASTE TO

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

Ändern Sie die Funktion, indem Sie 2 fettgedruckte Zeilen hinzufügen.

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 du wirst es gerne sehen .... !!

Pragnesh Karia
quelle
2

Der Attributname erstellen ist " price_screen_tab_name". und Zugriff mit dieser einfachen Formel.

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

Ich habe Zeile hinzugefügt

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

im

app / code / core / Mage / Katalog / Block / Produkt / List.php in Zeile 95

in Funktion _getProductCollection()

und dann anrufen

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

Durch Schreiben von Code

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

Jetzt funktioniert es in Magento 1.4.x.

Anita Mourya
quelle