Pytanie Magento - Odzyskaj produkty o określonej wartości atrybutu


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

Alternatywnie, jeśli nie jest to możliwe, w jaki sposób można odzyskać wszystkie produkty, a następnie przefiltrować je, aby wyświetlić listę produktów o określonym atrybucie?

Jak wykonać wyszukiwanie przy użyciu standardowych filtrów logicznych AND lub OR dopasować podzbiór moich produktów?


76
2017-08-26 06:41


pochodzenie




Odpowiedzi:


Prawie wszystkie modele Magento mają odpowiedni obiekt Collection, który może być użyty do pobrania wielu instancji Modelu.

Aby utworzyć instancję kolekcji produktów, wykonaj następujące czynności

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

Produkty są modelem w stylu Magento EAV, więc musisz dodać dodatkowe atrybuty, które chcesz zwró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 sposób filtrowania według zakresu wartości (więcej niż I mniej 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'),
));

Będzie to filtrowane według nazwy, która równa się jednej rzeczy LUB innej.

$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łna lista obsługiwanych krótkich warunków (eq, lt, itp.) Znajduje się w _getConditionSql metoda w lib/Varien/Data/Collection/Db.php

Na koniec wszystkie kolekcje Magento mogą być iterowane (podstawowa klasa kolekcji implementuje interfejsy 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());
}

160
2017-08-27 04:01



bardzo szczegółowa odpowiedź. dzięki! - Rick J
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 '))); Zwraca "cw_category" => ciąg ", 536,535,534 '(długość = 12) - Christian
Nie mogę ci w tym pomóc bez dużego 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. - Alan Storm
Alan, dzięki za dodatkowe wskazówki. Przesłuchałem kod przez wiele godzin i nie miałem szczęścia. Nauczyłem się dużo więcej o Magento w procesie, więc myślę, że to nie wszystko jest złe. Udało mi się uruchomić debugger sql. Wygląda na to, że zamierzam po prostu użyć ID atrybutu w moich kryteriach filtrowania. na przykład ...-> addAttributeToFilter ('cw_category', '536') zamiast -> addAttributeToFilter ("cw_category", "Aero") na przykład. - Christian
Widziałem to jako powszechny sposób radzenia sobie z tym. Myślę, że sposób, w jaki "masz" to zrobić, jest instancją i atrybutem obiektu, który chcesz, i przekazać go jednej z metod filtrowania. - Alan Storm


Jest to 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żesz 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;
}

7
2018-01-27 22:34





$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
2017-09-05 17:36





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

Dzięki, Anita Mourya

Znalazłem dwie metody. 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 PRODUKTU OBCIĄŻENIA PRZEZ SKU I UZYSKANIA ATRYBUTÓW WEWNĄTRZ KAŻDEGO PODEJŚCIA

<?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 PONIEWAŻ RIDE i ustaw w "folderze lokalnym"

to znaczy Skopiuj z

Mage/Catalog/Block/Product/List.phtml

i WKLEJ DO

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

zmień funkcję, dodając 2 wiersze zaznaczone pogrubioną czcionką poniżej.

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


3
2017-09-06 10:41





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');?>

2
2018-06-09 09:09





Dodałem linię

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

w

app / code / core / Mage / Catalogue / Block / Product / List.php w linii 95

w działaniu _getProductCollection() 

a następnie zadzwoń

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


0
2018-06-04 22:20