2

I want to get product collection for current category while I am on a list page.
I want to get current product collection for current category while ajax call (i want the same collection in the controller which return some data based on collection) so is there any way that I can get the same product collection which was used in list.phtml
Here is code, which returns product collection but results not match 100%

    namespace Vendor\Module\Controller\Index;
    use Magento\Framework\App\Action\Context;

    class Model extends \Magento\Framework\App\Action\Action
    {
        protected $resultJsonFactory;
        protected $request;
        protected $store_manager;
        protected $productRepository;
        protected $searchCriteriaBuilder;
        protected $eavConfig;

        public function __construct(
            Context $context,
            \Magento\Framework\Controller\Result\JsonFactory $resultJsonFactory,
            \Magento\Framework\App\RequestInterface $request,
            \Magento\Store\Model\StoreManagerInterface $store_manager,
            \Magento\Catalog\Api\ProductRepositoryInterface $productRepository,
            \Magento\Framework\Api\SearchCriteriaBuilder $searchCriteriaBuilder,
            \Magento\Catalog\Model\ResourceModel\Product\CollectionFactory $collection,
            \Magento\Catalog\Model\CategoryRepository $categoryRepository,
            \Magento\Catalog\Model\CategoryFactory $categoryFactory,
            \Magento\Eav\Model\Config $eavConfig)
        {
            $this->request = $request;
            $this->resultJsonFactory = $resultJsonFactory;
            $this->store_manager = $store_manager;
            $this->productRepository = $productRepository;
            $this->searchCriteriaBuilder = $searchCriteriaBuilder;
            $this->eavConfig = $eavConfig;
            $this->productCollection = $collection;
            $this->categoryRepository = $categoryRepository;
            $this->_categoryFactory = $categoryFactory;
            parent::__construct($context);
        }

        public function execute()
        {
$data = $this->request->getParams();
$parent_category_id = $data['current_category_id'];
            $productsCollection=$this->getProductCollection($parent_category_id);
            $productsCollection->addAttributeToFilter('make',array('in'=>array(floatval($data['make']))));

        }

        private function getStoreCode()
        {
            return $this->store_manager->getStore()->getCode();
        }

        public function getProductCollection($categoryId)
        {
            $category = $this->_categoryFactory->create()->load($categoryId);
            $collection = $this->productCollection->create();
            $collection->addAttributeToSelect('*');
            $collection->addCategoryFilter($category);
            $collection->addAttributeToFilter('visibility', \Magento\Catalog\Model\Product\Visibility::VISIBILITY_BOTH);
            $collection->addAttributeToFilter('status',\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED);
            return $collection;
        }
    }

Does anyone have any idea how can I achieve my above requirement?
Thanks

3 Answers 3

2

Try below code

namespace Vendor\Module\Block\Home;

use Magento\Catalog\Api\CategoryRepositoryInterface;

class Products extends \Magento\Catalog\Block\Product\ListProduct {

    protected $_collection;

    protected $categoryRepository;

    protected $_resource;

    public function __construct(
    \Magento\Catalog\Block\Product\Context $context, 
            \Magento\Framework\Data\Helper\PostHelper $postDataHelper, 
            \Magento\Catalog\Model\Layer\Resolver $layerResolver, 
            CategoryRepositoryInterface $categoryRepository,
            \Magento\Framework\Url\Helper\Data $urlHelper, 
            \Magento\Catalog\Model\ResourceModel\Product\Collection $collection, 
            \Magento\Framework\App\ResourceConnection $resource,
            array $data = []
    ) {
        $this->categoryRepository = $categoryRepository;
        $this->_collection = $collection;
        $this->_resource = $resource;

        parent::__construct($context, $postDataHelper, $layerResolver, $categoryRepository, $urlHelper, $data);
    }

