Фильтруя сборы продуктов по атрибуту без флат

magento.stackexchange https://magento.stackexchange.com/questions/1469

  •  16-10-2019
  •  | 
  •  

Вопрос

Я делаю следующее:

$productCollection = Mage::getModel('catalog/product')
    ->getCollection();

$productCollection
    ->addAttributeToFilter('my_attribute', 1);

my_attribute не в плоских таблицах, но плоские таблицы включены.

Я продолжаю получать полную коллекцию.

Причина, кажется, в \Mage_Catalog_Model_Resource_Product_Collection::addAttributeToSelect:

$columns = $this->getEntity()->getAttributeForSelect($attributeCode);

Нет $this->getEntity() это случай Mage_Catalog_Model_Resource_Product_Flat которые приносят плоские поля - и, если их не найдено, просто возвращает NULL.

Как чистый способ добавить атрибут без плата в фильтр сбора?

В моем случае это не чувствует, чтобы добавить атрибут к плоской таблице.

Это было полезно?

Решение

Вы можете присоединиться к необходимому столу самостоятельно.

$productCollection = Mage::getModel('catalog/product')
->getCollection();

$table = Mage::getSingleton('eav/config')->getAttribute('catalog_product', 'my_attribute')->getBackend()->getTable();
$attributeId = Mage::getSingleton('eav/config')->getAttribute('catalog_product', 'my_attribute')->getAttributeId();

$productCollection->getSelect()->join(array('attributeTable' => $table), 'e.entity_id = attributeTable.entity_id', array('my_attribute' => 'attributeTable.value'))
                            ->where("attributeTable.attribute_id = ?", $attributeId)
                            ->where("attributeTable.value = ?", 1);

Вы можете присоединиться к Store_id.

Другие советы

Взлом (CE 1.6.2.0+) состоит в том, чтобы передать условие как массив и верьте, хотите нет, что это работает как предполагалось:

$collection->addFieldToFilter(array(array('attribute' => 'my_attribute', 'eq' => 1)));

Причина, по которой работает Ответ Колинма, связана с кодом в app/code/core/Mage/Catalog/Model/Resource/Product/Collection.phpS. addAttributeToFilter метод Если вы используете этот формат массива, он не звонит addAttributeToSelect. Анкет В плоском режиме, addAttributeToSelect молча терпит неудачу, если атрибут нет в плоской таблице.

(Ниже приведен переосмысление моего ответа на https://stackoverflow.com/questions/6271284/can-i-add-other-attributes-to-magentos-flat-product-catalog-table/17021620 - Я не уверен, что это за этикет, но знаю, что я бы нашел его полезным)

Я хотел «чистого» решения для выбора и фильтрации на атрибутах, не являющихся флатом, которые:

  • Не требует, чтобы атрибут имел конкретные настройки в администраторе (он может быть добавлен пользователем или скрыт на передней части)
  • работает как для плоского, так и для неплаттного режима

Я использовал соответствующую коллекцию продуктов, но это относится к любой коллекции EAV.

Неудачный код:

$_product = Mage::getModel('catalog/product')->loadByAttribute( 'sku', 'ABC123' );
$coll = $_product->getTypeInstance()->getAssociatedProductCollection()
    ->addAttributeToSelect( 'my_custom_attribute' )
    ->addAttributeToFilter( 'my_custom_attribute', 3 )
;

В плоском режиме приведенный выше код молча не может выбрать или фильтровать на атрибуте, если это произойдет не в плоской таблице.

Добавление к выбору:

$_product = Mage::getModel('catalog/product')->loadByAttribute( 'sku', 'ABC123' );
$coll = $_product->getTypeInstance()->getAssociatedProductCollection()
    ->joinAttribute( 'my_custom_attribute', 'catalog_product/my_custom_attribute', 'entity_id', null, 'left' )
    ->addAttributeToSelect( 'my_custom_attribute' )
;

А joinAttribute Метод добавляет присоединение к запросу для конкретного запрошенного атрибута. Он по -прежнему работает, когда атрибут уже находится в плоской таблице, но будет немного менее эффективным, чем чисто используя плоскую таблицу.

Я использовал left Присоединяйтесь туда, чтобы убедиться, что он получает продукты, если my_custom_attribute не установлен на этих продуктах. Изменить это для inner Если вы заинтересованы только в рядах, где my_custom_attribute установлен.

Добавление к фильтру (согласно Колинму выше):

$_product = Mage::getModel('catalog/product')->loadByAttribute( 'sku', 'ABC123' );
$coll = $_product->getTypeInstance()->getAssociatedProductCollection()
    ->addAttributeToFilter( array( array( 'attribute' => 'my_custom_attribute', 'eq' => 3 ) ) )
;

Приведенный выше код добавит его в выбор, а также подчиняться вашему фильтру.

(Протестировано в CE 1.6.2.0)

в Mage_Rss Модуль. Они используют тот факт, что плоские таблицы всегда выключены в магазине администратора, и поэтому просто подражают магазину администратора.

class Mage_Rss_Helper_Data {

[...]

/**
 * Disable using of flat catalog and/or product model to prevent limiting results to single store. Probably won't
 * work inside a controller.
 *
 * @return null
 */
public function disableFlat()
{
    /* @var $flatHelper Mage_Catalog_Helper_Product_Flat */
    $flatHelper = Mage::helper('catalog/product_flat');
    if ($flatHelper->isEnabled()) {
        /* @var $emulationModel Mage_Core_Model_App_Emulation */
        $emulationModel = Mage::getModel('core/app_emulation');
        // Emulate admin environment to disable using flat model - otherwise we won't get global stats
        // for all stores
        $emulationModel->startEnvironmentEmulation(0, Mage_Core_Model_App_Area::AREA_ADMINHTML);
    }
}

После начала эмуляции вы должны сбросить ее с emulationModel->stopEnvironmentEmulation()

Когда вы создаете атрибут, он должен быть на глобальном уровне и отфильтруемый. Таким образом, это будет использоваться в индивидуальной навигации. Также это потребует, чтобы атрибут был раскрывающимся или многосекционным. Я бы лично посоветовал с изменением основных файлов в соответствии с вашими потребностями в этом случае

Лицензировано под: CC-BY-SA с атрибуция
Не связан с magento.stackexchange
scroll top