0

私は何時間も問題に取り組んできましたが、上記の並べ替えを機能させる方法が見つからないようです。

magento プロジェクト (magento は比較的新しいものです) では、コレクションを最初にサブカテゴリで並べ替え、次に属性で並べ替え、最後に製品名で並べ替える必要があります。is Anchorすべてのカテゴリに対応するように設定されているため、親カテゴリにはサブカテゴリの製品も表示されます。

次のように、コンパレーター関数で 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上記のすべてを、クラスでテスト (機能しているかどうかを確認するため) として設定しました。保存のために、デフォルトの並べ替え設定をコメントアウトしましsetOrderToolbar.php

上記のコードはhttps://magento.stackexchange.com/questions/5438/on-search-result-group-products-by-categoryで見つけたもので、有望に思えました (たとえこれが OO よりもハックであったとしても)。

$collectionItems注文を印刷すると、期待どおりです。フロントエンドでは、属性ws_geschmackがソートされておらず、サブカテゴリも「適切に」ソートされていないなど、期待どおりではありません。

$collectionまた、メンバーに戻す_productCollection方法が正しいかどうかも自問します (stackexchange の回答にあるサンプル コードにあるように)。setValueクラスで呼び出されるメソッドもありますReflectionObjectが、機能しません。

サブカテゴリが属性である場合、問題は実際の問題ではありません。この場合setOrder、フィールドの配列で を使用して、ASC 順に並べ替えることができます。

また、バックエンドのカテゴリの順序 (アルファベット順に並べた場合) は効果がないようです。これが機能する場合は、サブカテゴリの並べ替えを削除できます。

並べ替えは、カテゴリの製品リストと検索結果リストで機能する必要があります。後者はそれほど重要ではありませんが、カテゴリのブラウジングは重要です。

別の質問も私のものと似ています(https://magento.stackexchange.com/questions/2889/sorting-product-list-by-more-than-one-attribute)が、その男には属性しかなく、解決できます配列を使用したsetOrderCall で。

だから私はアイデアがありません。この問題を解決する方法を知っている人はいますか? どんな助けでも大歓迎です!

このプロジェクトでは、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()たとえば、戻り値として必要なものすべて。その機能を実装するのは簡単なことではないと思います。

4

1 に答える 1

0

これが期待される結果であるかどうかはわかりませんが、あなたの基準を考えると、以下は必要な方法でコレクションを設定しますか?

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

同様の方法を使用して、コレクションを絞り込み、物事を単純化できます。また、フロントエンドのソーターがフロントエンドを変更している可能性がある組み込みの製品収集メソッドをカスタマイズしている場合は、影響を受けていないことを確認する必要があることも知っておいてください。

于 2013-09-30T17:14:03.570 に答える