问题
In my block code I am trying to programmatically retrieve a list of products that have a attribute with a specific value.
Alternately if that is not possible how would one retrieve all products then filter them to just list the products with a specific attribute?
How would I perform a search using standard boolean filters AND
or OR
to match a subset of my products?
回答1:
Almost all Magento Models have a corresponding Collection object that can be used to fetch multiple instances of a Model.
To instantiate a Product collection, do the following
$collection = Mage::getModel('catalog/product')->getCollection();
Products are a Magento EAV style Model, so you'll need to add on any additional attributes that you want to return.
$collection = Mage::getModel('catalog/product')->getCollection();
//fetch name and orig_price into data
$collection->addAttributeToSelect('name');
$collection->addAttributeToSelect('orig_price');
There's multiple syntaxes for setting filters on collections. I always use the verbose one below, but you might want to inspect the Magento source for additional ways the filtering methods can be used.
The following shows how to filter by a range of values (greater than AND less than)
$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'),
));
While this will filter by a name that equals one thing OR another.
$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'),
));
A full list of the supported short conditionals (eq,lt, etc.) can be found in the _getConditionSql
method in lib/Varien/Data/Collection/Db.php
Finally, all Magento collections may be iterated over (the base collection class implements on of the the iterator interfaces). This is how you'll grab your products once filters are set.
$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());
}
回答2:
This is a follow up to my original question to help out others with the same problem. If you need to filter by an attribute, rather than manually looking up the id you can use the following code to retrieve all the id, value pairs for an attribute. The data is returned as an array with the attribute name as the key.
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;
}
Here is a function you can use to get products by their attribute set id. Retrieved using the previous function.
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;
}
回答3:
$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>";
}
回答4:
To Get TEXT
attributes added from admin to front end on product listing page.
Thanks Anita Mourya
I have found there is two methods. Let say product attribute called "na_author" is added from backend as text field.
METHOD 1
on list.phtml
<?php $i=0; foreach ($_productCollection as $_product): ?>
FOR EACH PRODUCT LOAD BY SKU AND GET 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 RIDE and set in 'local folder'
i.e. Copy From
Mage/Catalog/Block/Product/List.phtml
and PASTE TO
app/code/local/Mage/Catalog/Block/Product/List.phtml
change the function by adding 2 lines shown in bold below.
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;
}
and you will be happy to see it....!!
回答5:
create attribute name is "price_screen_tab_name
". and access using this simple formula.
<?php $_product = $this->getProduct(); ?>
<?php echo $_product->getData('price_screen_tab_name');?>
回答6:
I have added line
$this->_productCollection->addAttributeToSelect('releasedate');
in
app/code/core/Mage/Catalog/Block/Product/List.php on line 95
in function _getProductCollection()
and then call it in
app/design/frontend/default/hellopress/template/catalog/product/list.phtml
By writing code
<div><?php echo $this->__('Release Date: %s', $this->dateFormat($_product->getReleasedate())) ?>
</div>
Now it is working in Magento 1.4.x
来源:https://stackoverflow.com/questions/1332742/magento-retrieve-products-with-a-specific-attribute-value