geocoder-php / GeocoderLaravel

Geocoder service provider for Laravel
http://geocoder-php.org/GeocoderLaravel/
MIT License
704 stars 102 forks source link

Class "Nyholm\Psr7\Factory\HttplugFactory" is deprecated since version 1.8, use "Nyholm\Psr7\Factory\Psr17Factory" instead #196

Open forthowin opened 1 year ago

forthowin commented 1 year ago

General Information

GeocoderLaravel Version: 4.6 Laravel Version: 10.13 PHP Version: 8.1 Operating System and Version: macOS Monterey

Issue Description

I'm getting the warning message in the title. How do I make geocoder use Psr17Factory?

Steps to Replicate

The code I am using:

$geocodeData = app('geocoder')->geocode($this->visitorIp)->get()->first();

Here is my geocoder config:

<?php

use App\Providers\Geocoder\Providers\GeoIP2\GeoIP2;
use App\Providers\Geocoder\Providers\Ipstack\Ipstack;
use Geocoder\Provider\Chain\Chain;
use GeoIp2\WebService\Client as WebService;
use Http\Adapter\Guzzle7\Client;

return [
    'cache' => [

        /*
        |-----------------------------------------------------------------------
        | Cache Store
        |-----------------------------------------------------------------------
        |
        | Specify the cache store to use for caching. The value "null" will use
        | the default cache store specified in /config/cache.php file.
        |
        | Default: null
        |
        */

        'store' => null,

        /*
        |-----------------------------------------------------------------------
        | Cache Duration
        |-----------------------------------------------------------------------
        |
        | Specify the cache duration in minutes. The default approximates a
        | "forever" cache, but there are certain issues with Laravel's forever
        | caching methods that prevent us from using them in this project.
        |
        | Default: 9999999 (integer)
        |
        */

        'duration' => 9999999,
    ],

    /*
    |---------------------------------------------------------------------------
    | Providers
    |---------------------------------------------------------------------------
    |
    | Here you may specify any number of providers that should be used to
    | perform geocaching operations. The `chain` provider is special,
    | in that it can contain multiple providers that will be run in
    | the sequence listed, should the previous provider fail. By
    | default the first provider listed will be used, but you
    | can explicitly call subsequently listed providers by
    | alias: `app('geocoder')->using('google_maps')`.
    |
    | Please consult the official Geocoder documentation for more info.
    | https://github.com/geocoder-php/Geocoder#providers
    |
    */
    'providers' => [
        Chain::class => [
            Ipstack::class => [env('IPSTACK_ACCESS_KEY')],
            GeoIP2::class => [],
        ],
    ],

    /*
    |---------------------------------------------------------------------------
    | Adapter
    |---------------------------------------------------------------------------
    |
    | You can specify which PSR-7-compliant HTTP adapter you would like to use.
    | There are multiple options at your disposal: CURL, Guzzle, and others.
    |
    | Please consult the official Geocoder documentation for more info.
    | https://github.com/geocoder-php/Geocoder#usage
    |
    | Default: Client::class (FQCN for CURL adapter)
    |
    */
    'adapter' => Client::class,

    /*
    |---------------------------------------------------------------------------
    | Reader
    |---------------------------------------------------------------------------
    |
    | You can specify a reader for specific providers, like GeoIp2, which
    | connect to a local file-database. The reader should be set to an
    | instance of the required reader class.
    |
    | Please consult the official Geocoder documentation for more info.
    | https://github.com/geocoder-php/geoip2-provider
    |
    | Default: null
    |
    */
    'reader' => [
        WebService::class => [
            env('MAXMIND_USER_ID'),
            env('MAXMIND_LICENSE_KEY'),
        ],
    ],
];

Here is Ipstack.php:


<?php

declare(strict_types=1);

/*
 * This file is part of the Geocoder package.
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * @license    MIT License
 */

namespace App\Providers\Geocoder\Providers\Ipstack;

use App\Providers\Geocoder\Model\Address;
use Geocoder\Collection;
use Geocoder\Exception\InvalidArgument;
use Geocoder\Exception\InvalidCredentials;
use Geocoder\Exception\QuotaExceeded;
use Geocoder\Exception\UnsupportedOperation;
use Geocoder\Http\Provider\AbstractHttpProvider;
use Geocoder\Model\AddressCollection;
use Geocoder\Provider\Provider;
use Geocoder\Query\GeocodeQuery;
use Geocoder\Query\ReverseQuery;
use Psr\Http\Client\ClientInterface;

