ytorbyk / magento2-geo-ip2

Magento 2 extension: Integrates MaxMind GeoIP2 DB into Magento 2.
MIT License
17 stars 7 forks source link

Warning: is_readable() expects parameter 1 to be a valid path #4

Closed eugene-shab closed 6 years ago

eugene-shab commented 6 years ago

I reproduce this issue on 2.1.9 - 2.1.11 Magento version.

Exception:

Exception: Warning: is_readable() expects parameter 1 to be a valid path, object given in vendor/maxmind-db/reader/src/MaxMind/Db/Reader.php on line 47 in vendor/magento/framework/App/ErrorHandler.php:61

After some investigation, I found the following:

$instanceName = 'GeoIp2\Database\Reader'

...

$reader = $this->objectManager->create(
    $this->instanceName,
    ['filename' => $this->database->getDbPath($dbCode, true), 'locales' => $locales]
);

So, after that in reader we have instead of GeoIp2\Database\Reader - Tobai\GeoIp2\Model\Database\GeoIp2\Database\Reader


At first, i change the instanceName variable like:

$instanceName = '\GeoIp2\Database\Reader

It works locally but does not work in production mode.

For production mode i made the following:

<?php
/**
 * Copyright © 2015 ToBai. All rights reserved.
 */

namespace Tobai\GeoIp2\Model\Database;

use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\ObjectManagerInterface;
use Tobai\GeoIp2\Model\Database;
use GeoIp2\Database\Reader as GeoIp2Reader;

/**
 * Database reader factory
 */
class ReaderFactory
{
    /**
     * @var ObjectManagerInterface
     */
    protected $objectManager;

    /**
     * Instance name to create
     *
     * @var string
     */
    protected $instanceName;

    /**
     * @var \Tobai\GeoIp2\Model\Database
     */
    protected $database;

    /**
     * @param \Tobai\GeoIp2\Model\Database $database
     * @param ObjectManagerInterface $objectManager
     * @param string $instanceName
     */
    public function __construct(
        Database $database,
        ObjectManagerInterface $objectManager,
        $instanceName = 'GeoIp2\Database\Reader'
    ) {
        $this->database = $database;
        $this->objectManager = $objectManager;
        $this->instanceName = $instanceName;
    }

    /**
     * @param string $dbCode
     * @param array $locales
     * @return \GeoIp2\Database\Reader
     * @throws LocalizedException
     */
    public function create($dbCode, array $locales = ['en'])
    {
        if (!$this->database->isDbAvailable($dbCode)) {
            throw new LocalizedException(__('GeoIp2 database with "%1" code is not declared.', $dbCode));
        }

        $dbPath = $this->database->getDbPath($dbCode, true);
        $reader = new GeoIp2Reader($dbPath, $locales);

        if (!$reader instanceof \GeoIp2\Database\Reader) {
            throw new \InvalidArgumentException(get_class($reader) . ' must be an instance of \GeoIp2\Database\Reader.');
        }

        return $reader;
    }
}

Please let me know if you found the more elegant solution. And I hope you will make changes and fix the problem.

P.S.: I can create PR if you want.

ytorbyk commented 6 years ago

Hi @eugene-shab the issue is fixed.