    public function getProducts() {
        $count = $this->getProductCount();                       
        $category_id = $this->getData("category_id");
        $collection = clone $this->_collection;
        $collection->clear()->getSelect()->reset(\Magento\Framework\DB\Select::WHERE)->reset(\Magento\Framework\DB\Select::ORDER)->reset(\Magento\Framework\DB\Select::LIMIT_COUNT)->reset(\Magento\Framework\DB\Select::LIMIT_OFFSET)->reset(\Magento\Framework\DB\Select::GROUP);

        if(!$category_id) {
            $category_id = $this->_storeManager->getStore()->getRootCategoryId();
        }
        $category = $this->categoryRepository->get($category_id);
        if(isset($category) && $category) {
            $collection->addMinimalPrice()
                ->addFinalPrice()
                ->addTaxPercents()
                ->addAttributeToSelect('name')
                ->addAttributeToSelect('image')
                ->addAttributeToSelect('small_image')
                ->addAttributeToSelect('thumbnail')
                ->addAttributeToSelect($this->_catalogConfig->getProductAttributes())
                ->addUrlRewrite()
                ->addCategoryFilter($category)
                ->addAttributeToSort('created_at','desc');
        } else {
            $collection->addMinimalPrice()
                ->addFinalPrice()
                ->addTaxPercents()
                ->addAttributeToSelect('name')
                ->addAttributeToSelect('image')
                ->addAttributeToSelect('small_image')
                ->addAttributeToSelect('thumbnail')
                ->addAttributeToSelect($this->_catalogConfig->getProductAttributes())
                ->addUrlRewrite()
                ->addAttributeToFilter('is_saleable', 1, 'left')
                ->addAttributeToSort('created_at','desc');
        }

        $collection->getSelect()
                ->order('created_at','desc')
                ->limit($count);

        return $collection;
    }

    public function getLoadedProductCollection() {
        return $this->getProducts();
    }

    public function getProductCount() {
        $limit = $this->getData("product_count");
        if(!$limit)
            $limit = 10;
        return $limit;
    }
}

Then you can use in the template this:

<?php foreach ($block->getLoadedProductCollection() as $product) : ?>
    <!-- do something with $product -->
<?php endforeach;?>
11
  • it gives the diffrent result, results not 100% as list.phtml collectoin Commented Mar 27, 2019 at 9:04
  • @NavinBhudiya i have updated my answer pleasea check it Commented Mar 27, 2019 at 9:05
  • i already try same code but result not match 100% Commented Mar 27, 2019 at 9:29
  • you have missing something because it is working code for me in past Commented Mar 27, 2019 at 9:30
  • ur code return collection that has disabled product also and many more, I had applied filters still no luck Commented Mar 27, 2019 at 9:30
2

Try to use this below code in your block file :

<?php
/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */
namespace VendorName\ModuleName\Block;

class Data extends \Magento\Framework\View\Element\Template
{

    /**
     * @var \Magento\Catalog\Model\CategoryFactory
     */
    protected $categoryFactory;

    /**
     * @var \Magento\Framework\Registry
     */
    protected $registry;


    public function __construct(
        \Magento\Framework\View\Element\Template\Context $context,
        \Magento\Catalog\Model\CategoryFactory $categoryFactory
        \Magento\Framework\Registry $registry,
        array $data = []
    ) {
        $this->_categoryFactory = $categoryFactory;
        $this->registry = $registry;
        parent::__construct($context, $data);
    }

    public function getProductNameList($catUrlKey) {

        $categoryId = $this->registry->registry('current_category')->getId();
        $product = $this->categoryFactory->create()->load($categoryId)->getProductCollection()->addAttributeToSelect('*');
        $product->addAttributeToFilter('visibility', \Magento\Catalog\Model\Product\Visibility::VISIBILITY_IN_CATALOG);
        $product->addAttributeToFilter('status', \Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED);
        return $product;
    }
}
?>
4
  • it gives the diffrent result, results not 100% as list.phtml collectoin Commented Mar 27, 2019 at 9:04
  • i just update question with my code ... main issue is result are not same as list.phtml Commented Mar 27, 2019 at 9:39
  • replace this code in your question code : $collection->addCategoryFilter(['eq' => $categoryID]); Commented Mar 27, 2019 at 9:59
  • not worked....... Commented Mar 27, 2019 at 13:32
1

You can use a block like this. Loads the current catalog layer ( asuming you are in a category list page ) and from there you can get the loaded collection

namespace Vendor\Module\Block;
use Magento\Catalog\Model\Layer\Resolver;
use Magento\Framework\View\Element\Template;
class Category extends \Magento\Framework\View\Element\Template
{
   private $registry;
   private $catalogLayer;

   public function __construct(
    Template\Context $context,
    \Magento\Framework\Registry $registry,
    Resolver $layerResolver,
    array $data = array()
)
{
    $this->registry = $registry;
    $this->catalogLayer = $layerResolver->get(); // This is where we get the catalog layer with the loaded data

    parent::__construct($context, $data);
}

public function getAllVisibleProducts() {
    $productsCollection = $this->catalogLayer->getProductCollection(); // This is where we load the category collection

    $productData = [];

    foreach ($productsCollection as $item) {
        $productData[] = [
          'id' => $item->getId(),
          'name' => $item->getName(),
          'price' => $item->getFinalPrice(),
        ];
    }

    return $productData;
}
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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