2012-02-27 9 views
6

C'è un modo semplice per filtrare una raccolta di prodotti per più categorie? Per ottenere tutti gli oggetti in una delle categorie elencate? addCategoryFilter non sembra consentire un array.Collezione di filtri Magento raccolta di più categorie

È l'unico modo per ottenere separatamente le raccolte per ogni categoria di interesse, quindi unirle?

capisco è usato per essere possibile con qualcosa come

addAttributeToFilter('category_ids',array('finset'=>array('1','2'))) 

o simili, ma che questo non è più possibile dal 1.4.

Nota: sto usando 1.6, e nel caso di qualsiasi uso, sto usando qualcosa di simile:

$product = Mage::getModel('catalog/product'); 
$_productCollection = $product->getCollection() 
    ->addAttributeToSelect('*') 
    ->addAttributeToFilter('status',1) 
    ->addStoreFilter(); 
+0

Unfortunetly Non c'è un modo semplice per farlo. – xyz

risposta

4

Il modo Magento funziona ora, è quello di ottenere lo Store e sul negozio , è possibile ottenere le categorie dalla raccolta dati come $ oStoreCollection-> addCategoryFilter (array ('1', '2'));

mi sono imbattuto in una soluzione che potrebbe aiutare, che si trova qui a:

http://www.magentocommerce.com/boards/&/viewthread/201114/#t329230

Il codice che usano, sembra questo: Override Mage/Catalogo/Modello/Resource/Eav/MySQL4/prodotto/Raccolta, e aggiungere i seguenti metodi:

public function addCategoriesFilter($categories) 
    { 
     $this->_productLimitationFilters['category_ids'] = $categories; 

     if ($this->getStoreId() == Mage_Core_Model_App::ADMIN_STORE_ID) { 
      $this->_applyZeroStoreProductLimitations(); 
     } else { 
      $this->_applyProductLimitations(); 
     } 

     return $this; 
    } 

    protected function _applyProductLimitations() 
    { 
     $this->_prepareProductLimitationFilters(); 
     $this->_productLimitationJoinWebsite(); 
     $this->_productLimitationJoinPrice(); 
     $filters = $this->_productLimitationFilters; 

     // Addition: support for filtering multiple categories. 
     if (!isset($filters['category_id']) && !isset($filters['category_ids']) && !isset($filters['visibility'])) { 
      return $this; 
     } 

     $conditions = array(
      'cat_index.product_id=e.entity_id', 
      $this->getConnection()->quoteInto('cat_index.store_id=?', $filters['store_id']) 
     ); 
     if (isset($filters['visibility']) && !isset($filters['store_table'])) { 
      $conditions[] = $this->getConnection() 
       ->quoteInto('cat_index.visibility IN(?)', $filters['visibility']); 
     } 

     // Addition: support for filtering multiple categories. 
     if (!isset($filters['category_ids'])) { 
      $conditions[] = $this->getConnection() 
       ->quoteInto('cat_index.category_id=?', $filters['category_id']); 
      if (isset($filters['category_is_anchor'])) { 
       $conditions[] = $this->getConnection() 
        ->quoteInto('cat_index.is_parent=?', $filters['category_is_anchor']); 
      } 
     } else { 
      $conditions[] = $this->getConnection()->quoteInto('cat_index.category_id IN(' . implode(',', $filters['category_ids']) . ')', ""); 
     } 

     $joinCond = join(' AND ', $conditions); 
     $fromPart = $this->getSelect()->getPart(Zend_Db_Select::FROM); 
     if (isset($fromPart['cat_index'])) { 
      $fromPart['cat_index']['joinCondition'] = $joinCond; 
      $this->getSelect()->setPart(Zend_Db_Select::FROM, $fromPart); 
     } 
     else { 
      $this->getSelect()->join(
       array('cat_index' => $this->getTable('catalog/category_product_index')), 
       $joinCond, 
       array('cat_index_position' => 'position') 
      ); 
     } 

     $this->_productLimitationJoinStore(); 

     Mage::dispatchEvent('catalog_product_collection_apply_limitations_after', array(
      'collection' => $this 
     )); 

     return $this; 
    } 

    protected function _applyZeroStoreProductLimitations() 
    { 
     $filters = $this->_productLimitationFilters; 

     // Addition: supprot for filtering multiple categories. 
     $categoryCondition = null; 
     if (!isset($filters['category_ids'])) { 
      $categoryCondition = $this->getConnection()->quoteInto('cat_pro.category_id=?', $filters['category_id']); 
     } else { 
      $categoryCondition = $this->getConnection()->quoteInto('cat_pro.category_id IN(' . implode(',', $filters['category_ids']) . ')', ""); 
     } 

     $conditions = array(
      'cat_pro.product_id=e.entity_id', 
      $categoryCondition 
     ); 
     $joinCond = join(' AND ', $conditions); 

     $fromPart = $this->getSelect()->getPart(Zend_Db_Select::FROM); 
     if (isset($fromPart['cat_pro'])) { 
      $fromPart['cat_pro']['joinCondition'] = $joinCond; 
      $this->getSelect()->setPart(Zend_Db_Select::FROM, $fromPart); 
     } 
     else { 
      $this->getSelect()->join(
       array('cat_pro' => $this->getTable('catalog/category_product')), 
       $joinCond, 
       array('cat_index_position' => 'position') 
      ); 
     } 

     return $this; 
    } 

