0

I'm trying to add a custom method Magento\LayeredNavigation\Block\Navigation. To my knowledge preference is the only way to do that.

My di.xml

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
 <preference for="Magento\LayeredNavigation\Block\Navigation" type="Vendor\ModuleName\Block\Navigation" />
</config>

My Navigation.php

<?php

 namespace Vendor\ModuleName\Block;

 class Navigation extends \Magento\LayeredNavigation\Block\Navigation
 {
  public function customMethod() {
   ...code
  }
 }

I run magento setup:upgrade and compile but when i try to call the function i get nothing back. Putting the same function in core works fine, so nothing wrong with the function itself.

<?php var_dump($block->customMethod()); ?> 

Returns NULL

I've seen a bunch of questions from people having problems regarding this but not any satisfying solutions.

  • try to run di:compile – Keyur Shah Aug 31 '17 at 7:14
1

I hope you are trying to override Magento Layered navigation block. Your di.xml should be like below:

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
 <preference for="Magento\LayeredNavigation\Block\Navigation" type="Macforum\MultipleLayeredNavigation\Block\Navigation" />
</config>
  • Yeah sorry...that was just a typo when i wrote the question...edited the question. Sorry... – GuWa Sep 1 '17 at 6:34
1

As you want to overide the class Magento\LayeredNavigation\Block\Navigation

So your preference class should be

for="Magento\LayeredNavigation\Block\Navigation"

instead of

for="Vendor\ModuleName\Block\Navigation"

Please do the recommend changes at di.xml.

And Macforum\MultipleLayeredNavigation\Block\Navigation code should be:


<?php

namespace Macforum\MultipleLayeredNavigation\Block;

use Magento\Catalog\Model\Category;
use Magento\Customer\Model\Context;

/**
 * Catalog navigation
 *
 * @SuppressWarnings(PHPMD.LongVariable)
 * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
 */
class Navigation extends \Magento\Framework\View\Element\Template implements \Magento\Framework\DataObject\IdentityInterface
{
    /**
     * @var Category
     */
    protected $_categoryInstance;

    /**
     * Current category key
     *
     * @var string
     */
    protected $_currentCategoryKey;

    /**
     * Array of level position counters
     *
     * @var array
     */
    protected $_itemLevelPositions = [];

    /**
     * Catalog category
     *
     * @var \Magento\Catalog\Helper\Category
     */
    protected $_catalogCategory;

    /**
     * @var \Magento\Framework\Registry
     */
    protected $_registry;

    /**
     * Customer session
     *
     * @var \Magento\Framework\App\Http\Context
     */
    protected $httpContext;

    /**
     * Catalog layer
     *
     * @var \Magento\Catalog\Model\Layer
     */
    protected $_catalogLayer;

    /**
     * Product collection factory
     *
     * @var \Magento\Catalog\Model\ResourceModel\Product\CollectionFactory
     */
    protected $_productCollectionFactory;

    /**
     * @var \Magento\Catalog\Model\Indexer\Category\Flat\State
     */
    protected $flatState;

    /**
     * @param \Magento\Framework\View\Element\Template\Context $context
     * @param \Magento\Catalog\Model\CategoryFactory $categoryFactory
     * @param \Magento\Catalog\Model\ResourceModel\Product\CollectionFactory $productCollectionFactory
     * @param \Magento\Catalog\Model\Layer\Resolver $layerResolver
     * @param \Magento\Framework\App\Http\Context $httpContext
     * @param \Magento\Catalog\Helper\Category $catalogCategory
     * @param \Magento\Framework\Registry $registry
     * @param \Magento\Catalog\Model\Indexer\Category\Flat\State $flatState
     * @param array $data
     */
    public function __construct(
        \Magento\Framework\View\Element\Template\Context $context,
        \Magento\Catalog\Model\CategoryFactory $categoryFactory,
        \Magento\Catalog\Model\ResourceModel\Product\CollectionFactory $productCollectionFactory,
        \Magento\Catalog\Model\Layer\Resolver $layerResolver,
        \Magento\Framework\App\Http\Context $httpContext,
        \Magento\Catalog\Helper\Category $catalogCategory,
        \Magento\Framework\Registry $registry,
        \Magento\Catalog\Model\Indexer\Category\Flat\State $flatState,
        array $data = []
    ) {
        $this->_productCollectionFactory = $productCollectionFactory;
        $this->_catalogLayer = $layerResolver->get();
        $this->httpContext = $httpContext;
        $this->_catalogCategory = $catalogCategory;
        $this->_registry = $registry;
        $this->flatState = $flatState;
        $this->_categoryInstance = $categoryFactory->create();
        parent::__construct($context, $data);
    }

