2009-08-26 22 views
76

En mi código de bloque, estoy tratando de recuperar programáticamente una lista de productos que tienen un atributo con un valor específico.Magento - Recuperar productos con un valor de atributo específico

Alternativamente, si eso no es posible, ¿cómo se recuperarían todos los productos y luego se los filtraría para enumerar simplemente los productos con un atributo específico?

¿Cómo realizaría una búsqueda utilizando los filtros booleanos estándar AND o OR para que coincida con un subconjunto de mis productos?

Respuesta

160

Casi todos los modelos de Magento tienen un objeto de colección correspondiente que se puede usar para buscar varias instancias de un modelo.

para crear instancias de una colección de productos, haga lo siguiente

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

los productos son un modelo de estilo Magento EAV, por lo que tendrá que añadir en cualquier atributo adicional que desea devolver.

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

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

Hay múltiples sintaxis para configurar los filtros en las colecciones. Siempre uso la detallada a continuación, pero es posible que desee inspeccionar la fuente de Magento para conocer las formas adicionales en que se pueden usar los métodos de filtrado.

A continuación se muestra cómo filtrar por un rango de valores (mayor que y menor que)

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

Aunque esto va a filtrar por un nombre que es igual a una cosa u otra.

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

Una lista completa de los condicionales cortas compatibles (eq, lt, etc.) se pueden encontrar en el método de _getConditionSql en lib/Varien/Data/Collection/Db.php

Finalmente, todas las colecciones de Magento pueden repiten a lo largo (la clase de colección de base implementa en las interfaces del iterador). Así es como agarrarás tus productos una vez que se establezcan los filtros.

$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

respuesta muy detallada. ¡Gracias! –

+0

Muchas gracias por la respuesta detallada. Me has puesto en el camino correcto. Hice un var_dump de los resultados de su código de ejemplo. Debido a que el atributo con el que estoy trabajando es un elemento de selección múltiple, obtengo una identificación numérica en los resultados, por lo que una comparación de texto no funciona. P.EJ.$ this-> collection-> addFieldToFilter (array ( array ('atributo' => 'cw_category', 'eq' => 'Aero'), array ('atributo' => 'cw_category', 'eq' => 'Track'), array ('atributo' => 'cw_category', 'eq' => 'Touring') )); está volviendo 'cw_category' => string', 536535534' (longitud = 12) No se puede – Christian

+0

específicamente para ayudarte allí sin un montón de excavación (Stackoverflow representante es agradable, pero no paga las facturas). Dos avenidas para que puedas perseguir. Primero, como se mencionó, revise _getConditionSql para obtener una lista de todos los posibles operadores de comparación. Es posible que pueda salir adelante con una cláusula similar o tal vez una entrada. En segundo lugar, si descarga PHPDoc para el método addAttributeToFilter en Mage_Eav_Model_Entity_Collection_Abstract, verá que uno de los valores esperados del primer parámetro es Mage_Eav_Model_Entity_Attribute_Interface. Eso podría llevarte en el camino correcto. –

7

Esto es una continuación de mi pregunta original para ayudar a otros con el mismo problema. Si necesita filtrar por un atributo, en lugar de buscar manualmente el ID, puede usar el siguiente código para recuperar todos los pares de ID y valor para un atributo. Los datos se devuelven como una matriz con el nombre del atributo como la clave.

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

Aquí hay una función que puede utilizar para obtener los productos por su atributo establecido id. Obtenido usando la función anterior.

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

he añadido la línea

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

en

app/código/core/Mago/Catálogo/Bloquear/producto/Lista.php en la línea 95

en función _getProductCollection()

y luego lo llaman en

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

Por escritura de código

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

Ahora está funcionando en Magento 1.4.x

3

Para obtener TEXT atributos agregados de admin al front-end en la página de lista de productos.

Gracias Anita Mourya

he encontrado que hay dos métodos. Deje decir que el atributo de producto llamado "na_author" se agrega desde el backend como campo de texto.

MÉTODO 1

en list.phtml

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

para cada carga PRODUCTO POR SKU Y Get Attribute DENTRO 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 "";} 
?> 

MÉTODO 2

Mage/Catalog/Block/Product/List.phtml SOBRE RIDE y ajustado en ' carpeta local '

es decir Copiar de

Mage/Catalog/Block/Product/List.phtml 

y pegar para

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

cambiar la función mediante la adición de 2 líneas que se muestran en negrita a continuación.

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; 

} 

y le alegrará verlo ... !!

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

crear nombre de atributo es "price_screen_tab_name". y accede usando esta simple fórmula.

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