e allora viene chiamato in questo modo:

$collection = Mage::getModel('catalog/product')->getCollection() 
         ->addAttributeToSelect('*') 
         ->distinct(true) // THIS IS WHAT YOU NEED TO ADD 
         ->addCategoriesFilter($category->getAllChildren(true)); // Make sure you don't forget to retrieve your category here. 

HTH

+0

Grazie per quello. Ho aggiunto entrambi e ora ricevo un errore di metodo sconosciuto. Per qualche ragione non riconosce cosa è stato aggiunto, qualche pensiero? –

+0

'Errore irreversibile: chiamata al metodo non definito Mage_Catalog_Model_Resource_Product_Collection :: addCategoriesFilter() ....' –

+0

'Mago/Catalogo/Modello/Risorsa/Eav/Mysql4/Prodotto/Collection.php' non sembra essere stato caricato in all –

9

Ecco un metodo che non richiede modifiche al core. È preso da this post con l'aggiunta della clausola 'gruppo' per gestire record di prodotti duplicati.

$categories = array(7,45,233); 

     $collection = Mage::getModel('catalog/product')->getCollection() 
      ->addAttributeToSelect('*') 
      ->joinField('category_id', 
       'catalog/category_product', 
       'category_id', 
       'product_id=entity_id', 
       null, 
       'left') 
      ->addAttributeToFilter('category_id', array('in' => $categories)); 
     $collection->getSelect()->group('e.entity_id'); 
+0

Il join funziona ma il filtro non lo è. Nulla viene aggiunto alla clausola 'WHERE'. –

+1

Ho provato anche questa soluzione e mi sono imbattuta nello stesso problema di @ButtleButkus ... Vedo che il join è stato aggiunto alla query generata, ma nessuna condizione WHERE. Usiamo Magento EE 1.12 (aka CE 1.7). –

+5

Sto passando il codice e questa soluzione funzionerebbe quando il catalogo flat di Magento è disattivato. Quando il catalogo flat è abilitato, si verifica quanto segue. Il metodo addAttributeToFilter riconosce che il campo category_id non si trova nell'elenco SELECT e chiama addAttributeToSelect per aggiungerlo. Il metodo addAttributeToSelect fallisce perché category_id non è un attributo di prodotto e nessun filtro viene aggiunto alla raccolta. –

3

Se si desidera filtrare su più categorie, l'utilizzo e (quindi un prodotto deve essere nella categoria A, B e C di presentarsi, è necessario disporre di più join:

