Magento 2 – How to Get Current Category Product Collection

magento-2.1magento2magento2.2.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

Best Answer

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