Question

I recently updated my Magento version from 2.1.1 to 2.1.10 and the module mentioned in the title is causing that exception. module version is 2.0.6

I contacted their support, and was told it is a known issue, and they're planning to solve it in the next release. The problem is that no one knows when the next release is planned and I need to put the application live in some days, so I need to solve the issue.

Actually they sent me a sort of patch, in order to substitue the di.xml in app/code/IWD/StoreLocator/etc/frontend/di.xml, that is just a commented version of the original one, and changed the url to store locator page to 'storelocator'.

patched 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">
    <!--<type name="Magento\Framework\App\RouterList">-->
        <!--<arguments>-->
            <!--<argument name="routerList" xsi:type="array">-->
                <!--<item name="storelocatorroute" xsi:type="array">-->
                    <!--<item name="class" xsi:type="string">IWD\StoreLocator\Controller\Router</item>-->
                    <!--<item name="disable" xsi:type="boolean">false</item>-->
                    <!--<item name="sortOrder" xsi:type="string">22</item>-->
                <!--</item>-->
            <!--</argument>-->
        <!--</arguments>-->
    <!--</type>-->
</config>

Exception is disappeared, but the map contains no markers at all, hence stores are not displayed.

Does anyone has a clue on the issue?

EDIT - The router causing the problem

public function match(\Magento\Framework\App\RequestInterface $request)
{
    $status = $this->_scopeConfig->getValue('iwd_storelocator/general/is_active', \Magento\Store\Model\ScopeInterface::SCOPE_STORE);
    if(!$status){
        return;
    }

    $locatorRoute = $this->_scopeConfig->getValue('iwd_storelocator/general/path', \Magento\Store\Model\ScopeInterface::SCOPE_STORE); 

    $path = strtolower($locatorRoute);
    $path = trim($locatorRoute);

    $identifier = trim($request->getPathInfo(), '/');
    $action = $request->getActionName();

    if($identifier == $locatorRoute) {

        $request->setModuleName('storelocator')
                        ->setControllerName('index')
                        ->setActionName($action);
    } else {
        //There is no match
        return;
    }

    /*
     * We have match and now we will forward action
     */
    return $this->actionFactory->create(
        'Magento\Framework\App\Action\Forward',
        ['request' => $request]
    );
}

EDIT 2 To avoid redirection I've added a dummy counter to the controller, to avoid too many redirections, like this

if($identifier == $locatorRoute && $this->count < 2) {          
   $request->setModuleName('storelocator')
       ->setControllerName('index')
       ->setActionName($action);
    } else {
        return;
    }

but I get the same result as commenting the di.xml, so no marker is shown on the map.

Was it helpful?

Solution

The extension support has very kindly sent me a patch to be applied that solves the problem and told me I could post the code here. Maybe it could be of help for someone else.

Just substitute the app/code/IWD/StoreLocator/Block/Search.php with this one:

<?php
namespace IWD\StoreLocator\Block;

use Magento\Framework\View\Element\Template;
use IWD\StoreLocator\Model\ResourceModel\Item\CollectionFactory as ItemCollectionFactory;

/**
 * Class Search
 * @package IWD\StoreLocator\Block
 */
class Search extends Template
{
    /**
     * @var \Magento\Store\Model\StoreManagerInterface
     */
    private $scopeConfig;

    /**
     * @var \Magento\Directory\Model\CountryFactory
     */
    private $countryFactory;

    /**
     * @var \Magento\Directory\Model\RegionFactory
     */
    private $regionFactory;

    /**
     * @var ItemCollectionFactory
     */
    private $ItemCollectionFactory;

    /**
     * @var \IWD\StoreLocator\Model\Image
     */
    private $imageHelper;

    /**
     * @var \Magento\Store\Model\StoreManagerInterface
     */
    private $storeManager;

