Извините, нет короткого ответа, который не вводил бы в заблуждение и не путал вещи здесь.
Важный момент # 1: Основная команда Magento не хочет удалять или переименовывать методы из исходного дерева.Культура стартапов означала, что они отказались от тестов, и, будучи публичным проектом, они не могли контролировать то, что люди делали со своим продуктом.Вместо того, чтобы удалять методы и рисковать, они оставят методы на месте, которые вызывают новый метод.Таким образом, даже если есть старый код, который вызывает метод, они покрыты.
Важный момент №2. Цепочка наследования коллекций является неуклюжей и непоследовательно применялась в некоторых частях кодовой базы.Это очищается, но все равно может легко привести вас к петле.
Важный момент # 3: я размышляю над тем, как многое из этого должно быть использовано и произошло.Я не окончательный авторитет здесь, я просто кто-то пытается понять это.Приведенные ниже сведения относятся к 1.6, но эти понятия применимы ко всем версиям
Все коллекции наследуются от класса Varien_Data_Collection_Db
.Это класс, который моделирует базовую концепцию «сбора серии объектов, загруженных из базы данных».Этот класс имеет единственный метод addFieldToFilter
.
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;
}
, который представляет собой простую реализацию, которая добавляет предложение where к теоретическому запросу.
Далее, есть два абстрактных класса, которые имеют Varien_Data_Collection_Db
в качестве предка.Mage_Core_Model_Resource_Db_Collection_Abstract
и Mage_Eav_Model_Entity_Collection_Abstract
.
Mage_Core_Model_Resource_Db_Collection_Abstract
- это класс коллекции для "обычных, не EAV моделей".Он не имеет ни метода addFieldToFilter
, ни метода addAttributeToFilter
.Он основан на реализации базового класса Varien_Data_Collection_Db
.
Mage_Eav_Model_Entity_Collection_Abstract
- это класс коллекции для моделей EAV.У него есть метод addAttributeToFilter
, который является более сложным.
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;
}
Это потому, что запрос атрибута не прямой запрос "где".Кроме того, этот метод был разработан для получения либо имени атрибута, или идентификатора базы данных атрибутов, или экземпляра объекта атрибута.Вы не добавляете поле в фильтр, вы добавляете атрибут в фильтр.Таким образом, в зависимости от реализации EAV и таблицы, в которой хранится атрибут, вам необходимо добавить другой бит кода SQL (прямой запрос «где» в основной таблице, «где» добавляется с помощью одной из таблиц объединения и т. Д.)
Это создает проблему.Поскольку этот объект коллекции EAV наследуется от базового объекта коллекции, addFieldToFilter
все еще существует и все равно добавит базовое условие where в запрос EAV, что может привести в замешательство конечного пользователя, не выполнив то, что он думал.Следовательно, класс коллекции EAV также имеет этот
public function addFieldToFilter($attribute, $condition = null)
{
return $this->addAttributeToFilter($attribute, $condition);
}
, который переносит любой вызов от addFieldToFilter
до addAttributeToFilter
(опять же, в модели EAV).Итак, если у вас есть модель EAV, вы можете использовать addFieldToFilter
или addAttributeToFilter
.Если вы работаете с обычной моделью, вы можете только звонить addFieldToFilter
, addAttributeToFilter
не существует.
В идеале имена методов должны были бы быть унифицированы с самого начала, но как только произошло разделение, команда Magento решила продолжить поддерживать разделение в пользу обратной совместимости.
Подождите, есть еще
В базе кода осталось две коллекции, которые наследуют напрямую от Varien_Data_Collection_Db.Это Mage_Sales_Model_Resource_Sale_Collection
и Mage_Review_Model_Resource_Review_Summary_Collection
.Это число выше в версиях Magento CE до 1.6.Хотя это не влияет на вопрос фильтрации, оно запутывает цепочку наследования, поэтому вам следует остерегаться этого.
Многие не-EAV коллекции будут реализовывать свои собственные addFieldToFilter
для проверки работоспособности переменных или небольшого колебания параметров запроса, если они делают что-то немного нестандартное.
Коллекции EAV также включаются в это действие, переопределяя addAttributeToFilter
.Опять же, это сделано для добавления пользовательской логики, которая не вписывается в базовую загрузку коллекции Magento.