$products = Mage::getModel('catalog/product')->getCollection() 
    ->joinField('category_id_1', 'catalog/category_product', 'category_id', 'product_id=entity_id', null, 'left') 
    ->joinField('category_id_2', 'catalog/category_product', 'category_id', 'product_id=entity_id', null, 'left') 
    ->addAttributeToFilter('category_id_1', array('eq' => 358)) 
    ->addAttributeToFilter('category_id_2', array('eq' => 252)) 
// etc... 
; 
0
  • Magento 1.8.0.0;
  • piatto catalogo abilitato in amministrazione;
  • assicurati di aver memorizzato nella cache il blocco in cui si inserisce questo;
  • Do Non aggiungere questo nei temi pagati ..
  • Il join interno hard-coded qui riproduce questo:

    $collection->setVisibility(Mage::getSingleton('catalog/product_visibility')->getVisibleInCatalogIds());

    senza 'cat_index.category_id = 2'

$category = Mage::getModel('catalog/category')->load(100); 
$allChildsIds = $category->getAllChildren($category); 

$visibility = Mage::getModel('catalog/product_visibility'); 

$collection = Mage::getResourceModel('catalog/product_collection'); 
$collection = $this->_addProductAttributesAndPrices($collection) 
    ->addStoreFilter() 
    ->setFlag('do_not_use_category_id', true) 
    ->setFlag('disable_root_category_filter', true) 
    ->addAttributeToSort('created_at', 'desc'); 

$whereCategoryCondition = $collection->getConnection() 
    ->quoteInto('cat_index.category_id IN(?) ', $allChildsIds); 
$collection->getSelect()->where($whereCategoryCondition); 

$conditions = array(); 
$conditions[] = "cat_index.product_id = e.entity_id"; 
$conditions[] = $collection->getConnection() 
    ->quoteInto('cat_index.store_id = ? ', Mage::app()->getStore()->getStoreId()); 
$conditions[] = $collection->getConnection() 
    ->quoteInto('cat_index.visibility IN(?) ', $visibility->getVisibleInCatalogIds()); 

$collection->getSelect()->join(
    array('cat_index' => $collection->getTable('catalog/category_product_index')), 
    join(' AND ', $conditions), 
    array() 
); 

$collection 
    ->setPageSize(3) 
    ->setCurPage(1); 

$collection->load(); 
0

filtro di raccolta del prodotto utilizzando più categorie ids

$all_categories = array('3','13','113'); 
$productCollection = Mage::getModel('catalog/product')->getCollection(); 
$productCollection->joinField('category_id', 'catalog/category_product', 'category_id', 
        'product_id = entity_id', null, 'left') 
        ->addAttributeToSelect('*') 
        ->addAttributeToFilter('type_id', array('eq' => 'simple')) 
        ->addAttributeToFilter('category_id', array($all_categories)); 
foreach($productCollection as $product) 
{ 
    echo $product->getId() .$product->getName() . "<br/>"; 
} 

È possibile rimuovere la condizione per tipo di prodotto cioè type_id o modificarlo secondo il requisito.

1

sono riuscito a risolvere questo (dopo molti tentativi ed errori) con il seguente codice:

$collection = Mage::getModel('catalog/product')->getCollection(); 
$collection->addAttributeToFilter('status', 1); 
$collection->addAttributeToSelect(array('name','sku','price','small_image')); 

// Filter by multiple categories 
$collection->joinField('category_id','catalog/category_product','category_id','product_id=entity_id',null,'left'); 
$data_cats = $this->getRequest()->getParam('categories'); 
// Or $data_cats = array(85,86,87,88); 

     $filter_cats = array(); 
     foreach ($data_cats as $value_cats) { 
     $filter_cats[] = array(
     'attribute' => 'category_id', 
     'finset' => $value_cats 
    ); 
} 

$collection->addAttributeToFilter($filter_cats); 

Spero che questo aiuti qualcuno;)

Problemi correlati