    /**
     * @return void
     */
    protected function _construct()
    {
        $this->addData(
            [
                'cache_lifetime' => false,
                'cache_tags' => [Category::CACHE_TAG, \Magento\Store\Model\Group::CACHE_TAG],
            ]
        );
    }

    /**
     * Get current category
     *
     * @return Category
     */
    public function getCategory()
    {
        return $this->_registry->registry('current_category');
    }

    /**
     * Get Key pieces for caching block content
     *
     * @return array
     */
    public function getCacheKeyInfo()
    {
        $shortCacheId = [
            'CATALOG_NAVIGATION',
            $this->_storeManager->getStore()->getId(),
            $this->_design->getDesignTheme()->getId(),
            $this->httpContext->getValue(Context::CONTEXT_GROUP),
            'template' => $this->getTemplate(),
            'name' => $this->getNameInLayout(),
            $this->getCurrentCategoryKey(),
        ];
        $cacheId = $shortCacheId;

        $shortCacheId = array_values($shortCacheId);
        $shortCacheId = implode('|', $shortCacheId);
        $shortCacheId = md5($shortCacheId);

        $cacheId['category_path'] = $this->getCurrentCategoryKey();
        $cacheId['short_cache_id'] = $shortCacheId;

        return $cacheId;
    }

    /**
     * Get current category key
     *
     * @return string
     */
    public function getCurrentCategoryKey()
    {
        if (!$this->_currentCategoryKey) {
            $category = $this->_registry->registry('current_category');
            if ($category) {
                $this->_currentCategoryKey = $category->getPath();
            } else {
                $this->_currentCategoryKey = $this->_storeManager->getStore()->getRootCategoryId();
            }
        }

        return $this->_currentCategoryKey;
    }

    /**
     * Retrieve child categories of current category
     *
     * @return \Magento\Framework\Data\Tree\Node\Collection
     */
    public function getCurrentChildCategories()
    {
        $categories = $this->_catalogLayer->getCurrentCategory()->getChildrenCategories();
        /** @var \Magento\Catalog\Model\ResourceModel\Product\Collection $productCollection */
        $productCollection = $this->_productCollectionFactory->create();
        $this->_catalogLayer->prepareProductCollection($productCollection);
        $productCollection->addCountToCategories($categories);
        return $categories;
    }

    /**
     * Checkin activity of category
     *
     * @param   \Magento\Framework\DataObject $category
     * @return  bool
     */
    public function isCategoryActive($category)
    {
        if ($this->getCurrentCategory()) {
            return in_array($category->getId(), $this->getCurrentCategory()->getPathIds());
        }
        return false;
    }

    /**
     * Get url for category data
     *
     * @param Category $category
     * @return string
     */
    public function getCategoryUrl($category)
    {
        if ($category instanceof Category) {
            $url = $category->getUrl();
        } else {
            $url = $this->_categoryInstance->setData($category->getData())->getUrl();
        }

        return $url;
    }

    /**
     * Enter description here...
     *
     * @return Category
     */
    public function getCurrentCategory()
    {
        return $this->_catalogLayer->getCurrentCategory();
    }

    /**
     * Return identifiers for produced content
     *
     * @return array
     */
    public function getIdentities()
    {
        return [\Magento\Catalog\Model\Category::CACHE_TAG, \Magento\Store\Model\Group::CACHE_TAG];
    } 
    public function customMethod() {
    //...code
  }

}
0

Try to pass this inside __construct() like

protected $_navigation

public function __construct(
...
\Macforum\MultipleLayeredNavigation\Block\Navigation $navigation
...
){
$this->_navigation = $navigation;
}

Then in your class use

$this->_navigation->customMethod();

Also you better put your custom functionality inside "Helper" directory or "Resolver", not inside a "Block".

0

Ok, so I finally got this to work and this is how I did it.

Apparently Magento\LayeredNavigation\Block\Navigation\ is never used by itself but is used by two virtual types in Magento/LayeredNavigation/etc/frontend/di.xml.

  • Magento\LayeredNavigation\Block\Navigation\Category
  • Magento\LayeredNavigation\Block\Navigation\Search

So in my case I actually had to create my own virtual type based on my class that extends Magento\LayeredNavigation\Block\Navigation and use that virtual type as preference for the virtual type created in core.

di.xml

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
...
<virtualType name="Vendor\ModuleName\Block\Navigation\Category" type="Vendor\ModuleName\Block\Navigation">
    <arguments>
         <argument name="filterList" xsi:type="object">categoryFilterList</argument>
    </arguments>
</virtualType>
<preference for="Magento\LayeredNavigation\Block\Navigation\Category" type="Vendor\ModuleName\Block\Navigation\Category" />
...
</config>

Navigation.php

<?php

namespace Vendor\ModuleName\Block;

class Navigation extends \Magento\LayeredNavigation\Block\Navigation
{

 public function customMethod()
 {
   ...
 }
}

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.