Pregunta

TL; DR: Cómo seleccionar atributos múltiples con filtro / desplegables (multi-selecciona sería engorroso)? O utilizar un método diferente?

Considere un producto de seleccionar / atributo desplegable cuyos valores corresponden a cada letra del alfabeto (Inglés en este caso). La etiqueta de la primera opción es "A", su valor es 1. "B" es 2, "C" es 3, y así sucesivamente:

Tengo este atributo asignado para controlar filtros de navegación por capas. Por lo que un usuario puede hacer clic en el vínculo para un valor específico, y agregará ?my_attribute=2 en los parámetros de la petición, y la lista de productos sólo muestra los productos cuyo valor de atributo es "B".

Me gustaría, en cambio, mostrar cualquier producto que del valor del atributo es mayor que o igual a la opción seleccionada. Así, en el caso de que un usuario hace clic en el enlace "B" en la navegación por capas, los resultados serían cada producto de "B-Z" (2-26).

La URL estructura: ?my_attribute=2&my_attribute_3&my_attribute=4... sería feo y además, no funciona, pero la idea está ahí. ?my_attribute=2-26 obviamente sería ideal, pero de nuevo, esto no es lo que hace Magento.

Curiosamente, mediante la búsqueda avanzada proporciona esta estructura URL (a través del controlador de búsqueda avanzada en lugar de nav capas):

?my_attribute%5B%5D=7&my_attribute%5B%5D=8&my_attribute%5B%5D=9&my_attribute%5B%5D=10

Este hecho proporciona los resultados deseados; Sin embargo, esta estructura no funciona con la categoría / páginas en capas, solamente búsqueda avanzada.

Estoy tratando de decidir cuál sería un mejor camino en este punto; Debería abandonar toda la colección producto cargado del bloque product_list incorporada utilidad de la navegación por capas, y en lugar de volver a escribir la base de mi valor del atributo? O debería adaptar algunas funciones de los resultados de búsqueda avanzada para adaptarse a mis necesidades?

Parece que lo mejor sería dejar la funcionalidad de navegación por capas solos haciendo que otros filtros de productos siguen trabajando como se esperaba; pero no parece que permitirá múltiples valores de un atributo único ser seleccionados al mismo tiempo. Como alternativa, una solución sería utilizar un atributo de selección múltiple, y si un producto se le asignaría "B", que tendría que ser asignado todas las opciones de "B-Z". Si bien esto proporcionaría los mayores resultados inmediatos (todo va a trabajar sin más modificaciones), es sin duda una solución descuidado que será propenso a errores y torpe para manejar en el futuro.

¿Fue útil?

Solución

Lo que hice en este caso era reescribir tanto el modelo como el recurso correspondiente, por lo que volver a escribir la primera Mage_Catalog_Model_Layer_Filter_Attribute clase para ser capaz de aceptar múltiples valores. En mi caso, estoy utilizando comas como separador, para que pueda filtrar como ?my_attribute=1,2,3

En el apply() método que analizar el atributo para poner los diferentes valores en una matriz:

  public function apply(Zend_Controller_Request_Abstract $request, $filterBlock)
    {
        $filter = $request->getParam($this->_requestVar);
        if (is_array($filter)) {
            return $this;
        }

        // MP customized
        $filter = explode(',', $filter);
        if (count($filter) < 1) {
            return $this;
        } else if ($filter == '') {
            return $this;
        }

        if (count($filter) == 1) {
            $filter = $filter[0];
        }

        if ($filter == '') {
            return $this;
        }

        if ($filter) {
            $this->_initItems();
            $this->_getResource()->applyFilterToCollection($this, $filter);
            $text = '';
            foreach ($filter as $att) {
                ($text == '') ? $text = $this->_getOptionText($att) : $text .= ', '.$this->_getOptionText($att);
            }
            if (count($filter) == 1) {
                $text = $this->_getOptionText($filter);
            }
            $this->getLayer()->getState()->addFilter($this->_createItem($text, $filter));
        }
        // End MP customized
        return $this;
      }

