Filtra la raccolta prodotti per attributo non piatto


14

Sto facendo quanto segue:

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

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

my_attribute non si trova nei tavoli piatti, ma i tavoli piatti sono abilitati.

Continuo a ricevere l'intera collezione.

Il motivo sembra essere in \Mage_Catalog_Model_Resource_Product_Collection::addAttributeToSelect:

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

No $this->getEntity()è un'istanza Mage_Catalog_Model_Resource_Product_Flatche recupera i campi piatti e, se non viene trovata, restituisce null.

Qual è un modo semplice per aggiungere un attributo non piatto al filtro di raccolta?

Nel mio caso non ha senso aggiungere l'attributo alla tabella piatta.


Ciao signore, sei gentile? Hai risolto la confusione ?? WAT è medio di non-flat attribute? Grazie. E non fare magento Confusione. È già confuso
Pratik,

Sto parlando di attributi che non sono nell'indice piatto. Questi sono quelli con "Usato nella scheda di prodotto" impostato su "No".
Alex,

Risposte:


18

Puoi unirti al tavolo necessario tu stesso.

$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);

Potresti voler unirti anche a store_id.


Penso che avrei ancora il problema di non ottenere i prodotti di tutti i negozi. (ogni volta che inizialmente non vedevo questo problema nella mia domanda). Sembra che voglio disabilitare completamente gli indici piatti.
Alex

Se hai bisogno di tutti i prodotti, i tavoli piatti non saranno tuoi amici, sì.
Matthias Zeis,

Immagino che potresti voler modificare la tua domanda o accettare la mia risposta (che funziona per la domanda originale), quindi.
Matthias Zeis,

awasome .. concept
Amit Bera

15

Un hack (CE 1.6.2.0+) è quello di passare la condizione come un array e crederci o no che funzioni come previsto:

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

Qualche idea sul perché funzioni?
Alex,

3
Funziona perché per eav collection addFieldToFilerè un wrapper per addAttributeToFiltere questo ha un'opzione per passare l'attributo come un array:if (is_array($attribute)) { $sqlArr = array(); foreach ($attribute as $condition) { $sqlArr[] = $this->_getAttributeConditionSql($condition['attribute'], $condition, $joinType); } $conditionSql = '('.implode(') OR (', $sqlArr).')'; }
Marius

@Marius, significa che non è un trucco? : P Posso sentirmi bene nell'usarlo?
Erfan,

3
@Erfan. non è un trucco. è una caratteristica.
Marius

Dolce. È ancora strano che l'implementazione della tabella dei prodotti (eav / flat) non venga sottratta a cose semplici come filtrare una collezione. Questo significa che devo sempre usare addFieldToFilter invece di addAttributeToFilter nel mio codice, perché non saprò se sta usando eav o flat? Qual è il punto di addAttributeToFilter comunque?
Erfan,

6

La ragione per cui la risposta di ColinM funziona è grazie al codice a app/code/core/Mage/Catalog/Model/Resource/Product/Collection.php's addAttributeToFiltermetodo. Se si utilizza questo formato di array, non chiama addAttributeToSelect. In modalità flat, addAttributeToSelectnon riesce in modo silenzioso se l'attributo non si trova nella tabella flat.

(di seguito è riportato un hash della mia risposta su /programming/6271284/can-i-add-other-attributes-to-magentos-flat-product-catalog-table/17021620 - Sono non sono sicuro di cosa sia l'etichetta per quello, ma so che l'avrei trovato utile)

Volevo una soluzione "pulita" per la selezione e il filtraggio di raccolte in modalità flat su attributi non piatti, che:

  • non richiede che l'attributo abbia impostazioni specifiche nell'amministratore (potrebbe essere aggiunto da un utente o nascosto nel front-end)
  • funziona sia in modalità flat che non flat

Ho usato la raccolta di prodotti associata, ma questo vale per qualsiasi raccolta EAV.

Codice in errore:

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

In modalità flat, il codice sopra riportato non riesce a selezionare o filtrare silenziosamente l'attributo se non si trova nella tabella flat.

Aggiungendo alla selezione:

$_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 joinAttributemetodo aggiunge un join alla query per l'attributo specifico richiesto. Funziona ancora quando l'attributo è già nella tabella piatta, ma sarà leggermente meno efficiente rispetto all'utilizzo puramente della tabella piatta.

Ho usato un leftjoin lì, per assicurarmi che recuperi prodotti se my_custom_attributenon è impostato su tali prodotti. Cambialo per innerse sei interessato solo alle righe in cui my_custom_attributeè impostato.

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 sopra lo aggiungerà alla selezione e obbedirà al tuo filtro.

(testato in CE 1.6.2.0)


4

Nel Mage_Rssmodulo hanno usato il metodo hacky per disabilitare i tavoli piatti. Usano il fatto che i tavoli piatti sono sempre spenti nell'archivio dell'amministratore e quindi emulano l'archivio dell'amministratore.

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, è necessario ripristinarlo con emulationModel->stopEnvironmentEmulation()


Dov'era questa risposta 3 giorni fa? ; _;
sg3s,

Giusto qui? Da mar 20.
Alex

1

quando crei l'attributo dovrebbe essere a livello globale e filtrabile. In questo modo sarà utilizzabile nella navigazione a strati. Inoltre richiederà che l'attributo sia un menu a discesa o una selezione multipla. Consiglio personalmente di non modificare i file di base in base alle proprie esigenze in questo caso


Non voglio l'attributo nel filtro frontend - Voglio semplicemente fare un filtro di raccolta per uso interno.
Alex
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.