Filterproduktsammlung nach Nicht-Flat-Attribut
-
16-10-2019 - |
Frage
Ich mache Folgendes:
$productCollection = Mage::getModel('catalog/product')
->getCollection();
$productCollection
->addAttributeToFilter('my_attribute', 1);
my_attribute
befindet sich nicht in den flachen Tischen, aber flache Tische sind aktiviert.
Ich bekomme immer wieder die vollständige Sammlung.
Der Grund scheint in zu sein \Mage_Catalog_Model_Resource_Product_Collection::addAttributeToSelect
:
$columns = $this->getEntity()->getAttributeForSelect($attributeCode);
Nein $this->getEntity()
ist eine Instanz von Mage_Catalog_Model_Resource_Product_Flat
Das holt die flachen Felder ab - und wenn keiner gefunden wird, gibt es einfach NULL zurück.
Was ist ein sauberer Weg, um dem Sammelfilter ein Nicht-Flat-Attribut hinzuzufügen?
In meinem Fall wird es nicht erkennen, das Attribut zur flachen Tabelle hinzuzufügen.
Lösung
Sie könnten sich dem notwendigen Tisch selbst anschließen.
$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);
Vielleicht möchten Sie auch mit store_id beitreten.
Andere Tipps
Ein Hack (CE 1.6.2.0+) soll die Bedingung als Array bestehen und glauben, dass dies wie beabsichtigt funktioniert:
$collection->addFieldToFilter(array(array('attribute' => 'my_attribute', 'eq' => 1)));
Der Grund, warum die Antwort von Colinm funktioniert, ist der Code in app/code/core/Mage/Catalog/Model/Resource/Product/Collection.php
's addAttributeToFilter
Methode. Wenn Sie dieses Array -Format verwenden, ruft es nicht auf addAttributeToSelect
. Im Flachmodus, addAttributeToSelect
fällt lautlos fehllos, wenn sich das Attribut nicht in der flachen Tabelle befindet.
(Unten finden Sie eine Wiederholung meiner Antwort auf https://stackoverflow.com/questions/6271284/can-i-add-other-attributes-to-magentos-flat-product-catalog-table/17021620 - Ich bin mir nicht sicher, was die Etikette dafür ist, weiß aber, dass ich es hilfreich gefunden hätte)
Ich wollte eine "saubere" Lösung für die Auswahl und Filterung von Nicht-Flat-Attributen für die Flat-Mode-Sammlung, die:
- erfordert nicht, dass das Attribut spezifische Einstellungen im Administrator aufweist (es kann von einem Benutzer hinzugefügt oder am vorderen Ende versteckt).
- Funktioniert sowohl für den flachen als auch für den Nicht-Flat-Modus
Ich habe die zugehörige Produktsammlung verwendet, dies gilt jedoch für jede EAV -Sammlung.
Fehlercode:
$_product = Mage::getModel('catalog/product')->loadByAttribute( 'sku', 'ABC123' );
$coll = $_product->getTypeInstance()->getAssociatedProductCollection()
->addAttributeToSelect( 'my_custom_attribute' )
->addAttributeToFilter( 'my_custom_attribute', 3 )
;
Im flachen Modus kann der obige Code stillschweigend im Attribut ausgewählt oder filtern, wenn es sich nicht in der flachen Tabelle befindet.
Hinzufügen zur Auswahl:
$_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' )
;
Das joinAttribute
Die Methode fügt eine Join zur Abfrage für das angeforderte spezifische Attribut hinzu. Es funktioniert immer noch, wenn sich das Attribut bereits in der flachen Tabelle befindet, ist jedoch etwas weniger effizient als nur mit der flachen Tabelle.
Ich habe a verwendet left
Melden Sie sich dort an, um sicherzustellen, dass es Produkte holt, wenn my_custom_attribute
ist nicht auf diese Produkte eingestellt. Ändern Sie das für inner
Wenn Sie nur an Zeilen interessiert sind, wo my_custom_attribute
ist eingestellt.
Hinzufügen zum Filter (gemäß Colinm oben):
$_product = Mage::getModel('catalog/product')->loadByAttribute( 'sku', 'ABC123' );
$coll = $_product->getTypeInstance()->getAssociatedProductCollection()
->addAttributeToFilter( array( array( 'attribute' => 'my_custom_attribute', 'eq' => 3 ) ) )
;
Der obige Code fügt ihn dem Auswählen hinzu und folgt Ihrem Filter.
(getestet in CE 1.6.2.0)
In dem Mage_Rss
Modul Sie benutzten das A Hacky-Methode, um die flachen Tische zu deaktivieren. Sie verwenden die Tatsache, dass flache Tische immer im Admin -Geschäft ausgeschöpft sind und so den Administratorgeschäft emulieren.
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);
}
}
Nach dem Beginn der Emulation sollten Sie sie zurücksetzen emulationModel->stopEnvironmentEmulation()
Wenn Sie das Attribut erstellen, sollte es auf globaler Ebene und filterbar sein. Auf diese Weise wird es in der Layared Navigation verwendbar sein. Außerdem muss das Attribut eine Dropdown- oder Multiselect sein. Ich würde persönlich beraten, die Kerndateien zu ändern, um in diesem Fall Ihren Anforderungen zu entsprechen