|
A few days ago I upgraded from 1.1.8 to 1.2.0 and then 1.2.0.1. I was very thorough after the upgrade and ran a UNIX diff to compare EVERY file in the distribution against my local copies to ensure I had an accurate copy of every one. In addition, I ran diffs to compare my modified theme files against the default theme files they are derived from to be sure that I copied over any changes that were made other than the look-and-feel stuff that we’ve customized locally.
After this, I got a report from a user that the Best Value sort was not working. I have verified this is the case. However, sort by price or name both work fine. Products sorted by Best Value are displayed unsorted (actually sorted by entity_id ascending).
I traced through various classes and methods to figure out what was going on when setOrder was called on a collection and set up a number of “break points” in the code to see what variables were being set to what at various points.
Mage_Eav_Model_Entity_Collection_Abstract->addAttributeToSort() is where I end up:
public function addAttributeToSort($attribute, $dir='asc') { if (isset($this->_joinFields[$attribute])) { $this->getSelect()->order($this->_getAttributeFieldName($attribute).' '.$dir); return $this; } if (isset($this->_joinAttributes[$attribute])) { $attrInstance = $this->_joinAttributes[$attribute]['attribute']; $entityField = $this->_getAttributeTableAlias($attribute).'.'.$attrInstance->getAttributeCode(); } else { $attrInstance = $this->getEntity()->getAttribute($attribute); $entityField = 'e.'.$attribute; } if ($attrInstance) {
if ($attrInstance->getBackend()->isStatic()) { $this->getSelect()->order($entityField.' '.$dir); } else { $this->_addAttributeJoin($attribute, 'left'); if (isset($this->_joinAttributes[$attribute])) { $this->getSelect()->order($attribute.' '.$dir); } else { $this->getSelect()->order($this->_getAttributeTableAlias($attribute).'.value '.$dir); } } }
return $this; }
At the top of this function I can print out $attribute and $dir and demonstrate that this is where the sort code ultimately goes. When called from catalog/block/product/list, the else block gets hit:
else { $attrInstance = $this->getEntity()->getAttribute($attribute); $entityField = 'e.'.$attribute; }
After this point $attriInstance is set to false, presumably because catalog_category_product_index.position is not part of the EAV system so the EAV functions can’t return a proper AttributeInstance.
After this point, the function falls through to the return without ever setting a sort order on the query that is being built in the collection.
If I add the following code directly above the return statement, I can get Best Value sorting to work properly:
if ($attribute == 'position') { $this->getSelect()->order("position $dir"); }
It is easy to verify this with a $this->getSelect()->__toString() printout on either side of the order() function call.
However, since this function is also called from other locations on entities that have position attributes that are part of the EAV system, this will tack on a redundant order clause at the end of the SQL statement.
I am baffled because I’ve been so thorough at ensuring that my code exactly matches the distribution code. The magento demo store is also running 1.2.0.1 and clearly Best Value search works there. There is something weird going on here that warrants further investigation. I am not convinced that this is a 1.2.0.1 bug, but last week Best Value searches worked and this week they don’t.
I put in a bug report, and also figured I’d post here in case anyone else is experiencing this.
|