我一直在解决一个问题几个小时,似乎我找不到一种方法来获得上述排序工作。按子类别,属性和产品名排序集合
在Magento的项目(IM相对较新的Magento)我必须按子类别排序第一的集合,然后由产品名称的属性和最后一个。 is Anchor
设置为与所有类别一致,所以父类别也显示子类别产品。
private static function cmp($a, $b) {
$a_product_geschmack = Mage::getModel('catalog/product')
->load($a->getId())->getAttributeText('ws_geschmack');
$b_product_geschmack = Mage::getModel('catalog/product')
->load($b->getId())->getAttributeText('ws_geschmack');
$r = strcmp(get_category($a), get_category($b));
if ($r != 0)
return $r;
$r = strcmp($a_product_geschmack, $b_product_geschmack);
if ($r != 0)
return $r;
return strcmp($a->getName(), $b->getName());
}
的辅助函数来获取子类看起来是这样的:
function get_category($product) {
$categoryModel = Mage::getModel('catalog/category');
// Get Array of Category Id's with Last as First (Reversed)
$_categories = array_reverse($product->getCategoryIds());
// Get Parent Category Id
$_parentId = $categoryModel->load($_categories[0])->getParentId();
// Load Parent Category
$_category = $categoryModel->load($_parentId);
return $_category->getName();
}
我碰到使用ReflectionObject
使用usort()
PHP函数与比较功能,这样的想法来到
将上述比较器与usort和_getProductCollection()
方法中的ReflectionObject一起使用Mage_Catalog_Block_Product_List
:
// ...
$collection = $this->_productCollection;
$collectionReflection = new ReflectionObject($collection);
$itemsPropertyReflection = $collectionReflection->getProperty('_items');
$itemsPropertyReflection->setAccessible(true); // Make it accessible
$collectionItems = $itemsPropertyReflection->getValue($collection);
usort($collectionItems, array('Mage_Catalog_Block_Product_List', 'cmp'));
$itemsPropertyReflection->setValue($collectionReflection, $collectionItems);
$itemsPropertyReflection->setAccessible(false); // Return restriction back
$this->_productCollection = $collection;
// ...
以上所有我设置为测试(看看它是否工作)在Mage_Catalog_Block_Product_List
类。对于savety我注释掉默认的排序与setOrder
在Toolbar.php
上面的代码,我发现在https://magento.stackexchange.com/questions/5438/on-search-result-group-products-by-category设置,它似乎希望的(即使这是比OO黑客攻击)。
当我打印$collectionItems
如预期的顺序。在前端它不是预期的,例如属性ws_geschmack
没有排序,也没有“正确”排序子类别。
我还问自己,如果将$collection
传递给_productCollection
成员的方式是要走的路(因为它是在stackexchange答案中找到的示例代码)。我发现,在ReflectionObject
类中也有一种叫做setValue
的方法,但也不起作用。
那么,如果该子类别是一个属性,这个问题将不是一个真正的问题,在这种情况下,我可以使用setOrder
与字段数组按ASC顺序排序。
另外在后台的类别(如果我按字母顺序它们)的顺序似乎没有任何效果。如果这可行,我可以删除子类别的排序。
的排序在该类别产品的上市,并在搜索结果列表中的工作,后者是不是那么重要,但类别浏览功能。
另一个问题与我的类似(https://magento.stackexchange.com/questions/2889/sorting-product-list-by-more-than-one-attribute),但那个人只有属性,并且可以通过setOrder
使用数组来调用。
所以我没有想法。任何人都有一个想法如何解决这个问题?任何帮助是极大的赞赏!
我在这个项目中使用了magento 1.7.0.2版本。
更新
只是为了澄清什么,我在寻找:我实现了这个迭代代码不正是我需要的。它首先获取当前类别的子类别,然后查询这些子类别中的所有产品。结果排序的类别列表,以及产品结果/子表由属性ws_geschmack
和name
分类:
$categories = Mage::getModel('catalog/category')->getCollection()
->addAttributeToSelect('name')
->addFieldToFilter('parent_id',
array(
'eq' => Mage::getModel('catalog/layer')->getCurrentCategory()->getId()))
->addFieldToFilter('include_in_menu',array('eq' => '1'))
->addFieldToFilter('is_active', array('eq' => '1'))
->addAttributeToFilter('is_active', 1)
->addAttributeToSort('name', 'asc');
foreach($categories as $category) {
// Check if there are products for sale in this category
if (Mage::getModel('catalog/category')->load($category->getId())
->getProductCollection()
->addAttributeToSelect('entity_id')
->addAttributeToFilter('status', 1)
->addAttributeToFilter('visibility', 4)
->count() == 0) continue;
print "-> " . $category->getId() .': '. $category->getName() . "<br />";
// Get all child categories below this current category
$_subcategory_ids = get_categories(Mage::getModel('catalog/category')->getCategories($category->getId()));
// Build 'finset' query for category_id filter
$_subcategory_finset_ids = array_map(
function($elem) {
return array('finset' => $elem);
},
$_subcategory_ids);
$_products = Mage::getModel('catalog/product')
->getCollection()
->joinField('category_id', 'catalog/category_product', 'category_id', 'product_id = entity_id', null, 'left')
->addAttributeToSelect('*')
->addAttributeToFilter('status', 1)
->addAttributeToFilter('visibility', 4)
->addAttributeToFilter('is_saleable', array('like' => '1'))
->addAttributeToFilter('category_id', $_subcategory_finset_ids)
->addAttributeToSort('ws_geschmack', 'ASC')
->addAttributeToSort('name', 'ASC');
if ($_products->count() != 0) {
foreach ($_products as $_product) {
$prod = Mage::getModel('catalog/product')->load($_product->getId());
echo $prod->getName() . ": " . $prod->getAttributeText('ws_geschmack') . "<br />";
}
}
}
这只是一个演示代码,是我不能使用它。例如,我需要从getLoadedProductCollection()
返回的所有值。我想实现这个功能并不容易。
谢谢你的回答,杰森。我一直在考虑这种方式,它会是最简单的,但是对类别的排序将通过ID而不是表示该ID的实际类别字符串。另外,我认为'addAttributeToFilter'应该对所有类别和子类别ID(都是''anchor'ed!')执行'OR'操作,这是可能的,而不是问题。但在这里,主要问题仍然没有解决,因为它按数字ID排序。 –