Php – Magento – Changing attribute sorting

magentomagento-1.7PHPzend-framework

I'm trying to change the sorting of my products.

I want to use the attribute sort by options not to sort by name but rather sort by position given in the "manage attributes". But only when there's a position (when all is 0 it should sort by name).

For this I need to know in which file the sorting is applied to the product collection. I searched inside app\code\core\Mage\Catalog\Model\Config.php and app\code\core\Mage\Catalog\Block\Product\List.php but neither found anything about the sorting. And maybe some code suggestions, too.

Google isn't helping me with this issue, too so I try it here. Maybe somone can help me with this.

Thanks

EDIT:

As example we take the "Color" attribute, it's a drop-down attribute.

The table inside "manage attributes" looks like this:

Valuename   |   Position
========================
light blue  |       1
blue        |       2
dark blue   |       3
light red   |       4
red         |       5
dark red    |       6

In the frontend I sort by the attribute "Color" and my products will be listed this way:

blue
dark blue
dark red
light blue
light red
red

But I want it to be listed like this:

light blue
blue
dark blue
light red
red
dark red

EDIT2:

    public function getAllOptions($withEmpty = true, $defaultValues = false)
    {
        $storeId = $this->getAttribute()->getStoreId();
        if (!is_array($this->_options)) {
            $this->_options = array();
        }
        if (!is_array($this->_optionsDefault)) {
            $this->_optionsDefault = array();
        }
        if (!isset($this->_options[$storeId])) {
            $collection = Mage::getResourceModel('eav/entity_attribute_option_collection')
                ->setPositionOrder('asc')
                ->setAttributeFilter($this->getAttribute()->getId())
                ->setStoreFilter($this->getAttribute()->getStoreId())
                ->load();
            $this->_options[$storeId]        = $collection->toOptionArray();
            $this->_optionsDefault[$storeId] = $collection->toOptionArray('default_value');
        }
        $options = ($defaultValues ? $this->_optionsDefault[$storeId] : $this->_options[$storeId]);
        if ($withEmpty) {
            array_unshift($options, array('label' => '', 'value' => ''));
        }
        return $options;
    }

Best Answer

This is almost impossible to achieve if you want to go with the actual color attribute. The product collection can get the text value of each color from the EAV structure and run a sorting based on it. But the attribute option table isn't joined to the collection, so there's no way it could know what position you've set for your options.

I would make an workaround for that, maybe not the best overall solution, but you'll get what you want.

Create an attribute with code smth like sorting_color and label Color, and numerical options (e.g. 1,2,3). And assign proper values to each product (so "light blue" would be 1, "blue" is 2 - and so on). Then remove the actual color attribute from sorting, and add your newly created sorting_color.

As I said not the exact solution, but you could get yourself into troubles if you choose to mess up with the product collection sorting.

Related Topic