2
votes

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;
    }
4
Hello are you talking about sort product by attribute value name not by product attribute position? - drsndodiya
I'm talking about to sort by product attribute position and not attribute value name. At the moment it sorts by the attribute value name and not the attribute position. - WolvDev

4 Answers

3
votes

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.

1
votes

I was also facing the same problem and solved it by using some custom code: I want to share here so that someone will get idea from this: First I got all attributes options of color sorted by their position

$attribute = Mage::getSingleton('eav/config')->getAttribute('catalog_product', 'color');
if ($attribute->usesSource())
{

$options = $attribute->getSource()->getAllOptions('positions');

}

foreach($options as $val)
{   
$color_attr_array[] = $val['label'];
}

I obtained all the attribute options of color sorted by their position

foreach($childProducts as $_childProduct)
{
//get the attribute option of a particular product and find itd key from the attributes array

$color_attr_val = $_childProduct->getAttributeText('color');

$color_pos = array_search($color_attr_val,$color_attr_array);

//make a new array with key indexes of attribute options

$_childproduct_final_arr[$color_pos] =  $_childProduct;

}


ksort($_childproduct_final_arr); 

//This is the final array of products sorted by attribute options position

1
votes

I found the function addValueSortToCollection in Mage_Eav_Model_Entity_Attribute_Source_Table is what defines the sort order. By adding a LEFT JOIN to the table eav_attribute_option and pulling in the sort_order field I was able to sort by the adminhtml position of the attribute. I haven't tested fully but it seems to do what I want.

I created a separate module to rewrite this class, the only modification is to addValueSortToCollection, below this line:

Mage::getResourceModel('eav/entity_attribute_option')
        ->addOptionValueToCollection($collection, $this->getAttribute(), $valueExpr);

I added the following Join, and modified the getSelect statement to sort by position 1st, then alphabetical second:

// add join here to pull in sort_order for attribute
$collection->getSelect()->joinLeft(
        array($this->getAttribute()->getAttributeCode() . '_option' => 'eav_attribute_option'), "{$this->getAttribute()->getAttributeCode()}_option_value_t1.option_id=" . $this->getAttribute()->getAttributeCode() . "_option.option_id"
);

$collection->getSelect()
        ->order("sort_order {$dir}")  // Add sort_order to the select statement
        ->order("{$this->getAttribute()->getAttributeCode()} {$dir}");

return $this;

}

Hope someone finds this helpful.

0
votes

de

Just open this file Mage/Eav/Model/Entity/Attribute/Source/table.php and there is one function is there getAllOptions() in which try this

 $collection = Mage::getResourceModel('eav/entity_attribute_option_collection')
            ->setPositionOrder('asc')
            ->setAttributeFilter($this->getAttribute()->getId())
            ->setStoreFilter($this->getAttribute()->getStoreId())
            ->load();

OR

please try to see weather there is comment or not this in app/code/core/Mage/Catalog/Model/Config.php:

public function getAttributeUsedForSortByArray()
{
  $options = array(
   **‘position’ => Mage::helper(‘catalog’)->__(‘Position’)**
);
foreach ($this->getAttributesUsedForSortBy() as $attribute) {
 /* @var $attribute Mage_Eav_Model_Entity_Attribute_Abstract */
  $options[$attribute->getAttributeCode()] = $attribute->getStoreLabel();
}

  return $options;

}

may this will help you

let me know if you still facing any problem