2012-02-03 11 views
5

Quiero filtrar y paginar una colección de productos. todo está bien, excepto la paginación. Solo estoy recuperando toda la colección, en lugar de 3 artículos para la primera página.Magento: paginate colección de productos filtrados

//fetch all visible products 
    $product_collection = Mage::getModel('catalog/product')->getCollection(); 

    //set wanted fields (nescessary for filter) 
    $product_collection->addAttributeToSelect('name'); 
    $product_collection->addAttributeToSelect('description'); 
    $product_collection->addAttributeToSelect('price'); 
    $product_collection->addAttributeToFilter('visibility', array('neq' => 1)); 

    //filter by name or description 
    $product_collection->addFieldToFilter(array(
      array('attribute'=>'name','like'=>$sTerm), 
      array('attribute'=>'description','like'=>$sTerm) 
    )); 

    //filter for max price 
    foreach ($product_collection as $key => $item) { 
     if($item->getPrice() >= $priceTo){ 
      $product_collection->removeItemByKey($key); 
     } 
    } 

    //pagination (THIS DOESNT WORK!) 
    $product_collection->setPageSize(3)->setCurPage(1); 

    //TEST OUTPUT 
    foreach ($product_collection as $product) { 
      echo $product->getName().'<br />'; 
    } 

gracias por su apoyo!

Respuesta

4

Gracias @Ben! Me diste la pista correcta. ¡Ahora funciona! Básicamente estoy creando otra colección y la filtro por los ID de los elementos ya filtrados. Después, es fácil agregar paginación a esa nueva colección. Ese es el código de trabajo:

//fetch all visible products 
    $product_collection = Mage::getModel('catalog/product')->getCollection(); 

    //set wanted fields (nescessary for filter) 
    $product_collection->addAttributeToSelect('name'); 
    $product_collection->addAttributeToSelect('description'); 
    $product_collection->addAttributeToSelect('price'); 
    $product_collection->addAttributeToFilter('visibility', array('neq' => 1)); 

    //filter by name or description 
    $product_collection->addFieldToFilter(array(
      array('attribute'=>'name','like'=>$sTerm), 
      array('attribute'=>'description','like'=>$sTerm) 
    )); 

    //filter for max price 
    foreach ($product_collection as $key => $item) { 
     if($item->getPrice() >= $priceTo){ 
      $product_collection->removeItemByKey($key); 
     } 
    } 

    //build id array out of filtered items (NEW!) 
    foreach($product_collection as $item){ 
     $arrProductIds[]=$item->getId(); 
    } 

    //recreate collection out of product ids (NEW) 
    $product_filtered_collection = Mage::getModel('catalog/product')->getCollection(); 
    $product_filtered_collection->addAttributeToFilter('entity_id', array('in'=>$arrProductIds)); 


    //add pagination (on new collection) (NEW) 
    $product_filtered_collection->setPageSize(3)->setCurPage(1); 


    //TEST OUTPUT 
    foreach ($product_filtered_collection as $product) { 
      echo $product->getName().'<br />'; 
    } 
13

¡Estás tan cerca! Intente mover esa línea $product_collection->setPageSize(3)->setCurPage(1);antes de la primera iteración foreach() sobre la colección.

Las colecciones de Magento son de carga lenta. Hasta que los load() directamente (o los cargue implícitamente a través de una llamada a count() o foreach()), puede modificar las propiedades de la colección que afectan a la consulta subyacente (EDIT: consulte la nota a continuación). Una vez que la colección se haya cargado explícita o implícitamente, solo obtendrá los miembros de la propiedad _items que se hayan establecido.

FYI puede llamar al clear() para dejar las propiedades originales que afectan a la consulta (filtros, clasificadores, límites, uniones, etc.) en su lugar y luego agregar otras propiedades.

HTH

EDITAR: En realidad, el ajuste de propiedades de la consulta es siempre posible, independientemente de _items estado de carga, pero el efecto no será visible hasta que se regenera la colección.

+0

gracias hasta ahora! Traté de regenerar la colección: '$ product_filtered_collection = new Varien_Data_Collection(); foreach ($ product_collection as $ item) { $ product_filtered_collection-> addItem ($ item); } '... y agregó la paginación a esta nueva colección pero eso tampoco funciona –

+0

Ugh. Acabo de volver a leer tu publicación. Tendrás dos problemas más grandes que abordar. Para paginar su colección, el filtrado de precios debe ser parte de la consulta original para cargar datos (que no es así, ya que el 'foreach()' carga primero los datos. Además, según sus necesidades, la lógica del precio final en Magento pueden verse afectados por los observadores que no se ejecutarán para los artículos de esta colección. Lo siento! – benmarks

+0

sí, Ben! me apuntaste en la dirección correcta. Ahora sí funciona. Publicaré el ejemplo de trabajo en aproximadamente 4 horas (causa mis créditos son demasiado bajos) básicamente se trata de crear una nueva colección, filtrarla por los identificadores de los productos y paginarla después. ¡Genial! –

Cuestiones relacionadas