diff --git a/modules/search_api_location_geocoder/src/Plugin/search_api_location/location_input/Geocode.php b/modules/search_api_location_geocoder/src/Plugin/search_api_location/location_input/Geocode.php index d473cdc..34ee3f5 100644 --- a/modules/search_api_location_geocoder/src/Plugin/search_api_location/location_input/Geocode.php +++ b/modules/search_api_location_geocoder/src/Plugin/search_api_location/location_input/Geocode.php @@ -2,13 +2,12 @@ namespace Drupal\search_api_location_geocoder\Plugin\search_api_location\location_input; -use Drupal\Core\Config\ConfigFactoryInterface; use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Plugin\ContainerFactoryPluginInterface; +use Drupal\geocoder\Entity\GeocoderProvider; use Drupal\geocoder\Geocoder; use Drupal\search_api_location\LocationInput\LocationInputPluginBase; -use Drupal\Component\Utility\SortArray; use Symfony\Component\DependencyInjection\ContainerInterface; /** @@ -29,13 +28,6 @@ class Geocode extends LocationInputPluginBase implements ContainerFactoryPluginI */ protected $geocoder; - /** - * The geocoder config. - * - * @var \Drupal\Core\Config\ImmutableConfig - */ - protected $geocoderConfig; - /** * The entity storage class. * @@ -54,12 +46,11 @@ class Geocode extends LocationInputPluginBase implements ContainerFactoryPluginI * The plugin implementation definition. * @param \Drupal\geocoder\Geocoder $geocoder * The geocoder service. - * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory - * A config factory for retrieving required config objects. + * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager + * The Entity Type Manager for loading the providers. */ - public function __construct(array $configuration, $plugin_id, $plugin_definition, Geocoder $geocoder, ConfigFactoryInterface $config_factory, EntityTypeManagerInterface $entity_type_manager) { + public function __construct(array $configuration, $plugin_id, $plugin_definition, Geocoder $geocoder, EntityTypeManagerInterface $entity_type_manager) { $this->geocoder = $geocoder; - $this->geocoderConfig = $config_factory->get('geocoder.settings'); $this->geocoderProviderStorage = $entity_type_manager->getStorage('geocoder_provider'); parent::__construct($configuration, $plugin_id, $plugin_definition); } @@ -73,7 +64,6 @@ class Geocode extends LocationInputPluginBase implements ContainerFactoryPluginI $plugin_id, $plugin_definition, $container->get('geocoder'), - $container->get('config.factory'), $container->get('entity_type.manager') ); } @@ -85,18 +75,11 @@ class Geocode extends LocationInputPluginBase implements ContainerFactoryPluginI if (empty($input['value'])) { throw new \InvalidArgumentException('Input doesn\'t contain a location value.'); } - else { - $active_plugins = $this->getActivePlugins(); - $plugin_options = (array) $this->geocoderConfig->get('plugins_options'); - - /** @var \Geocoder\Model\AddressCollection $geocoded_addresses */ - $geocoded_addresses = $this->geocoder - ->geocode($input['value'], $active_plugins, $plugin_options); - if ($geocoded_addresses) { - return $geocoded_addresses->first()->getCoordinates() - ->getLatitude() . ',' . $geocoded_addresses->first()->getCoordinates() - ->getLongitude(); - } + $providers = $this->getEnabledProviders(); + $geocoded_addresses = $this->geocoder->geocode($input['value'], $providers); + if ($geocoded_addresses) { + $coordinates = $geocoded_addresses->first()->getCoordinates(); + return $coordinates->getLatitude() . ',' . $coordinates->getLongitude(); } return NULL; } @@ -104,17 +87,28 @@ class Geocode extends LocationInputPluginBase implements ContainerFactoryPluginI /** * Gets the active geocoder plugins. */ - protected function getActivePlugins() { - $plugins = $this->configuration['plugins']; - uasort($plugins, [SortArray::class, 'sortByWeightProperty']); - - $active_plugins = []; - foreach ($plugins as $id => $plugin) { - if ($plugin['checked']) { - $active_plugins[$id] = $id; + protected function getEnabledProviders() { + // Get the current selected providers + $selected_providers = $this->configuration['plugins']; + + // Load all the providers + $geocoderProviders = $this->geocoderProviderStorage->loadMultiple(); + + // Filter out all providers that are disabled. + $providers = array_filter($geocoderProviders, function (GeocoderProvider $provider) use ($selected_providers): bool { + return !empty($selected_providers[$provider->id()]) && $selected_providers[$provider->id()]['checked'] == TRUE; + }); + + // Sort providers according to weight. + uasort($providers, function (GeocoderProvider $a, GeocoderProvider $b) use ($selected_providers): int { + if ((int) $selected_providers[$a->id()]['weight'] === (int) $selected_providers[$b->id()]['weight']) { + return 0; } - } - return $active_plugins; + + return (int) $selected_providers[$a->id()]['weight'] < (int) $selected_providers[$b->id()]['weight'] ? -1 : 1; + }); + + return $providers; } /** diff --git a/modules/search_api_location_geocoder/tests/src/Kernel/GeocodeTest.php b/modules/search_api_location_geocoder/tests/src/Kernel/GeocodeTest.php index c87737a..a728adf 100644 --- a/modules/search_api_location_geocoder/tests/src/Kernel/GeocodeTest.php +++ b/modules/search_api_location_geocoder/tests/src/Kernel/GeocodeTest.php @@ -37,7 +37,7 @@ class GeocodeTest extends KernelTestBase { /** * {@inheritdoc} */ - public function setUp(): void { + protected function setUp():void { parent::setUp(); $ghent = new AddressCollection([new Address('n/a', new AdminLevelCollection([]), new Coordinates(51.037455, 3.7192784))]); @@ -106,4 +106,15 @@ class GeocodeTest extends KernelTestBase { $this->sut->getParsedInput($input); } + /** + * Test the parsed input entered by user in raw format with invalid data. + * + * @covers ::getParsedInput + */ + public function testInvalidInput() { + $input = ['value' => ['animal' => 'llama']]; + $this->expectException(\TypeError::class); + $this->sut->getParsedInput($input); + } + } diff --git a/tests/src/Kernel/RawTest.php b/tests/src/Kernel/RawTest.php index ac1176c..0b6269b 100644 --- a/tests/src/Kernel/RawTest.php +++ b/tests/src/Kernel/RawTest.php @@ -31,7 +31,7 @@ class RawTest extends KernelTestBase { /** * {@inheritdoc} */ - public function setUp(): void { + protected function setUp():void { parent::setUp(); $this->sut = $this->container