Sorry, there is no short answer that is not misleading or confusing here.
Point # 1: The Magento core team does not want to remove or rename methods from the source tree. A startup culture meant that they avoided testing and were a public project, and that meant that they could not control what people did with their product. Instead of deleting methods and jeopardizing violations, they leave methods that invoke the new method. That way, even if there is old code that calls a method, they are covered.
Point # 2: The collection inheritance chain is disgusting and has been inconsistently applied in some parts of the code base. It clears up, but it can still easily throw you in a loop.
Point 3: I'm thinking about how much of this is for use and has happened. I am not the ultimate authority here, I am just trying to figure it out. The specifics below apply to 1.6, but these concepts apply to all versions.
All collections inherit from the Varien_Data_Collection_Db
class. This is a class that models the basic concept of "collecting a series of objects loaded from the database." This class has a single addFieldToFilter
method.
public function addFieldToFilter($field, $condition=null) { $field = $this->_getMappedField($field); $this->_select->where($this->_getConditionSql($field, $condition), null, Varien_Db_Select::TYPE_CONDITION); return $this; }
which is a simple implementation that adds a where clause to a theoretical query.
Further, there are two abstract classes that have Varien_Data_Collection_Db
as their ancestor. Mage_Core_Model_Resource_Db_Collection_Abstract
and Mage_Eav_Model_Entity_Collection_Abstract
.
Mage_Core_Model_Resource_Db_Collection_Abstract
is a collection class for "regular, not EAV models." It has neither the addFieldToFilter
method nor the addAttributeToFilter
method. It relies on an implementation in the base class Varien_Data_Collection_Db
.
Mage_Eav_Model_Entity_Collection_Abstract
is a collection class for EAV models. It has an addAttributeToFilter
method, which is more complex.
public function addAttributeToFilter($attribute, $condition = null, $joinType = 'inner') { if ($attribute === null) { $this->getSelect(); return $this; } if (is_numeric($attribute)) { $attribute = $this->getEntity()->getAttribute($attribute)->getAttributeCode(); } else if ($attribute instanceof Mage_Eav_Model_Entity_Attribute_Interface) { $attribute = $attribute->getAttributeCode(); } if (is_array($attribute)) { $sqlArr = array(); foreach ($attribute as $condition) { $sqlArr[] = $this->_getAttributeConditionSql($condition['attribute'], $condition, $joinType); } $conditionSql = '('.implode(') OR (', $sqlArr).')'; } else if (is_string($attribute)) { if ($condition === null) { $condition = ''; } $conditionSql = $this->_getAttributeConditionSql($attribute, $condition, $joinType); } if (!empty($conditionSql)) { $this->getSelect()->where($conditionSql, null, Varien_Db_Select::TYPE_CONDITION); } else { Mage::throwException('Invalid attribute identifier for filter ('.get_class($attribute).')'); } return $this; }
This is because an attribute request is not a direct "where" request. In addition, this method was intended to obtain either the attribute name , or the identifier of the attribute database, or the object of the instance object. You do not add a field to the filter; you add an attribute to the filter. Thus, depending on the EAV implementation and the table in which the attribute is stored, you need to add another bit of SQL code (direct, where the query is in the main table, where one of the join tables is added, etc.)
This creates a problem. Since this EAV collection object is inherited from the base collection object, addFieldToFilter
still exists and will continue to add a basic condition in which the EAV request condition can confuse the end user without doing what they think. Therefore, the EAV collection class also has this
public function addFieldToFilter($attribute, $condition = null) { return $this->addAttributeToFilter($attribute, $condition); }
which transfers any call to addFieldToFilter
to addAttributeToFilter
(again, to the EAV model). So, if you have an EAV model, you can use addFieldToFilter
or addAttributeToFilter
. If you are working with a regular model, you can only call addFieldToFilter
, addAttributeToFilter
not exist.
Ideally, the method names would be unified from the very beginning, but after the split, the Magento team decided to continue supporting the split in favor of backward compatibility.
Wait there more
There are two collections left in Codebase that inherit directly from Varien_Data_Collection_Db. These are Mage_Sales_Model_Resource_Sale_Collection
and Mage_Review_Model_Resource_Review_Summary_Collection
. This number is higher in Magento CE versions up to 1.6. Although this does not affect the filtering issue, it confuses the inheritance chain, so you should keep an eye on it.
Many non-EAV collections will implement their own addFieldToFilter
to perform sanity checks on variables or modify query parameters slightly if they do something a little non-standard.
EAV collections are also included in this act, overriding addAttributeToFilter
. Again, this is done to add custom logic that doesn't fit into the base load of the Magento collection.