Frage

TL; DR: Wie filtert ich mehrere SELECT/Dropdown-Attribute (Multi-Selekten wären umständlich)? Oder eine andere Methode verwenden?

Betrachten Sie ein Produkt ausgewählt/Dropdown -Attribut, dessen Werte jedem Buchstaben des Alphabets entsprechen (in diesem Fall Englisch). Das Etikett der ersten Option ist "A", ihr Wert ist 1. "B" ist 2, "C" ist 3 und so weiter:

Ich habe dieses Attribut für die Steuerung von Layered Navigation -Filtern zugewiesen. Ein Benutzer kann also auf den Link klicken, um einen bestimmten Wert zu erhalten, und er wird hinzugefügt ?my_attribute=2 In die Anforderungsparameter, und die Produktliste zeigt nur Produkte, deren Attributwert "B" ist.

Ich möchte stattdessen alle Produkte anzeigen, deren Attributwert größer oder gleich der ausgewählten Option ist. Wenn ein Benutzer auf den Link "B" im Layered NAV klickt, sind die Ergebnisse jedes Produkt von "BZ" (2-26).

Die URL -Struktur: ?my_attribute=2&my_attribute_3&my_attribute=4... Wäre hässlich und außerdem funktioniert es nicht, aber die Idee ist da. ?my_attribute=2-26 Wäre offensichtlich ideal, aber das ist nicht das, was Magento tut.

Seltsamerweise bietet die Verwendung erweiterter Suche diese URL -Struktur (über den erweiterten Suchcontroller anstelle von mehrschichtigen NAV):

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

Dies liefert in der Tat die gewünschten Ergebnisse; Diese Struktur funktioniert jedoch nicht mit Kategorie-/Schichtseiten, nur mit fortgeschrittener Suche.

Ich versuche zu entscheiden, welches zu diesem Zeitpunkt ein besserer Weg wäre. Soll ich den integrierten Nutzen der geschichteten Navigation aufgeben und stattdessen die neu schreiben product_list Die geladene Produktsammlung von Block basiert auf meinem Attributwert? Oder sollte ich einige Funktionen aus erweiterten Suchergebnissen an meine Bedürfnisse anpassen?

Es scheint, als wäre es am besten, die Schichtnavigationsfunktionen in Ruhe zu lassen, damit andere Produktfilter weiterhin wie erwartet funktionieren. Es scheint jedoch nicht, dass mehrere Werte aus einem einzigen Attribut gleichzeitig ausgewählt werden. Alternativ würde eine Problemumgehung darin bestehen, ein Multi-Select-Attribut zu verwenden, und wenn ein Produkt "B" zugewiesen würde, müsste es alle Optionen von "BZ" zugewiesen werden. Dies würde zwar die größten sofortigen Ergebnisse liefern (alles wird ohne weitere Modifikationen funktionieren), aber es ist sicherlich eine schlampige Lösung, die in Zukunft fehleranfällige und klobig zu verwalten ist.

War es hilfreich?

Lösung

Was ich in diesem Fall getan habe, war, sowohl das Modell als auch die entsprechende Ressource neu zu schreiben, also schreiben Sie zuerst die Klasse neu. Mage_Catalog_Model_Layer_Filter_Attribute mehrere Werte akzeptieren zu können. In meinem Fall verwende ich Kommas als Trennzeichen, damit ich wie ?my_attribute=1,2,3

In der Methode apply() Ich analysiere das Attribut, um die verschiedenen Werte in ein Array zu setzen:

  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;
      }

Dann in der Datei Mage_Catalog_Model_Resource_Eav_Mysql4_Layer_Filter_Attribute Sie müssen sicherstellen, dass Sie in Ihrer Abfrage mehrere Werte filtern können. Daher habe ich die folgende Methode wie folgt neu geschrieben:

     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;
    }

Andere Tipps

Hier ist eine geschichtete Navigation mit benutzerdefinierter Produktsammlung

<?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();
    }
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit magento.stackexchange
scroll top