geocoder-php/GeocoderLaravel

Broken getProvider method

antonkomarev opened this issue ยท 15 comments

It's trying to access to private method:

protected function getProvider()
{
return $this->aggregator->getProvider();
}

https://github.com/geocoder-php/Geocoder/blob/69167527c25779e604791f5eef4f3f9a96b6e9dc/src/Common/ProviderAggregator.php#L166-L192

Why is this useless? Please provide more detail as to what the problem is, what you are trying to do, and what you think the solution would be.

Because you cannot call private method getProvider outside of the Geocoder\ProviderAggregator class, an exception will be thrown.
I haven't thought about solution of this issue, and haven't tried to use it... just researched how this package is working and noticed an error in IDE. It's looks like base Geocoder package API was changed and this method isn't exposed to public anymore.

There is no problem that I have seen. I have unit tests for all these methods. Please provide a complete stack trace, package version, PHP version, Laravel version, and providers and aggregators you are using.

PHP 7.1
"toin0u/geocoder-laravel": "^4.0"

Haven't changed any config. Clean package install.

Code sample:

$provider = app('geocoder')->getProvider();
dd($provider);

Error: Call to protected method Geocoder\Laravel\ProviderAndDumperAggregator::getProvider()

Any version of PHP will throw an exception, because you cannot call private method outside of the class!

OK, thanks. I see it now. Use ->getProviders(). Investigating if it needs to be removed or fixed. (I misread my unit test and didn't realize I was testing getProviders, and not geProvider.)

Yep. You still can get provider from Address instance:

$provider = app('geocoder)->geocode('Los Angeles, CA')->get()->first()->getProvidedBy();

But it will be great to have it oh higher level. To easier determine which provider was used to get this collection. Because there is a possibility to have 0 results in collection.

I inspected how the parent package works, and it basically just returns the first provider from all available ones. Posting a fix today, but will continue looking into a way to get the provider used for the current result. :)

Was looking more into this and thinking about it. Providing it at a higher level actually provides very little, if any value, as the each result could be provided by a different provider, so you must inspect at the result level, then if no results, look at what providers were loaded:

$providers = app('geocoder)->geocode('Los Angeles, CA')->getProviders();
$result = app('geocoder')->get()->first();
$provider = $result->getProvider() ?? $providers;

or something similar.

Better to leave this to the user to implement, as this will probably rarely be used.

Is there a possibility to get collection of results from different providers? I thought that providers will be called one by one until first one wouldn't return the success result.

Sure, that would involve iterating over each result and aggregating the used providers, just the same. Will look into if that's easy to implement.

If there could be collection of results from different providers thats make sense then. There is no need to have it on the top level in that case. I thought collection must contains results from one provider only.

oh, no, they are mixed, you get only one collection back

This is now "fixed" in 4.0.2 and marked as deprecated. Thanks for working through this with me.

You are welcome! Thank you for the package support and quick fix!