我已经解决了几个小时的问题,似乎我找不到让上述排序工作的方法。
在一个magento项目中(我对magento比较陌生)我必须首先按子类别对集合进行排序,然后是属性,最后是产品名称。is Anchor
设置为 ture 与所有类别,因此父类别也显示子类别产品。
我遇到了将PHP 函数与比较器函数一起ReflectionObject
使用的想法,如下所示:usort()
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();
}
_getProductCollection()
在以下方法中使用上述比较器与 usort 和 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
。setOrder
为了安全起见,我用in注释掉了默认排序设置Toolbar.php
我在https://magento.stackexchange.com/questions/5438/on-search-result-group-products-by-category找到的以上代码看起来很有希望(即使这比 OO 更像是一个 hack)。
当我打印$collectionItems
订单时,正如预期的那样。在前端,它与预期不符,例如属性ws_geschmack
未排序,子类别也未“正确”排序。
我还问自己,传回$collection
给_productCollection
成员的方式是否正确(就像在 stackexchange 答案中的示例代码中一样)。我发现,类中还有一个方法调用setValue
,ReflectionObject
但也不起作用。
好吧,如果子类别是一个属性,那么问题就不是真正的问题,在这种情况下,我可以将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()
。我想实现该功能并非易事。