2009-08-26 10 views
76

W moim kodzie blokowym próbuję programowo pobrać listę produktów, które mają atrybut o określonej wartości.Magento - Pobieranie produktów o określonej wartości atrybutu

Alternatywnie, jeśli nie jest to możliwe, w jaki sposób można pobrać wszystkie produkty, a następnie odfiltrować je, aby wyświetlić tylko produkty z określonym atrybutem?

Jak wykonać wyszukiwanie przy użyciu standardowych filtrów boolowskich AND lub OR, aby dopasować do podzestawu moich produktów?

Odpowiedz

160

Prawie wszystkie modele Magento mają odpowiedni obiekt Collection, który może służyć do pobierania wielu wystąpień modelu.

Aby instancji kolekcji produktu, wykonaj następujące czynności

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

produkty są Magento EAV stylu modelu, więc trzeba dodać na wszelkich dodatkowych atrybutów, które chcesz przywrócić.

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

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

Istnieje wiele składni do ustawiania filtrów w kolekcjach. Zawsze używam poniższego, ale możesz chcieć sprawdzić źródło Magento, aby dowiedzieć się więcej o metodach filtrowania.

Poniżej przedstawiono, jak filtrować według zakresu wartości (większy i mniejszy niż)

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

ile to będzie filtrować według nazwy, która wynosi jedną rzecz lub innego.

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

Pełną listę obsługiwanych krótkich warunkowych (równanie, LT, itd.) Można znaleźć w sposobie _getConditionSql w lib/Varien/Data/Collection/Db.php

Ostatecznie wszystkie zbiory Magento może być powtarzana przez (The klasy gromadzenia baza implementuje interfejs iteratora). W ten sposób pobierzesz swoje produkty po ustawieniu filtrów.

$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

bardzo szczegółowa odpowiedź. dzięki! –

+0

Dziękuję bardzo za szczegółową odpowiedź. Ustawiłeś mnie na właściwej ścieżce. Zrobiłem var_dump wyników z twojego przykładowego kodu. Ponieważ atrybut, nad którym pracuję jest elementem wielokrotnego wyboru, otrzymuję numer identyfikacyjny w wynikach, więc porównanie tekstu nie działa. NA PRZYKŁAD.$ this-> collection-> addFieldToFilter (array ( array ('atrybut' => 'cw_category', 'eq' => 'Aero'), array ('atrybut' => 'cw_category', 'eq' => 'Track'), array ('atrybut' => 'cw_category', 'eq' => 'Touring') )); Powraca 'cw_category' => ciąg ', 536,535,534' (długość = 12) – Christian

+0

Nie może ci tam pomóc bez kopania (replikacja StackOverflow jest przyjemna, ale nie opłaca rachunków). Dwie drogi do realizacji. Najpierw, jak już wspomniano, kasa _getConditionSql dla listy wszystkich możliwych operatorów porównania. Być może uda ci się ominąć klauzulę lub wtyczkę. Po drugie, jeśli wyewidencjonujesz PHPDoc dla metody addAttributeToFilter na Mage_Eav_Model_Entity_Collection_Abstract, zobaczysz, że jedną z oczekiwanych wartości pierwszego parametru jest Mage_Eav_Model_Entity_Attribute_Interface. To może doprowadzić cię do właściwej ścieżki. –

7

To jest kontynuacja mojego pierwotnego pytania, aby pomóc innym z tym samym problemem. Jeśli chcesz filtrować według atrybutu, zamiast ręcznie wyszukiwać identyfikator, możesz użyć następującego kodu, aby pobrać wszystkie id, pary wartości dla atrybutu. Dane są zwracane jako tablica z nazwą atrybutu jako kluczem.

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

Oto funkcja, której można użyć do uzyskania produktów według ich identyfikatora zestawu atrybutów. Odzyskiwanie przy użyciu poprzedniej funkcji.

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

Dodałem linii

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

w

app/code/core/Mage/Katalog/block/product/List.php on line 95

w funkcji _getProductCollection()

a następnie wywołać go w

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

Pisząc kod

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

Teraz działa w Magento 1.4.x

3

Aby uzyskać atrybuty TEXT dodane od administratora do interfejsu użytkownika na stronie z listą produktów.

Dzięki Anita Mourya

Znalazłem tam jest na dwa sposoby. Powiedzmy, że atrybut produktu o nazwie "na_author" jest dodawany z backendu jako pole tekstowe.

METODA 1

na list.phtml

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

dla każdego kolejnego ładunku PRODUCT przez SKU I GET atrybut wewnątrz 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 "";} 
?> 

METODA 2

Mage/Catalog/Block/Product/List.phtml OVER RIDE i ustawić w ' folder lokalny "

tj Kopiuj z

Mage/Catalog/Block/Product/List.phtml 

i PASTA DO

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

zmiany funkcji poprzez dodanie 2 linie przedstawione pogrubioną czcionką.

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; 

} 

i będziesz szczęśliwy, widząc to ... !!

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

utwórz nazwę atrybutu to "price_screen_tab_name". i dostęp za pomocą tej prostej formuły.

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