A continuación, en el Mage_Catalog_Model_Resource_Eav_Mysql4_Layer_Filter_Attribute archivo que tiene que asegurarse de que son capaces de filtro para varios valores en la consulta, por lo que volvió a escribir el siguiente método como este:

     public function applyFilterToCollection($filter, $value)
    {
        $collection = $filter->getLayer()->getProductCollection();
        $attribute  = $filter->getAttributeModel();
        $connection = $this->_getReadAdapter();
        $tableAlias = $attribute->getAttributeCode() . '_idx';
        $conditions = array(
            "{$tableAlias}.entity_id = e.entity_id",
            $connection->quoteInto("{$tableAlias}.attribute_id = ?", $attribute->getAttributeId()),
            $connection->quoteInto("{$tableAlias}.store_id = ?", $collection->getStoreId()),
            $connection->quoteInto("{$tableAlias}.value IN (?)", $value)
        ); // Added IN (?) notation for arrays


        $collection->getSelect()->join(
            array($tableAlias => $this->getMainTable()),
            join(' AND ', $conditions),
            array()
            // MP Need distinct here to avoid getting the same config product from
            // different basic products when filtering for different values
            // in the same attribute
        )->distinct(true);

        return $this;
    }

Otros consejos

Esta es la navegación por capas con la colección de productos personalizados

<?php
    require_once('app/Mage.php'); //Must have file to begin

    Mage::app()->setCurrentStore(Mage_Core_Model_App::ADMIN_STORE_ID); //Initialize store

    $catId = Mage::app()->getRequest()->getParam('categoryId'); //Pass categoryId in get variable
        $storeId = Mage::app()->getWebsite(true)->getDefaultGroup()->getDefaultStoreId();
        $page_no = Mage::app()->getRequest()->getParam('page_no');
        $params = Mage::app()->getRequest()->getParams(); //Pass attributes in key=>value form to filter results.
        $category = Mage::getModel('catalog/category')->load($catId);

        $layer = Mage::getModel("catalog/layer");
        $layer->setCurrentCategory($category);
        $attributes = $layer->getFilterableAttributes(); //get all filterable attributes available in selected category layered navigation
        $attr = array();
        foreach ($attributes as $attribute) {
            if ($attribute->getAttributeCode() == 'price') {
                $filterBlockName = 'catalog/layer_filter_price';
            } elseif ($attribute->getBackendType() == 'decimal') {
                $filterBlockName = 'catalog/layer_filter_decimal';
            } else {
                $filterBlockName = 'catalog/layer_filter_attribute';
            }
            $attr[$attribute->getAttributeCode()] = $attribute->getFrontendLabel();

        }
        $filters = array_intersect_key($params, $attr);
        $collection = $category->getProductCollection()
                        ->addAttributeToFilter(
                            'status', array('eq' => Mage_Catalog_Model_Product_Status::STATUS_ENABLED))
                        ->addAttributeToSelect('*');
        foreach ($filters as $key => $value) {
            if($key == 'price'){
                $priceFilter = explode('-', $value);
                $collection->addAttributeToFilter('price', array('gteq' => $priceFilter[0]));
                $collection->addAttributeToFilter('price', array('lteq' => $priceFilter[1]));
            }
            else{
$codeId = Mage::getResourceModel('eav/entity_attribute')
    ->getIdByCode('catalog_product', $key)
$collection->getSelect()->join(array('at_'.$key =>'catalog_product_index_eav'),'at_'.$key.'.entity_id = e.entity_id and at_'.$key.'.attribute_id = '.$codeId.' and at_'.$key.'.store_id = '.Mage::helper('mobile')->getStore()->getId())->where('at_'.$key.'.value = '.$value);
            }
        }
        $collection->setPage($page_no, 10);
    foreach($collection as $product){
       echo $product->getName();
    }
Licenciado bajo: CC-BY-SA con atribución
No afiliado a magento.stackexchange
scroll top