3

I created a custom price filter (without layered navigation). This function works great on simple products, but configurable products are filtered (maybe because they don't have a price?).

This is my function:

<?php namespace Silvan\Sidebar\Model\Plugin;

use Magento\Catalog\Model\ResourceModel\Product\Collection as ProductCollection;

class SidebarFilter
{
    public function aroundAddFieldToFilter(ProductCollection $collection, \Closure $proceed, $fields, $condition = null)
    {
        if ($fields === 'category_ids') {

            $price  = isset($_GET[ 'price' ]) ? $_GET[ 'price' ] : false;

            if ($price && strpos($price, '-') !== false) {
                $price = explode('-', $price);
                $min   = isset($price[ 0 ]) ? $price[ 0 ] : 0;
                $max   = isset($price[ 1 ]) ? $price[ 1 ] : 9999999;

                $collection->addAttributeToFilter('price', ['gt' => $min]);
                $collection->addAttributeToFilter('price', ['lt' => $max]);
            }
        }

        return $fields ? $proceed($fields, $condition) : $collection;
    }
}

I tried using min_price and max_price, but these attributes are ignored in the filter.

  • You should use addPriceDataFieldFilter to filter on min_price range – Coen Ponsen Mar 7 '18 at 9:32
2
+100

Your code did not for simple products too (because it not include data from special price, tear price, required options, catalog price rules).

Magento using price index mechanism to pre-calculate price for a product. See catalog_product_index_price table. The field min_price contains the minimal possible price for product and layered navigation use this field for filtering.

So, try replace in your code

$collection->addAttributeToFilter('price', ['gt' => $min]);
$collection->addAttributeToFilter('price', ['lt' => $max]);

on

$collection->addFieldToFilter('price', ['from' => $min, 'to' => $max]);
  • Thank you, I already fixed my problem by using ` $select = $collection->getSelect(); $select->where('price_index.min_price >= ' . $min); $select->where('price_index.min_price < ' . $max);`. Your answer does also work. – Silvan Jul 4 '16 at 14:54
0

Configurable products are filtered (maybe because they don't have a price?). > You're right.

I have exactly the same issue when filtering quantity (qty).

Configurable products quantity is 0.

I don't think the team who designed Magento 2 handled this feature to be able to filter by configurable products children attributes.

We will have to analyze the vendor source code to figure out if they did it somewhere somehow.

Another possible fix would be to set price/quantity of configurable products manually by fetching its children attributes. Maybe a custom script/command we could then put into a cron after each stock update/import.

0

Try this code, it filters on min_price range used by configurable products:

class Related extends \Magento\Framework\View\Element\Template
{
  public function __construct(
    \Magento\Backend\Block\Template\Context $context,
    \Magento\Catalog\Model\ResourceModel\Product\CollectionFactory $productCollectionFactory,
    \Magento\Catalog\Model\Product\Attribute\Source\Status $productStatus,
    \Magento\Catalog\Model\Product\Visibility $productVisibility,
    \Magento\Framework\Registry $registry,
    array $data = []
  )
  {
    $this->_productCollectionFactory = $productCollectionFactory;
    $this->productStatus = $productStatus;
    $this->productVisibility = $productVisibility;
    $this->_registry = $registry;
    parent::__construct($context, $data);
  }

  public function getProductCollection()
  {
    try {

      $product = $this->_registry->registry('current_product');

      $range_percentage = 35;
      $price_temp = round($product->getFinalPrice() / 100 * $range_percentage);
      $price_from = $product->getFinalPrice() - $price_temp;
      $price_to = $product->getFinalPrice() + $price_temp;

      $categories = $product->getCategoryIds();

      $collection = $this->_productCollectionFactory->create();
      $collection->addAttributeToSelect('*')
        ->addCategoriesFilter(['in' => $categories])
        ->addPriceDataFieldFilter('%s >= %s', ['min_price', $price_from])
        ->addPriceDataFieldFilter('%s <= %s', ['min_price', $price_to])
        ->addMinimalPrice()
        ->addAttributeToFilter('entity_id', ['neq' => $product->getId()])
        ->addAttributeToFilter('status', ['in' => $this->productStatus->getVisibleStatusIds()])
        ->setVisibility($this->productVisibility->getVisibleInSiteIds())
        ->setPageSize(5);

      return $collection;

    } catch (\Exception $e) {

      var_dump($e->getMessage());
    }
  }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.