0

I want to sort products by sub category as seen in this picture like Sort by Summer Collection as Muzlin summer 20 or Sort by winter collection enter image description here

and i'm following this approach

Vendor\Module\Model\VisualMerchandiser\Sorting\SummerCollection.php

<?php
declare(strict_types=1);
/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */

namespace Vendor\Module\Model\VisualMerchandiser\Sorting;

use Exception;
use Magento\Catalog\Model\Product\Attribute\Source\Status;
use Magento\Catalog\Model\Product\Visibility;
use Magento\Catalog\Model\ResourceModel\Product\Collection;
use Magento\Framework\Data\Collection as CollectionAlias;
use Magento\VisualMerchandiser\Model\Sorting\SortAbstract;
use Magento\VisualMerchandiser\Model\Sorting\SortInterface;

class SummerCollection extends SortAbstract implements SortInterface
{
    /**
     * @inheritDoc
     * @throws Exception
     */
    public function sort(Collection $collection): Collection
    {
        $catIds=[];
        $categoriesId=[];
        foreach ($collection as $product)
        {
            $categoriesId[]= $product->getCategoryIds();
            $catIds=array_merge($catIds, $categoriesId);
        }
        $finalCat = array_unique($catIds);
        $collection->getSelect()->order(new \Zend_Db_Expr('FIELD(category_id,' . implode(',', $finalCat).')'));
        return $collection;
    }

    /**
     * @inheritDoc
     */
    public function getLabel()
    {
        return __('Summer Collection Wise Sorting');
    }
}

3 Answers 3

1

It's a really strange logic in sort method

Potential issues with code are:

  • You need to clone product collection before try to iterate it
  • category_id will be the same for all products because it's a parent category. Better to use table name for prevent ambiguously queries
  • Variable $categoriesId is array of array

Looks like you want to use some concrete category, for me it's look very strange, but it's your business. Looks like you need to define category id which you want to use to sort first and after join catalog_category_product with your subcategory and sort by position and NULL (not in category) to down

3
  • i have explain my question in my answer, from there you will get an idea of what i wanna do.
    – P.A
    Aug 8 at 15:13
  • $collection->addAttributeToSelect('*') ->getSelect() ->reset(Zend_Db_Select::ORDER); $collection->addCategoriesFilter(['in' => 701]); return $collection;
    – P.A
    Aug 9 at 19:55
  • this logic works, but i don't know if this is standard approach?
    – P.A
    Aug 9 at 19:55
0

for example, i have product collection object as in code above, and i want to filter those products who has SUMMER as category from that collection, then what approach would you follow. enter image description here

as you can see here all categories are given and the picture below are i have assign a category for that product and i want to filter those products who are assigned thsese categories. enter image description here My custom Logic, it kind of filter products.

$collection->addAttributeToSelect('*')
        ->getSelect()
        ->reset(Zend_Db_Select::ORDER);
        $collection->addCategoriesFilter(['in' => 701]);
        return $collection;
1
  • filter those products with category id 704
    – P.A
    Aug 8 at 15:15
0
<?php
declare(strict_types=1);
/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */

namespace Vendor\Module\Model\VisualMerchandiser\Sorting;

use Exception;
use Magento\Catalog\Api\CategoryRepositoryInterface;
use Magento\Catalog\Model\Indexer\Product\Price\DimensionCollectionFactory;
use Magento\Catalog\Model\ResourceModel\Product\Collection;
use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Framework\App\Request\Http;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\Indexer\DimensionFactory;
use Magento\Framework\Indexer\ScopeResolver\IndexScopeResolver;
use Magento\Framework\Module\Manager;
use Magento\VisualMerchandiser\Model\Sorting\SortAbstract;
use Magento\VisualMerchandiser\Model\Sorting\SortInterface;
use Zend_Db_Select;

/**
 * Sort product collection wise
 */
class SummerCollection extends SortAbstract implements SortInterface
{
    /**
     * @var Http
     */
    protected Http $request;
    /**
     * @var CategoryRepositoryInterface
     */
    protected CategoryRepositoryInterface $categoryRepository;

    /**
     * @param Manager $moduleManager
     * @param Http $request
     * @param CategoryRepositoryInterface $categoryRepository
     * @param ScopeConfigInterface $scopeConfig
     * @param DimensionCollectionFactory|null $dimensionCollectionFactory
     * @param IndexScopeResolver|null $indexScopeResolver
     * @param DimensionFactory|null $dimensionFactory
     */
    public function __construct(
        Manager $moduleManager,
        Http $request,
        CategoryRepositoryInterface $categoryRepository,
        ScopeConfigInterface $scopeConfig,
        DimensionCollectionFactory $dimensionCollectionFactory = null,
        IndexScopeResolver $indexScopeResolver = null,
        DimensionFactory $dimensionFactory = null
    ) {
        $this->categoryRepository = $categoryRepository;
        $this->request = $request;

        parent::__construct(
            $moduleManager,
            $scopeConfig,
            $dimensionCollectionFactory,
            $indexScopeResolver,
            $dimensionFactory
        );
    }

    /**
     * @inheritDoc
     * @throws Exception
     */
    public function sort(Collection $collection): Collection
    {
        $catIdWithSummer = array();
        $catIdWithoutSummer = array();
        $catIdMerge = array();
        $categories = $this->getCategoryCollection();
        foreach ($categories as $category) {
            if (strpos($category->getName(), 'Summer') !== false) {
                $catIdWithSummer[] = $category->getId();

            } else {
                $catIdWithoutSummer[] = $category->getId();
            }
        }
        $catIdMerge = array_merge($catIdWithSummer, $catIdWithoutSummer);
        $collection->addAttributeToSelect('*')
            ->getSelect()
            ->reset(Zend_Db_Select::ORDER);
        $collection->addCategoriesFilter(['in' => $catIdMerge]);
        return $collection;
    }

    /**
     * @throws LocalizedException
     */
    public function getCategoryCollection()
    {
        $categoryId = (int)$this->request->getParam('id', false);
        $category = $this->categoryRepository->get($categoryId);
        return $category->getChildrenCategories();
    }

    /**
     * @inheritDoc
     */
    public function getLabel()
    {
        return __('Summer Collection Wise Sorting');
    }
}

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.