    /**
     * Search constructor.
     * @param Template\Context $context
     * @param \Magento\Directory\Model\CountryFactory $countryFactory
     * @param \Magento\Directory\Model\RegionFactory $regionFactory
     * @param ItemCollectionFactory $ItemCollectionFactory
     * @param \IWD\StoreLocator\Model\Image $imageHelper
     */
    public function __construct(
        Template\Context $context,
        \Magento\Directory\Model\CountryFactory $countryFactory,
        \Magento\Directory\Model\RegionFactory $regionFactory,
        ItemCollectionFactory $ItemCollectionFactory,
        \IWD\StoreLocator\Model\Image $imageHelper
    ) {
        $this->countryFactory = $countryFactory;
        $this->regionFactory = $regionFactory;
        $this->ItemCollectionFactory = $ItemCollectionFactory;
        $this->storeManager =  $context->getStoreManager();
        $this->imageHelper = $imageHelper;
        $this->scopeConfig = $context->getScopeConfig();
        parent::__construct($context);
    }

    /**
     * @return $this
     */
    protected function _prepareLayout()
    {
        $metaTitle = $this->scopeConfig->getValue('iwd_storelocator/general/meta_title', \Magento\Store\Model\ScopeInterface::SCOPE_STORE);
        $metaKeywords = $this->scopeConfig->getValue('iwd_storelocator/general/meta_keyword', \Magento\Store\Model\ScopeInterface::SCOPE_STORE);
        $metaDescription = $this->scopeConfig->getValue('iwd_storelocator/general/meta_description', \Magento\Store\Model\ScopeInterface::SCOPE_STORE);

        $this->pageConfig->getTitle()->set($metaTitle);
        $this->pageConfig->setKeywords($metaKeywords);
        $this->pageConfig->setDescription($metaDescription);

        $pageMainTitle = $this->getLayout()->getBlock('page.main.title');
        if ($pageMainTitle) {
            // Setting empty page title if content heading is absent
            $pageMainTitle->setPageTitle($this->escapeHtml($metaTitle));
        }
        return parent::_prepareLayout();
    }

    public function getGMBrowserApiKey()
    {
        return $this->scopeConfig->getValue('iwd_storelocator/gm/browser_api_key', \Magento\Store\Model\ScopeInterface::SCOPE_STORE);
    }

    public function getSearchOnLoad()
    {
        return (int)$this->scopeConfig->getValue('iwd_storelocator/search/search_onload', \Magento\Store\Model\ScopeInterface::SCOPE_STORE);
    }

    public function getConfigOption($path, $bool = false)
    {
        if (!$bool) {
            return $this->scopeConfig->getValue($path, \Magento\Store\Model\ScopeInterface::SCOPE_STORE);
        }

        return (bool)$this->scopeConfig->getValue($path, \Magento\Store\Model\ScopeInterface::SCOPE_STORE);
    }

