非フラット属性によるフィルター製品コレクション
-
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)));
Colinmの答えが機能する理由は、 app/code/core/Mage/Catalog/Model/Resource/Product/Collection.php
's 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
メソッドは、要求された特定の属性のクエリに結合を追加します。属性がすでにフラットテーブルにある場合でも機能しますが、フラットテーブルを純粋に使用するよりも効率がわずかに低くなります。
私はaを使用しました left
そこに参加して、それが製品を取得することを確認するために my_custom_attribute
それらの製品には設定されていません。それを変更します inner
あなたがどこで行に興味があるなら my_custom_attribute
設定されています。
フィルターに追加します(上記のColinmによる):
$_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()
属性を作成するときは、グローバルレベルでフィルタリング可能である必要があります。このようにして、Layaredナビゲーションで使用できます。また、属性がドロップダウンまたはマルチセレクトである必要があります。この場合、私はあなたのニーズに合わせてコアファイルを変更することに対して個人的にアドバイスします