0

Everything is in the question i need to load a custom product collection in frontend using smile elasticsuite. But i can't figure out how to do it. Do you guys have a working example ?

"smile/elasticsuite": "~2.10.13"

EDIT (Removed all previous code and error from the issue) : Please find latest evolution and description of the issue to the smile elastic suite discussion there : https://github.com/Smile-SA/elasticsuite/discussions/3018#discussioncomment-6616473

6
  • Hey mate, regarding "why it's using the magento class instead of smile", it's because Smile module extends and override magento classes :)
    – Tu Van
    Commented Jul 26, 2023 at 8:55
  • the smile class defined this method so if it was really taking into consideration the smile extend i should have it. Though smile is working perfectly fine on my website, it's only for custom collection that i'm struggling.
    – Claims
    Commented Jul 26, 2023 at 9:20
  • Seems like you maybe generating the collection in your block. Can you post your Sa\CustomCollection\Block\Product\ListProduct class. Commented Aug 1, 2023 at 10:09
  • @Claims There are some more files (block classes and model) maybe related to this issue. Would you mind sharing the module to help me reproduce the issue quickly? If so, please upload a zip file somewhere and paste the link here.
    – Tu Van
    Commented Aug 1, 2023 at 12:06
  • @Claims what is code in file app/code/Sa/CustomCollection/Model/Layer.php Commented Aug 1, 2023 at 12:38

1 Answer 1

0

To load a custom product collection in the frontend using Smile ElasticSuite, you need to adjust how you develop your custom modules to work with ElasticSuite. This error occurs because the Smile ElasticSuite modifies the standard product collection to use Elasticsearch.

The method addSortFilterParameters() is not in the Magento Catalog\Model\ResourceModel\Product\Collection, but is instead in the Smile ElasticSuite ElasticsuiteCatalog\Model\ResourceModel\Product\Fulltext\Collection. When ElasticSuite is enabled, the latter should be used everywhere instead of the former.

In your custom module, don't create the product collection directly. Instead, you should use the Magento\Catalog\Model\Layer model to get the product collection to make sure it will return the product collection with ElasticSuite modification.

To do this in your block, you need to override the _getProductCollection method from Magento\Catalog\Block\Product\ListProduct:

class ListProduct extends \Magento\Catalog\Block\Product\ListProduct
{
    protected function _getProductCollection()
    {
        /** @var \Magento\Catalog\Model\Layer $layer */
        $layer = $this->getLayer();

        if ($this->_productCollection === null) {
            $this->_productCollection = $layer->getProductCollection();
        }

        $this->_eventManager->dispatch(
            'catalog_block_product_list_collection',
            ['collection' => $this->_productCollection]
        );

        return $this->_productCollection;
    }
}

Then in your layout XML file, reference the "product_list" block, and replace the class to your custom class.

This should load the product collection with ElasticSuite modification. If you want to add more filters or sorts to the collection, use the AddFieldToFilter() method on the product collection returned by $layer->getProductCollection() instead of creating your own collection.

Edited to provide additional info:

From the error you shared, the method addSortFilterParameters() is not defined in the class Magento\Catalog\Model\ResourceModel\Product\Collection\Interceptor. If the method is defined in Smile's Full Text collection, I recommend using Dependency Injection to inject an instance of Smile's collection into your Model's constructor.

Here's an example of how you can do this:

namespace Sa\CustomCollection\Model;

class CustomModel {
   
    protected $_smileCollection;
    
    public function __construct(
        \Smile\ElasticsuiteCatalog\Model\ResourceModel\Product\Fulltext\Collection $smileCollection,
    ) {
        $this->_smileCollection = $smileCollection;
    }

    public function getSmileCollection() {
        $this->_smileCollection->addSortFilterParameters();
    } 

}

Now, you can call the method getSmileCollection() in your controller to get Smile's FullText collection.

Regarding your filters not adjusting to the pre-filtered collection on the first load of the page, the page load is not aware of the pre-filters applied on the collection. It seems that Smile was designed to work by applying filters via the URL, thus it's always expecting filter parameters in the URL.

3
  • Please find updated of the issue in the smile discussion link i've been providing. Thanks
    – Claims
    Commented Aug 2, 2023 at 14:01
  • @Claims Please update your question with the required info and remove the url,. I have updated my answer
    – Rapidmod
    Commented Aug 2, 2023 at 22:52
  • I have no more error in the updated code i shared (which is why i deleted the error from the question) , it's just the behavior of the filter who isn't good when you load the page without any filtering parameter. Even if you load the collection filtered properly...the filters on the left will still considered that all products are printed, so for example you will have 1000 match for an attribute when you really should have 24 according to what you really print. I will update directly paste the question info without the link
    – Claims
    Commented Aug 3, 2023 at 8:03

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.