Problem/Motivation
When defining a custom Entity with BaseFieldDefinition's, it impossible to configure and apply the reverse geocoding feature of geocoder module.
It turns out, there's a way to provide third_party_settings to BaseFieldDefinition by a simple extends BaseFieldDefinition implements ThirdPartySettingsInterface:
my_module/src/Field/GeocoderBaseFieldDefinition.php:
<?php
namespace Drupal\my_module\Field;
use Drupal\Core\Field\BaseFieldDefinition;
use Drupal\Core\Config\Entity\ThirdPartySettingsInterface;
class GeocoderBaseFieldDefinition extends BaseFieldDefinition implements ThirdPartySettingsInterface
{
/**
* Third party settings.
*
* An array of key/value pairs keyed by provider.
*
* @var array[]
*/
protected $third_party_settings = [
'geocoder_field' => [
'skip_not_empty_value' => false,
'disabled' => false,
'hidden' => false,
'providers' => ['googlemaps'],
'delta_handling' => 'default',
'failure' => ['handling' => 'empty', 'status_message' => true, 'log' => true],
'geocode' => ['field' => '', 'delta_handling' => 'default']
]
];
/**
* {@inheritdoc}
*/
public function getThirdPartySetting($provider, $key, $default = NULL)
{
return $this->third_party_settings[$provider][$key] ?? $default;
}
/**
* {@inheritdoc}
*/
public function getThirdPartySettings($provider)
{
return $this->third_party_settings[$provider] ?? [];
}
/**
* {@inheritdoc}
*/
public function setThirdPartySetting($provider, $key, $value)
{
$this->third_party_settings[$provider][$key] = $value;
return $this;
}
/**
* {@inheritdoc}
*/
public function unsetThirdPartySetting($provider, $key)
{
unset($this->third_party_settings[$provider][$key]);
// If the third party is no longer storing any information, completely
// remove the array holding the settings for this provider.
if (empty($this->third_party_settings[$provider])) {
unset($this->third_party_settings[$provider]);
}
return $this;
}
/**
* {@inheritdoc}
*/
public function getThirdPartyProviders()
{
return array_keys($this->third_party_settings);
}
}
Now, in your Drupal\my_module\Entity\my_Entity.php the 'address' and corresponding 'geofield' is declared like so. Notice the GeocoderBaseFieldDefinition::create and calls of GeocoderBaseFieldDefinition::::setThirdPartySetting() to modulate the differences in 'address' and 'geofield':
...
$fields['address'] = GeocoderBaseFieldDefinition::create('address')
->setLabel(t('Addess'))
->setTranslatable(FALSE)
->setDescription(t('Address for the point of sales'))
->setSettings([
'field_overrides' => [
'givenName' => ['override' => 'hidden'],
'additionalName' => ['override' => 'hidden'],
'familyName' => ['override' => 'hidden'],
'organization' => ['override' => 'hidden'],
'dependentLocality' => ['override' => 'hidden'],
'administrativeArea' => ['override' => 'hidden']
]
])
->setThirdPartySetting('geocoder_field', 'method', 'reverse_geocode')
->setThirdPartySetting('geocoder_field', 'field', 'geofield')
->setThirdPartySetting('geocoder_field', 'dumper', 'geojson')
]);
$fields['geofield'] = GeocoderBaseFieldDefinition::create('geofield')
->setLabel(t('Geofield'))
->setTranslatable(FALSE)
->setDescription(t('Location of the point of sales'))
->setThirdPartySetting('geocoder_field', 'method', 'geocode')
->setThirdPartySetting('geocoder_field', 'field', 'address')
->setThirdPartySetting('geocoder_field', 'dumper', 'wkt')
->setDisplayOptions('form', [
'type' => 'geofield_map',
'weight' => -3,
'settings' => [
'html5_geolocation' => false,
'default_value' => [
'lat' => 0.0,
'lon' => 0.0
],
'map_library' => 'leaflet',
'map_type_leaflet' => 'OpenStreetMap_Mapnik',
'click_to_find_marker' => true,
'click_to_place_marker' => true,
'click_to_remove_marker' => false,
'hide_coordinates' => true,
'map_geocoder' => [
'control' => 1,
'settings' => [
'providers' => [
'googlemaps' => ['checked' => true]
]
]
]
]
]);
...
Proposed resolution
To make geocoder accept third_party_settings provided by the custom GeocoderBaseFieldDefinition only slight changes in geocoder module are required, changing a few instanceof targets. It's very simple, check my MR !
Issue fork geocoder-3375192
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #2
tomsaw commentedComment #3
tomsaw commentedComment #5
tomsaw commentedComment #6
itamair commentedHey TomSaw ... it looks that MR !34 is not mergeable and is indeed adding a lot of additional changes out of not relevant with) the context of this issue.
Such in the following files:
- doc/drupal_org_documentation/description.html
- modules/geocoder_address/src/AddressService.php
- etc ...
Didn't you notice and review your MR?
Please provide something that is indeed rebased to last stable Geocoder 8.x-4.9 release ...
Comment #7
tomsaw commentedOh darn. Since im a newby with gitlab and huge repos.. i had some trouble with the rebasing.
I first thought the MR was on 8.x-4.x
.. However. now it looks good to me
Comment #8
tomsaw commentedComment #9
tomsaw commentedComment #10
dwkitchen commentedReviewed and tested, works as described.
However, could we not add GeocoderBaseFieldDefinition and GeocoderBundleFieldDefinition to the Geocoder module, rather than having to define them in our custom modules?
Comment #11
tomsaw commentedPlease view the changes for this MR @dwkitchen.
I have not defined
GeocoderBaseFieldDefinition/GeocoderBundleFieldDefinitionin a custom module since it's already part of geocoder. The code blocks on top just demonstrate the application for this MRs feature!In geocoder itself the
GeocoderBaseFieldDefinitiondefinition has been extended, variousinstanceofdo now check against Interfaces rather than implementations and a few minor adjustments in geofield were required.What goes into your custom module - to use this MR's feature - is just your custom entity-type as it should be!
Comment #12
tomsaw commentedComment #17
tomsaw commentedComment #18
tomsaw commentedComment #27
itamair commentedI am not confident that this is really RTBC ... so moving back to Postponed, also because I can see a lot of new commits have been added, and the MR !34 is still marked as Draft etc.
Is there still some activity and commitment here?
Could we eventually have something more solid that Needs Review?
May be a brand new spinner off Issue could also make sense, after closing this as Outdated.