/**
 * @author Jonas Gielen <gielenjonas@gmail.com>
 */
final class Ipstack extends AbstractHttpProvider implements Provider
{
    /**
     * @var string
     */
    const GEOCODE_ENDPOINT_URL = 'http://api.ipstack.com/%s?access_key=%s';

    /**
     * @var string
     */
    private $apiKey;

    /**
     * @param  ClientInterface  $client an HTTP adapter
     * @param  string  $apiKey an API key
     */
    public function __construct(ClientInterface $client, string $apiKey)
    {
        if (empty($apiKey)) {
            throw new InvalidCredentials('No API key provided.');
        }

        $this->apiKey = $apiKey;
        parent::__construct($client);
    }

    /**
     * {@inheritdoc}
     */
    public function geocodeQuery(GeocodeQuery $query): Collection
    {
        $address = $query->getText();

        // This API doesn't handle IPs
        if (! filter_var($address, FILTER_VALIDATE_IP)) {
            throw new UnsupportedOperation('The Ipstack provider does not support street addresses.');
        }

        if (in_array($address, ['127.0.0.1', '::1'])) {
            return new AddressCollection([$this->getLocationForLocalhost()]);
        }

        $url = sprintf(sprintf(self::GEOCODE_ENDPOINT_URL, $address, $this->apiKey));

        if (null !== $query->getLocale()) {
            $url = sprintf('%s&language=%s', $url, $query->getLocale());
        }

        $body = $this->getUrlContents($url);
        $data = json_decode($body, true);

        // https://ipstack.com/documentation#errors
        if (isset($data['error'])) {
            switch ($data['error']['code']) {
                case 301:
                    throw new InvalidArgument('Invalid request (a required parameter is missing).');
                case 303:
                    throw new InvalidArgument('Bulk requests are not supported on your plan. Please upgrade your subscription.');
                case 104:
                    throw new QuotaExceeded('The maximum allowed amount of monthly API requests has been reached.');
                case 101:
                    throw new InvalidCredentials('No API Key was specified or an invalid API Key was specified.');
            }
        }

        if (null === $data['latitude']
            && null === $data['longitude']
            && null === $data['connection']
            && null === $data['city']
            && null === $data['region_name']
            && null === $data['region_code']
            && null === $data['zip']
            && null === $data['country_name']
            && null === $data['country_code']) {
            return new AddressCollection([]);
        }

        $adminLevels = [];
        $adminLevels[] = ['name' => $data['region_name'], 'code' => $data['region_code'], 'level' => 1];

        $locations[] = Address::createFromArray([
            'providedBy' => $this->getName(),
            'latitude' => $data['latitude'] ?: null,
            'longitude' => $data['longitude'] ?: null,
            'connection' => $data['connection'] ?: null,
            'locality' => $data['city'] ?: null,
            'postalCode' => $data['zip'] ?: null,
            'country' => $data['country_name'] ?: null,
            'countryCode' => $data['country_code'] ?: null,
            'adminLevels' => $adminLevels,
        ]);

        return new AddressCollection($locations);
    }

    /**
     * {@inheritdoc}
     */
    public function reverseQuery(ReverseQuery $query): Collection
    {
        throw new UnsupportedOperation('The Ipstack provider is not able to do reverse geocoding.');
    }

    /**
     * {@inheritdoc}
     */
    public function getName(): string
    {
        return 'ipstack';
    }
}

Here are the relevant composer installs:


"php": "^8.1",
"laravel/framework": "^10.13",
"geocoder-php/geoip2-provider": "^4.3",
"geocoder-php/ipstack-provider": "^0.4.0",
"toin0u/geocoder-laravel": "^4.6",
"guzzlehttp/guzzle": "^7.7",
"php-http/guzzle7-adapter": "^1.0",

Stack Trace

Class "Nyholm\Psr7\Factory\HttplugFactory" is deprecated since version 1.8, use "Nyholm\Psr7\Factory\Psr17Factory" instead. in /vendor/nyholm/psr7/src/Factory/HttplugFactory.php on line 18