Advertisement

Facebook

How to Get Products from Smile ElasticSuite Virtual Categories Programmatically in Magento 2

How to Get Products from Smile ElasticSuite Virtual Categories Programmatically in Magento 2

In Magento 2, Smile ElasticSuite is a powerful tool that enhances your store's search and product filtering. One of its best features is virtual categories, which automatically group products based on specific rules, saving you time and making your store smarter.

In this post, we'll show you how to programmatically get all products from a Smile ElasticSuite virtual category. Whether you're a developer or store owner working on custom category logic, this guide will help you achieve your goals with easy-to-follow steps.

What is a Virtual Category in Smile ElasticSuite?

A virtual category in Smile ElasticSuite isn’t a traditional category where products are manually assigned. Instead, it automatically displays products based on query rules like product attributes, price ranges, or custom conditions.

This dynamic approach is great for creating special collections, such as:

  • "Top 10 Best Sellers"
  • "New Arrivals Under $50"
  • "Eco-Friendly Products"

Create a Block to Fetch Products

Here’s a simple and complete code example of a Block to retrieve products from a virtual category.

<?php

namespace VendorName\ModuleName\Block;

use Smile\ElasticsuiteCatalog\Model\ResourceModel\Product\Fulltext\Collection as ProductCollection;
use Smile\ElasticsuiteCatalog\Model\Category\Filter\Provider as FilterProvider;
use Magento\Catalog\Api\CategoryRepositoryInterface;
use Magento\Store\Model\StoreManagerInterface;
use Magento\Framework\Exception\NoSuchEntityException;
use Psr\Log\LoggerInterface;
use Magento\Framework\View\Element\Template;

class Social extends Template
{
    /**
     * @var ProductCollection
     */
    protected $productCollection;

    /**
     * @var FilterProvider
     */
    protected $filterProvider;

    /**
     * @var CategoryRepositoryInterface
     */
    protected $categoryRepository;

    /**
     * @var StoreManagerInterface
     */
    protected $storeManager;

    /**
     * @var LoggerInterface
     */
    protected $logger;

    /**
     * @param ProductCollection $productCollection
     * @param FilterProvider $filterProvider
     * @param CategoryRepositoryInterface $categoryRepository
     * @param StoreManagerInterface $storeManager
     * @param LoggerInterface $logger
     * @param array $data
     */
    public function __construct(
        Template\Context $context,
        ProductCollection $productCollection,
        FilterProvider $filterProvider,
        CategoryRepositoryInterface $categoryRepository,
        StoreManagerInterface $storeManager,
        LoggerInterface $logger,
        array $data = []
    ) {
        $this->productCollection = $productCollection;
        $this->filterProvider = $filterProvider;
        $this->categoryRepository = $categoryRepository;
        $this->storeManager = $storeManager;
        $this->logger = $logger;
        parent::__construct($context, $data);
    }

    /**
     * Retrieve products from a virtual category based on category ID
     *
     * @param string $categoryId The category ID
     * @return ProductCollection|false
     */
    public function getVirtualCategoryData($categoryId)
    {
        // Validate category ID
        $categoryId = trim($categoryId);
        if (empty($categoryId)) {
            return false;
        }

        // Fetch category data
        $categoryData = $this->getCategoryData($categoryId);
        if (!$categoryData || !$categoryData->getIsVirtualCategory()) {
            return false;
        }

        // Apply query filter and sorting for virtual category
        $queryFilter = $this->filterProvider->getQueryFilter($categoryData);
        $this->productCollection->addQueryFilter($queryFilter)
                                ->setOrder('category.position', 'ASC');

        return $this->productCollection->getItems();
    }

    /**
     * Retrieve category data by category ID
     *
     * @param string $categoryId The category ID
     * @return Category|null
     */
    public function getCategoryData($categoryId)
    {
        try {
            return $this->categoryRepository->get($categoryId, $this->getStoreId());
        } catch (NoSuchEntityException $e) {
            $this->logger->error($e->getMessage());
        } catch (\Exception $e) {
            $this->logger->error($e->getMessage());
        }

        return null;
    }

    /**
     * Retrieve the current store ID
     *
     * @return int
     */
    public function getStoreId()
    {
        return $this->storeManager->getStore()->getId();
    }
}

How the Code Works

1. Dependencies Injection

The constructor initializes key Magento components like:

  • ProductCollection: Fetches product data.
  • FilterProvider: Filters products for virtual categories.
  • CategoryRepositoryInterface: Retrieves category details.
  • StoreManagerInterface: Gets the current store.
  • LoggerInterface: Logs errors.

2. Fetching Products

The getVirtualCategoryData() method accepts a category ID, validates it, and checks if the category is virtual:

if (!$categoryData || !$categoryData->getIsVirtualCategory()) {
    return false;
}

If the category is virtual, it applies the query filter to fetch products.

3. Category and Store Handling

getCategoryData(): Fetches category details based on the ID.

getStoreId(): Gets the current store ID.

Displaying the Products in a Template

To use this Block in a template and display the products, bind the Block in your module's layout file:

<block class="VendorName\ModuleName\Block\Social" name="virtual_category_products" template="VendorName_ModuleName::products.phtml" />

Template Example (products.phtml)

<?php
$categoryId = 'YOUR_VIRTUAL_CATEGORY_ID'; // Replace with your category ID
$productCollection = $block->getVirtualCategoryData($categoryId);

if ($productCollection) {
    foreach ($productCollection as $product) {
        echo $product->getName() . '<br>';
    }
} else {
    echo 'No products found.';
}
?>

SEO Benefits of Virtual Categories

Using virtual categories lets you dynamically create SEO-friendly pages for different product collections, increasing your site's relevance for search engines.

For example, a virtual category for "Best Deals in Electronics" can target specific keywords without manually assigning products.

Conclusion

By following this guide, you now know how to fetch products programmatically from Smile ElasticSuite virtual categories in Magento 2. This approach saves time, improves efficiency, and allows you to create powerful, rule-based product collections.

Do you need more help with Magento or Smile ElasticSuite? Let us know in the comments!

Post a Comment

0 Comments

Buy Me A Coffee