Filtro di raccolta prodotto per attributo non piatta
-
16-10-2019 - |
Domanda
sto facendo quanto segue:
$productCollection = Mage::getModel('catalog/product')
->getCollection();
$productCollection
->addAttributeToFilter('my_attribute', 1);
my_attribute
non è nelle tabelle piatte, ma le tabelle piatte sono abilitati.
Continuo a ricevere la collezione completa.
Il motivo sembra essere in \Mage_Catalog_Model_Resource_Product_Collection::addAttributeToSelect
:
$columns = $this->getEntity()->getAttributeForSelect($attributeCode);
Non $this->getEntity()
è un'istanza di Mage_Catalog_Model_Resource_Product_Flat
che recupera i campi piatti -. E se non viene trovato, appena restituisce null
Che cosa è un modo pulito per aggiungere un attributo non piatta per il filtro di raccolta?
Nel mio caso non rileva, per aggiungere l'attributo al tavolo piano.
Soluzione
Si potrebbe unirsi al tavolo da soli necessaria.
$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);
Si potrebbe desiderare di unirsi per STORE_ID, anche.
Altri suggerimenti
Un hack (CE 1.6.2.0+) è per passare la condizione come un array e credere o no questo funziona come previsto:
$collection->addFieldToFilter(array(array('attribute' => 'my_attribute', 'eq' => 1)));
La ragione la risposta di ColinM funziona è dovuto al codice nel metodo di app/code/core/Mage/Catalog/Model/Resource/Product/Collection.php
di addAttributeToFilter
. Se si utilizza questo formato array, non chiama addAttributeToSelect
. In modalità piatta, addAttributeToSelect
riuscita automaticamente se l'attributo non è presente nella tabella piatta.
(qui di seguito è un re-hash della mia risposta su https://stackoverflow.com/questions/6271284/can-i-add-other-attributes-to-magentos-flat-product-catalog-table/17021620 - io non sono sicuro di ciò che l'etichetta è per questo, ma so che avrei trovato utile)
I desiderava una soluzione "pulita" per la raccolta piatto selezione di modo e filtrando su attributi non piane, che:
- non richiede l'attributo di avere impostazioni specifiche in admin (che potrebbe essere aggiunto da un utente, o nascosto sul front-end)
- funziona sia piatta e modalità non-flat
ho usato la raccolta del prodotto associato, ma questo vale per qualsiasi raccolta EAV.
Codice mancanza:
$_product = Mage::getModel('catalog/product')->loadByAttribute( 'sku', 'ABC123' );
$coll = $_product->getTypeInstance()->getAssociatedProductCollection()
->addAttributeToSelect( 'my_custom_attribute' )
->addAttributeToFilter( 'my_custom_attribute', 3 )
;
Nel piatto, il codice precedente non riesce automaticamente per selezionare o filtro sul attributo se per caso non è nella tavola piana.
In aggiunta alla select:
$_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' )
;
Il metodo joinAttribute
aggiunge una join alla query per l'attributo specifica richiesta. Ancora funziona quando l'attributo è già nella tavola piana, ma sarà leggermente meno efficiente rispetto puramente utilizzando la tabella piatta.
Ho usato un left
unirsi lì, per garantire che essa recupera i prodotti se my_custom_attribute
non è impostato su tali prodotti. Cambiamento che per inner
se siete interessati solo a righe in cui è impostato my_custom_attribute
.
Aggiunta al filtro (secondo ColinM sopra):
$_product = Mage::getModel('catalog/product')->loadByAttribute( 'sku', 'ABC123' );
$coll = $_product->getTypeInstance()->getAssociatedProductCollection()
->addAttributeToFilter( array( array( 'attribute' => 'my_custom_attribute', 'eq' => 3 ) ) )
;
Il codice qui sopra aggiungerlo al selezionare così come obbedendo il filtro.
(testato in CE 1.6.2.0)
Nel modulo Mage_Rss
hanno usato l'un hacky-metodo per disattivare le tabelle piatte. Usano il fatto, che le tabelle piatti sono sempre fuori nel negozio di amministrazione e quindi basta emulare il negozio di amministrazione.
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);
}
}
Dopo aver avviato l'emulazione si dovrebbe resettare con emulationModel->stopEnvironmentEmulation()
quando si crea l'attributo che dovrebbe essere a livello globale e filtrabile. In questo modo sarà utilizzabile nella navigazione layared. Inoltre richiederà l'attributo di essere una discesa o selezione multipla. Io personalmente consiglio di non modificare i file di base per soddisfare le vostre esigenze in questo caso