2012-07-17 6 views
7

Es posible filtrar una colección de Magento usando una matriz de id PERO tienen los resultados de la colección ordenados por el orden de los identificadores pasados ​​al filtro.Magento - Filtro de recopilación por matriz Mantener pedido

Por ejemplo:

$collection = Mage::getModel('catalog/product') 
        ->getCollection() 
        ->addAttributeToFilter('entity_id', array(
         'in' => array(1, 3, 2), 
        )); 

me gustaría tener la colección de productos en orden, de manera que cuando 1,3,2 bucle a través de la colección que salen en ese orden específico?

La única alternativa actualmente tengo es crear manualmente una gran variedad de productos:

$productIds = array(1,3,2); 
$collection = array(); 

foreach($productIds as $productId) { 
    $collection[] = Mage::getModel('catalog/product')->load($productId); 
} 

Obviamente, esto funciona, pero parece como una manera fea de hacer esto.

¿hay alguna manera de hacer esto puramente a través de las colecciones de magento?

Respuesta

0

Esta es una pregunta difícil, aquí hay una solución que debería funcionar:

$collection = Mage::getModel('catalog/product') 
        ->getCollection() 
        ->addAttributeToFilter('entity_id', array(
         'in' => array(1928, 1930, 1929), 
        )) 
      ->addAttributeToSort('entity_id = 1928', 'ASC') 
      ->addAttributeToSort('entity_id = 1930', 'ASC') 
      ->addAttributeToSort('entity_id = 1929', 'ASC') 
      ; 
+0

Hola Gershon, gracias por la respuesta. Tiene sentido con respecto a attributeToSort pero el problema es que el ejemplo addAttributeToFilter anterior es solo un ejemplo, podría haber un número arbitrario de elementos en la matriz. Supongo que podría recorrer cada elemento y llamar a addAttributeToSort, pero luego entrar al territorio donde comencé con el ciclo para crear la colección como una matriz –

1

Puede cargar la colección antes de la clasificación en PHP. Por ejemplo:

$result = array(); 
$productIds = array(1,3,2); 
$collection = Mage::getModel('catalog/product') 
    ->getCollection() 
    ->addAttributeToFilter('entity_id', array('in' => $productIds)) 
    ->load(); 

foreach ($productIds as $productId) { 
    if ($product = $collection->getItemById($productId)) { 
     $result[$productId] = $product; 
    } 
} 

lo demás, puramente con las colecciones, primero debe pasar por el Zend_Db_Select objeto de la colección, para ser capaz de ordenar en las expresiones (lo que no puede ser posible con colecciones basadas por ejemplo, EAV y pide a addAttributeToSort o sortOrder).
Luego puede usar múltiples llamadas order como se indica en la respuesta de Gershon, o usar una sola order con una declaración CASE WHEN THEN generada. Sabiendo que podría depender de la cantidad máxima de ID que deba filtrar.

11
$productIds = array(1,3,2); 

/** 
* Build up a case statement to ensure the order of ids is preserved 
*/ 
$orderString = array('CASE e.entity_id'); 
foreach($productIds as $i => $productId) { 
    $orderString[] = 'WHEN '.$productId.' THEN '.$i; 
} 
$orderString[] = 'END'; 
$orderString = implode(' ', $orderString); 

/** 
* Filter the collection 
*/ 
$productCollection = Mage::getModel('catalog/product')->getCollection() 
    ->addAttributeToFilter('entity_id', array('in' => $productIds)); 

/** 
* Apply the order based on the case statement 
*/ 
$productCollection->getSelect() 
    ->order(new Zend_Db_Expr($orderString)) 
+0

Solución perfecta. Funciona genial. – Muttley75

2

Bastante viejo, pero una solución sencilla que encontré en stackoverflow es

$productIds = array(1,3,2); 
$products = Mage::getModel('catalog/product')->getCollection() 
      ->addAttributeToFilter('entity_id', array('in' => $productIds)); 
$products->getSelect()->order("find_in_set(entity_id,'".implode(',',$productIds)."')"); 

from here on stackoverflow

Cuestiones relacionadas