0

I need to change functionality of getHref() method. So I Created several below files in my code folder.

1.<vendor>\Catalog\Block\Widget\Link\Link.php
<?php
namespace Tea\Catalog\Block\Widget;

use Magento\CatalogUrlRewrite\Model\ProductUrlRewriteGenerator;
use Magento\UrlRewrite\Model\UrlFinderInterface;
use Magento\UrlRewrite\Service\V1\Data\UrlRewrite;

class Link extends \Magento\Catalog\Block\Widget\Link
{
    /**
     * Entity model name which must be used to retrieve entity specific data.
     * @var null|\Magento\Catalog\Model\ResourceModel\AbstractResource
     */
    protected $_entityResource = null;

    /**
     * Prepared href attribute
     *
     * @var string
     */
    protected $_href;

    /**
     * Prepared anchor text
     *
     * @var string
     */
    protected $_anchorText;

    /**
     * Url finder for category
     *
     * @var UrlFinderInterface
     */
    protected $urlFinder;

    /**
     * @param \Magento\Framework\View\Element\Template\Context $context
     * @param UrlFinderInterface $urlFinder
     * @param \Magento\Catalog\Model\ResourceModel\AbstractResource $entityResource
     * @param array $data
     */
    public function __construct(
        \Magento\Framework\View\Element\Template\Context $context,
        UrlFinderInterface $urlFinder,
        \Magento\Catalog\Model\ResourceModel\AbstractResource $entityResource = null,
        array $data = []
    ) {
        parent::__construct($context, $data);
        $this->urlFinder = $urlFinder;
        $this->_entityResource = $entityResource;
    }

    /**
     * Prepare url using passed id path and return it
     * or return false if path was not found in url rewrites.
     *
     * @throws \RuntimeException
     * @return string|false
     * @SuppressWarnings(PHPMD.NPathComplexity)
     */
    public function getHref()
    {
        if ($this->_href === null) {
            if (!$this->getData('id_path')) {
                throw new \RuntimeException('Parameter id_path is not set.');
            }
            $rewriteData = $this->parseIdPath($this->getData('id_path'));

            $href = false;
            $store = $this->hasStoreId() ? $this->_storeManager->getStore($this->getStoreId())
                : $this->_storeManager->getStore();
            $filterData = [
                UrlRewrite::ENTITY_ID => $rewriteData[1],
                UrlRewrite::ENTITY_TYPE => $rewriteData[0],
                UrlRewrite::STORE_ID => $store->getId(),
            ];
            if (!empty($rewriteData[2]) && $rewriteData[0] == ProductUrlRewriteGenerator::ENTITY_TYPE) {
                $filterData[UrlRewrite::METADATA]['category_id'] = $rewriteData[2];
            }
            $rewrite = $this->urlFinder->findOneByData($filterData);

            if ($rewrite) {
                $href = $store->getUrl('', ['_direct' => $rewrite->getRequestPath()]);

                if (strpos($href, '___store') === false) {
                    $this->_href = $href;
                }
            }
            $this->_href = $href;
        }
        return $this->_href;
    }

    /**
     * Parse id_path
     *
     * @param string $idPath
     * @throws \RuntimeException
     * @return array
     */
    protected function parseIdPath($idPath)
    {
        $rewriteData = explode('/', $idPath);

        if (!isset($rewriteData[0]) || !isset($rewriteData[1])) {
            throw new \RuntimeException('Wrong id_path structure.');
        }
        return $rewriteData;
    }

    /**
     * Prepare label using passed text as parameter.
     * If anchor text was not specified get entity name from DB.
     *
     * @return string
     */
    public function getLabel()
    {
        if (!$this->_anchorText) {
            if ($this->getData('anchor_text')) {
                $this->_anchorText = $this->getData('anchor_text');
            } elseif ($this->_entityResource) {
                $idPath = explode('/', $this->_getData('id_path'));
                if (isset($idPath[1])) {
                    $id = $idPath[1];
                    if ($id) {
                        $this->_anchorText = $this->_entityResource->getAttributeRawValue(
                            $id,
                            'name',
                            $this->_storeManager->getStore()
                        );
                    }
                }
            }
        }

        return $this->_anchorText;
    }

    /**
     * Render block HTML
     * or return empty string if url can't be prepared
     *
     * @return string
     */
    protected function _toHtml()
    {
        if ($this->getHref()) {
            return parent::_toHtml();
        }
        return '';
    }
}


2.Update di.xml file

<preference for="Magento\Catalog\Block\Widget\Link" type="Tea\Catalog\Block\Widget\Link" />

But still use Magento\Catalog\Block\Widget\Link file. Please help me resolve the problem.

2
  • please share complete files including namespaces as well. Nov 22, 2020 at 7:45
  • @NathaOdedara updated Nov 22, 2020 at 8:01

2 Answers 2

0

Take a look into your vendor/magento/module-catalog/etc/di.xml file. The base class Magento\Catalog\Block\Widget\Link is provided as virtual type depending on the context it is used:

  • Category Magento\Catalog\Block\Category\Widget\Link or
  • Product Magento\Catalog\Block\Product\Widget\Link

So you've to define in your <VENDOR>/<MODULE>/etc/di.xml which virtual type you want to override:

Category:

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <preference for="Magento\Catalog\Block\Category\Widget\Link" type="VENDOR\MODULE\Catalog\Block\Widget\Link" />
</config>

Product:

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <preference for="Magento\Catalog\Block\Product\Widget\Link" type="VENDOR\MODULE\Catalog\Block\Widget\Link" />
</config>
0

The issue seems to be with naming, you need to write both VendorName and ModuleName whereas you've only written VendorName.

For example:

<vendor>\Catalog\Block\Widget\Link\Link.php <--- **Not correct**

<vendor>\<module>\Catalog\Block\Widget\Link\Link.php <--- **Correct**

You'll need to update in both files PHP and di.xml

3
  • My Vendor ->Tea and module -> Catalog Nov 22, 2020 at 9:45
  • Ohh Sorry didn’t noticed that. Anyway is there any error or something? Nov 22, 2020 at 9:47
  • Nothing to display any errors but load in Link.php in Vendor Nov 22, 2020 at 10:15

Your Answer

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

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