Php 按子类别、属性和产品名称对集合进行排序
我已经为一个问题工作了好几个小时,似乎我找不到一种方法来让上面的排序工作 在一个magento项目中(我对magento比较陌生),我必须先按子类别对集合排序,然后按属性排序,最后按产品名称排序<代码>是锚定的在所有类别中都设置为true,因此父类别也显示子类别产品 我想到了使用Php 按子类别、属性和产品名称对集合进行排序,php,magento,sorting,collections,usort,Php,Magento,Sorting,Collections,Usort,我已经为一个问题工作了好几个小时,似乎我找不到一种方法来让上面的排序工作 在一个magento项目中(我对magento比较陌生),我必须先按子类别对集合排序,然后按属性排序,最后按产品名称排序是锚定的在所有类别中都设置为true,因此父类别也显示子类别产品 我想到了使用ReflectionObject将usort()PHP函数与comparator函数结合使用,如下所示: private static function cmp($a, $b) { $a_product_geschmac
ReflectionObject
将usort()
PHP函数与comparator函数结合使用,如下所示:
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();
}
获取子类别的助手函数如下所示:
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();
}
在Mage\u Catalog\u Block\u Product\u List
的\u getProductCollection()
方法中将上述比较器与usort和ReflectionObject一起使用:
// ...
$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\u Catalog\u Block\u Product\u List
类中设置了一个测试(看看它是否工作)。对于savety,我在Toolbar.php
在上面的代码中,我发现了它,它看起来很有希望(即使这更像是一个黑客而不是OO)
当我打印$collectionItems
时,订单与预期一致。在前端,这与预期不符,例如属性ws_geschmack
未排序,子类别也未“正确”排序
我还问自己,将$collection
传递回\u productCollection
成员的方式是否正确(正如stackexchange答案中的示例代码所示)。我发现,ReflectionObject
类中还有一个名为setValue
的方法,但也不起作用
如果子类别是一个属性,那么问题就不是真正的问题了,在这种情况下,我可以使用setOrder
和一个字段数组来按ASC顺序排序
此外,后端中类别的顺序(如果我按字母顺序排列)似乎没有任何影响。如果这能起作用,我可以删除子类别的排序
分类必须在类别产品列表和搜索结果列表中进行,后者并不重要,但类别浏览是重要的
另一个问题类似于我的(),但那个家伙只有属性,可以通过使用数组调用setOrder
来解决
所以我没有主意了。有人知道如何解决这个问题吗?非常感谢您的帮助
我正在为这个项目使用magento 1.7.0.2版
更新
只是为了澄清我在寻找什么:我实现了这个迭代代码,它正是我所需要的。它首先获取当前类别的子类别,然后查询这些子类别中的所有产品。结果按类别列表排序,产品结果/子列表按属性ws_geschmack
和名称排序:
$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 />";
}
}
}
$categories=Mage::getModel('catalog/categority')->getCollection()
->addAttributeToSelect('名称')
->addFieldToFilter('parent_id',
排列(
'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作为$category){
//检查是否有此类产品可供销售
如果(Mage::getModel('catalog/category')->load($category->getId())
->getProductCollection()
->addAttributeToSelect('entity_id')
->addAttributeToFilter('状态',1)
->addAttributeToFilter('visibility',4)
->count()==0)继续;
打印“->”$category->getId():”.$category->getName().“
”;
//获取当前类别下的所有子类别
$\u subcategory\u id=get\u categories(Mage::getModel('catalog/category')->getCategories($category->getId());
//为类别\u id筛选器生成“finset”查询
$\子类别\ finset\ ID=数组\映射(
功能($elem){
返回数组('finset'=>$elem);
},
$\子类别\标识);
$\u products=Mage::getModel('目录/产品')
->getCollection()
->joinField('category\u id','category/category\u product','category\u id','product\u id=entity\u id',null,'left')
->addAttributeToSelect(“*”)
->addAttributeToFilter('状态',1)
->addAttributeToFilter('visibility',4)
->addAttributeToFilter('is_saleable',array('like'=>'1'))
->addAttributeToFilter('category\u id',$\u subcategory\u finset\u id)
->addAttributeToSort('ws_geschmack','ASC')
->addAttributeToSort('name','ASC');
如果($\u产品->计数()!=0){
foreach($\产品作为$\产品){
$prod=Mage::getModel('catalog/product')->load($\u product->getId());
echo$prod->getName()。“:”$prod->getAttributeText('ws_geschmack')。“
”;
}
}
}
这只是一个演示代码,我不能按原样使用。例如,getLoadedProductCollection()
返回值所需的所有内容。我想实现这一功能并非易事 我不确定这是否是预期的结果,但根据您的标准,下面的内容是否会按照您需要的方式设置集合
$products = Mage::getModel( 'catalog/product' )
->getCollection()
->addAttributeToSelect( '*' )
->addFieldToFilter( 'status', Mage_Catalog_Model_Product_Status::STATUS_ENABLED )
->addFieldToFilter( 'visibility', Mage_Catalog_Model_Product_Visibility::VISIBILITY_BOTH );
->addAttributeToFilter( 'category_id', array( 'in' => array( 'finset' => '[CATEGORY_ID_HERE]' ) ) );
->addAttributeToSort( 'category_id', ASC )
->addAttributeToSort( 'ws_geschmack', ASC )
->addAttributeToSort( 'name', ASC );
您可以使用类似的方法缩小收集范围并简化事情。还要知道,如果您正在定制内置产品收集方法,前端的分拣机可能正在修改您的前端,因此您可能需要确保它不会影响您的前端。谢谢您的回答,Jason。我也一直在考虑这种方式,这将是最简单的,但类别的排序将是按ID,而不是按表示此ID的实际类别字符串。此外,我认为