3
votes

how can I sort associated products by cutom attribute within a grouped product in Magento,

I have duplicated the file Grouped.php to: app/code/local/Mage/Catalog/Model/Product/Type/Grouped.php

and tried to add this in my getAssociatedProducts function:

->addAttributeToSort('my_attribute', 'DESC');

but it don't work, can anyone help ?

[EDIT]

I have overridden the file "app/code/core/Mage/Catalog/Model/Product/Type/Grouped.php" and I have tried to sort the associated products by a custom attribute by modifying the collection like this :

$collection = $this->getAssociatedProductCollection($product)
    ->addAttributeToSelect('*')
    ->addFilterByRequiredOptions()
    ->setPositionOrder()
    ->addStoreFilter($this->getStoreFilter($product))
    ->addAttributeToFilter('status', array('in' => $this->getStatusFilters($product)))
    ->addAttributeToSort('my_attribute', 'DESC');

but that's make no change !! :(

Thanks a lot for help.

4

4 Answers

1
votes

You need to make sure that you attribute is included in the select to be able to sort by it. I did the exact same thing to order the products by entity_id also.

public function getAssociatedProducts($product = null)
{
    if (!$this->getProduct($product)->hasData($this->_keyAssociatedProducts)) {
        $associatedProducts = array();

        if (!Mage::app()->getStore()->isAdmin()) {
            $this->setSaleableStatus($product);
        }

        $collection = $this->getAssociatedProductCollection($product)
            ->addAttributeToSelect('*')
            ->addFilterByRequiredOptions()
            ->setPositionOrder()
            //MRD added to order by product id also.
            ->addAttributeToSort('entity_id', 'ASC')
            //END MRD
            ->addStoreFilter($this->getStoreFilter($product))
            ->addAttributeToFilter('status', array('in' => $this->getStatusFilters($product)));

        foreach ($collection as $item) {
            $associatedProducts[] = $item;
        }

        $this->getProduct($product)->setData($this->_keyAssociatedProducts, $associatedProducts);
    }
    return $this->getProduct($product)->getData($this->_keyAssociatedProducts);
}

This worked for me in Magento 1.4.1.1. Note that you are still ordering by position. so your query takes this into account.

1
votes

Maybe this can help:

$_associatedProducts = $this->getAssociatedProducts();

usort($_associatedProducts, function ($a, $b) {
    if (intval($a->getCustomPosition())==intval($b->getExtraPosition())) {
        return 0;
    }
    return intval($a->getExtraPosition())<intval($b->getExtraPosition()) ? -1 : 1;
});
0
votes

I've also bumped into this type of problem; searched extensively as well and as a result, I found this thread but with no answers.. still no answers!.

Unfortunately seems like getAssociatedProducts() only returns an associative tree array instead of the regular ProductCollection which has that method (addAttributeToSort) that we want.

This is a bit hackish, but what I did instead is:

<?php 
foreach($_associatedProducts as $_item) {
    $index[$_item->getAttributeText('my_attribute')] = $_item; 
}
ksort($index);
?>

The result here is that we will then have an associative array sorted by key. we can then use that and proceed displaying the associated products as so:

<table class="data-table grouped-items-table" id="super-product-table">
<?php foreach($index as $_item) ?>
<tr>
     <td><?= $_item->getName() ?></td>
     <td><?= $this->getPriceHtml($_item, true) ?></td>
     <!-- etc.... some other stuff you want to display-->
</tr>
<?php endforeach; ?>
</table>

Not a really good solution imo, but not bad as well though. works for me! If anyone has a more elegant solution though, I would love to see it as well! :D cheers.

0
votes

This solution works well until you have several associated products with the same 'my-attribute' value, like size or price. In that case it only picks one of the options and skips the rest. If the values of the attribute that is used to sort products by is of the same value, I change them adding an increasing counter variable so all the options are displayed. Not the most elegant solution but it worked for me. By the way you can create several of these indexes to customize sorting method for different attribute sets.

<?php $key_count = 1; ?>
<?php foreach($_associatedProducts as $_item) {
            $index[$_item->getAttributeText('wheel_size') . "-" . $key_count] = $_item; 
            $key_count++;
            }
            ksort($index);
?>

Also if your attribute values are numbers stored as text, maybe adding a sort flag to ksort would change them to numeric type just for sorting purpose, like ksort($index, SORT_NUMERIC)