1

I am using Magento 2.3

I have override below core file.

vendor/magento/module-catalog/Model/ProductLink/CollectionProvider.php

To override this file I have created a new custom module in app/code directory.

I have created below files in my custom module:

app/code/Custom/ProductModule/registration.php

\Magento\Framework\Component\ComponentRegistrar::register(
\Magento\Framework\Component\ComponentRegistrar::MODULE,
'Custom_ProductModule',
__DIR__
);

app/code/Custom/ProductModule/etc/di.xml

    <?xml version="1.0"?>
    <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
        <preference for="Magento\Catalog\Model\ProductLink\CollectionProvider" type="Custom\ProductModule\Model\ProductLink\CollectionProvider" />
    </config>

app/code/Custom/ProductModule/etc/module.xml

    <?xml version="1.0"?>
        <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
            <module name="Custom_ProductModule" setup_version="1.0.1" />
    </config>

app/code/Custom/ProductModule/Model/ProductLink/CollectionProvider.php

<?php
/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */

namespace Custom\ProductModule\Model\ProductLink;

use Magento\Catalog\Model\ProductLink\Converter\ConverterPool;
use Magento\Framework\Exception\NoSuchEntityException;

class CollectionProvider
{
    /**
     * @var CollectionProviderInterface[]
     */
    protected $providers;

    /**
     * @var ConverterPool
     */
    protected $converterPool;

    /**
     * @param ConverterPool $converterPool
     * @param CollectionProviderInterface[] $providers
     */
    public function __construct(ConverterPool $converterPool, array $providers = [])
    {
        $this->converterPool = $converterPool;
        $this->providers = $providers;
    }

    /**
     * Get product collection by link type
     *
     * @param \Magento\Catalog\Model\Product $product
     * @param string $type
     * @return array
     * @throws NoSuchEntityException
     */
    public function getCollection(\Magento\Catalog\Model\Product $product, $type)
    {
        if (!isset($this->providers[$type])) {
            throw new NoSuchEntityException(__("The collection provider isn't registered."));
        }

        $products = $this->providers[$type]->getLinkedProducts($product);
        $converter = $this->converterPool->getConverter($type);
        $output = [];
        $sorterItems = [];
        foreach ($products as $item) {
            $output[$item->getId()] = $converter->convert($item);
        }

        foreach ($output as $item) {
            $itemPosition = (int)$item['position'];
            while(true) {
                if (!isset($sorterItems[$itemPosition])) {
                    break;
                }
                $itemPosition += 1;
            }
            $sorterItems[$itemPosition] = $item;
        }
        ksort($sorterItems);
        return $sorterItems;
    }
}

After creating this module I have run all commands in SSH but it seems the file is not overridden properly. I am getting below error in the front end:

Error filtering template: Type Error occurred when creating object: Magento\Catalog\Model\Product\Interceptor

Front end:

enter image description here

So What is the issue in my module?

  • 1
    You have to do compilation properly. – Amit Bera Apr 4 at 10:14
  • 1
    As you want to modification on the public function you can use plugin here – Amit Bera Apr 4 at 10:15
  • Are you saying that I have to run php bin/magento setup:di: compile command in SSH? – Chintan Kaneriya Apr 4 at 10:18
  • yes, right. Best way delete all files & folder from gerenrate folder exclude .htaccess and run php bin/magento setup:di: compile – Amit Bera Apr 4 at 10:20
  • Do I have to run only compile or all of the commands(upgrade, deploy, indexing, cache)? – Chintan Kaneriya Apr 5 at 6:12
0

Seems, you have using Amasty Shop by extension. It may because of the cause of this error.

I suggest that instead of using the Class override, use Magento plugin concept for your request.

As you want customization over getCollection() and this is a public function, so you can use the plugin Around method for override the function output.

Create di.xml at app/code/Custom/ProductModule/etc/di.xml and define the plugin here.

<?xml version="1.0" ?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Magento\Catalog\Model\ProductLink\CollectionProvider">
        <plugin disabled="false" name="product_link_collection_provider" sortOrder="1" 
        type="Custom\ProductModule\Plugin\CollectionProviderPlugin"/>
    </type>
</config>

NOw, create CollectionProviderPlugin.php at app/code/Custom/ProductModule/Plugin and write the code for plugin.

Plugin class

<?php

namespace Custom\ProductModule\Plugin;

use Magento\Catalog\Model\ProductLink\Converter\ConverterPool;
use Magento\Framework\Exception\NoSuchEntityException;

class CollectionProviderPlugin {

    /**
     * @var CollectionProviderInterface[]
     */
    protected $providers;

    /**
     * @var ConverterPool
     */
    protected $converterPool;

    /**
     * @param ConverterPool $converterPool
     * @param CollectionProviderInterface[] $providers
     */
    public function __construct(ConverterPool $converterPool, array $providers = [])
    {
        $this->converterPool = $converterPool;
        $this->providers = $providers;
    }    
   public function aroundGetCollection(
           \Magento\Catalog\Model\ProductLink\CollectionProvider $subject,
           \Closure $proceed,
           \Magento\Catalog\Model\Product $product,
           $type)
   {
        if (!isset($this->providers[$type])) {
            throw new NoSuchEntityException(__("The collection provider isn't registered."));
        }

        $products = $this->providers[$type]->getLinkedProducts($product);
        $converter = $this->converterPool->getConverter($type);
        $sorterItems = [];
        $output = [];

        foreach ($products as $item) {
            $output[$item->getId()] = $converter->convert($item);
        }

        foreach ($output as $item) {
            $itemPosition = (int)$item['position'];
            while(true) {
                if (!isset($sorterItems[$itemPosition])) {
                    break;
                }
                $itemPosition += 1;
            }
            $sorterItems[$itemPosition] = $item;
        }
        ksort($sorterItems);
        return $sorterItems;       
   }        
}

After that you have to do compilation properly and Best way delete all files & folder from gerenrate folder exclude .htaccess and run php bin/magento setup:di: compile.

  • I have implemented your solutions and It seems plugin is working fine but it is throwing an exception like "The collection provider isn't registered." in the product in admin. – Chintan Kaneriya Apr 8 at 4:25

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.