0

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.

4
  • 1
    Need to contact the extension. Nov 24, 2017 at 15:50
  • Issue in your IWD\StoreLocator\Controller\Router class
    – Amit Bera
    Nov 24, 2017 at 15:52
  • @KhoaTruongDinh i already contacted the support but that is the only thing they advised me.
    – sissy
    Nov 24, 2017 at 16:11
  • @AmitBera I know that is the controller causing the exception, but I cannot understand why it is generating the loop. I will attach the code of method match of the controller as an edit to my question, maybe someone can understand what the problem is
    – sissy
    Nov 24, 2017 at 16:11

1 Answer 1

1

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");
    }
}

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.