    public function init()
    {
        $metric = $this->scopeConfig->getValue('iwd_storelocator/search/metric', \Magento\Store\Model\ScopeInterface::SCOPE_STORE);
        if ($metric == 1) {
            $metric  = __('Km');
        } elseif ($metric == 2) {
            $metric  = __('Miles');
        }

        $fillColor = $this->getConfigOption("iwd_storelocator/design/fill_color");
        if (!preg_match('/#/i', $fillColor)) {
            $fillColor= '#' . $fillColor;
        }

        $strokeColor = $this->getConfigOption("iwd_storelocator/design/stroke_color");
        if (!preg_match('/#/i', $strokeColor)) {
            $strokeColor= '#' . $strokeColor;
        }

        $folderName = \IWD\StoreLocator\Model\Config\Backend\Image\Marker::UPLOAD_DIR;

        $placeholder = $this->getConfigOption('iwd_storelocator/design/placeholder');
        if (!empty($placeholder)) {
            $path = $folderName . '/' . $placeholder;
            $placeholder = $this->_urlBuilder->getBaseUrl(['_type' => \Magento\Framework\UrlInterface::URL_TYPE_MEDIA]) . $path;
        } else {
            $placeholder = $this->getViewFileUrl('IWD_StoreLocator::images/placeholder.png');
        }

        $marker = $this->getConfigOption('iwd_storelocator/gm/marker');

        if (!empty($marker)) {
            $path = $folderName . '/' . $marker;
            $marker = $this->_urlBuilder->getBaseUrl(['_type' => \Magento\Framework\UrlInterface::URL_TYPE_MEDIA]) . $path;
        } else {
            $marker = $this->getViewFileUrl('IWD_StoreLocator::images/marker.png');
        }

        $data = [
            'StoreLocator'=>[
                'url' => $this->_urlBuilder->getBaseUrl().'rest/V1/storelocator/search',
                'searchOnload' => $this->getSearchOnLoad(),
                'markerUrl' => $this->getViewFileUrl('IWD_StoreLocator::images/marker.png'),
                'closeUrl' => $this->getViewFileUrl('IWD_StoreLocator::images/close.png'),
                'pagination' => (int)$this->getConfigOption('iwd_storelocator/search/pagination'),
                'dropdown' => $this->_prepareCountrytRegion(),
                'baseUrlImage' => $this->imageHelper->getBaseUrl(),
                'radiusDecorator' =>  [
                    'active' => (int)$this->getConfigOption("iwd_storelocator/design/hightlight_result"),
                    'fillColor' => $fillColor,
                    'fillOpacity' => $this->getConfigOption("iwd_storelocator/design/opacity"),
                    'strokeColor' => $strokeColor,
                    'strokeOpacity' => $this->getConfigOption("iwd_storelocator/design/stroke_opacity"),
                    'strokeWeight'=> $this->getConfigOption("iwd_storelocator/design/stroke_weight"),
                ],

                'metric' =>  $metric,
                'placeholder_visability' => !$this->getConfigOption("iwd_storelocator/design/hide_placeholders", true),
                'empty_message' =>$this->getConfigOption('iwd_storelocator/search/message'),
                'placeholder' => $placeholder,
                'marker' => $marker,
                'pageSize' => $this->getConfigOption('iwd_storelocator/search/page_size'),
            ]
        ];

        return json_encode($data);
    }

    private function _prepareCountrytRegion()
    {
        $list = $this->_getListCountries();
        foreach ($list as $code => &$country) {
            $country = ['regions'=>$this->_getRegions($code)];
        }

        return $list;
    }

    private function _getRegions($country)
    {
        $storeId = $this->storeManager->getStore()->getId();

        $collection = $this->ItemCollectionFactory->create();
        $collection->addFieldToFilter('is_active', ['eq' => 1]);
        $collection->addFieldToFilter('country_id', ['eq' => $country]);

        $collection->addStoreFilter($storeId, true);

        $regions = [];
        foreach ($collection as $blockModel) {
            $regions[] = $blockModel->getRegionId();
        }
        $regions = array_unique($regions);
        sort($regions);

        $result = [];
        foreach ($regions as $region) {
            $regionModel = $this->regionFactory->create()->load($region);
            if ($regionModel->getId()) {
                $result[$regionModel->getName()] = $region;
            }
        }

        return $result;
    }

    private function _getListCountries()
    {
        $storeId = $this->storeManager->getStore()->getId();

        $collection = $this->ItemCollectionFactory->create();
        $collection->addFieldToFilter('is_active', ['eq' => 1]);

        $collection->addStoreFilter($storeId, true);

        $countries = [];
        foreach ($collection as $blockModel) {
            $countries[] = $blockModel->getCountryId();
        }
        $countries = array_unique($countries);

        $data = [];
        foreach ($countries as $code) {
            if (!empty($code)) {
                $data[$code] = $this->countryFactory->create()->loadByCode($code)->getName();
            }
        }
        return $data;
    }

    /**
     * @return bool
     */
    public function getScrollWheel()
    {
        return $this->getConfigOption("iwd_storelocator/gm/scrollwheel_zooming");
    }

    /**
     * @return bool
     */
    public function getScaleControl()
    {
        return $this->getConfigOption("iwd_storelocator/gm/scale_control");
    }

    /**
     * @return bool
     */
    public function getMapTypeControl()
    {
        return $this->getConfigOption("iwd_storelocator/gm/type_control");
    }

    /**
     * @return bool
     */
    public function getCmsBlock()
    {
        return $this->getConfigOption("iwd_storelocator/general/cms");
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with magento.stackexchange
scroll top