Magento – Sort products by attribute position

attributesposition;productssorting

In my site I have set a filter for ordering my products by attribute, but the order is alphabetical and I would like the order to be by position attribute setted in backend.

Example attribute color:

Valuename | Position

green | 1

blue | 2

red | 3

The actual result in frontend is product blue then green then red,
I would like the result is green then blue then red

What classes should I modify for resolving this problem?

Best Answer

I assume that the attribute values are usual values, not from a custom source model.
If that is the case, then the sorting is done in the method Mage_Eav_Model_Entity_Attribute_Source_Table::addValueSortToCollection.
Even if there is a custom source model you still need that method for sorting.
What I advice is to rewrite that method and change the way the sorting is done.
You can make that method look like this:

public function addValueSortToCollection($collection, $dir = Varien_Db_Select::SQL_ASC)
{
    $valueTable1    = $this->getAttribute()->getAttributeCode() . '_t1';
    $valueTable2    = $this->getAttribute()->getAttributeCode() . '_t2';
    $valueExpr = $collection->getSelect()->getAdapter()
        ->getCheckSql("{$valueTable2}.value_id > 0", "{$valueTable2}.value", "{$valueTable1}.value");
    $collection->getSelect()
        ->joinLeft(
            array($valueTable1 => $this->getAttribute()->getBackend()->getTable()),
            "e.entity_id={$valueTable1}.entity_id"
            . " AND {$valueTable1}.attribute_id='{$this->getAttribute()->getId()}'"
            . " AND {$valueTable1}.store_id=0",
            array())
        ->joinLeft(
            array($valueTable2 => $this->getAttribute()->getBackend()->getTable()),
            "e.entity_id={$valueTable2}.entity_id"
            . " AND {$valueTable2}.attribute_id='{$this->getAttribute()->getId()}'"
            . " AND {$valueTable2}.store_id='{$collection->getStoreId()}'",
            array($this->getAttribute()->getAttributeCode() => $valueExpr)
        );
    $collection->getSelect()
        ->order("{$this->getAttribute()->getAttributeCode()} {$dir}");

    return $this;
}
Related Topic