View source
<?php
namespace Drupal\geolocation\Plugin\views\filter;
use Drupal\Core\Form\FormStateInterface;
use Drupal\views\Plugin\views\filter\FilterPluginBase;
use Drupal\views\Plugin\views\query\Sql;
use Drupal\geolocation\GeocoderManager;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\Core\Render\BubbleableMetadata;
use Drupal\geolocation\BoundaryTrait;
use Drupal\Component\Utility\NestedArray;
class BoundaryFilter extends FilterPluginBase implements ContainerFactoryPluginInterface {
use BoundaryTrait;
public $no_operator = TRUE;
public $isGeolocationCommonMapOption = TRUE;
protected $alwaysMultiple = TRUE;
protected $geocoderManager;
public function __construct(array $configuration, $plugin_id, $plugin_definition, GeocoderManager $geocoder_manager) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->geocoderManager = $geocoder_manager;
}
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static($configuration, $plugin_id, $plugin_definition, $container
->get('plugin.manager.geolocation.geocoder'));
}
public function adminSummary() {
return $this
->t("Boundary filter");
}
protected function defineOptions() {
$options = parent::defineOptions();
$options['expose']['contains']['input_by_geocoding_widget'] = [
'default' => FALSE,
];
$options['expose']['contains']['geocoder_plugin_settings'] = [
'default' => [
'plugin_id' => '',
'settings' => [],
],
];
return $options;
}
public function buildExposeForm(&$form, FormStateInterface $form_state) {
$geocoder_settings = NestedArray::getValue($form_state
->getUserInput(), [
'options',
'expose',
'geocoder_plugin_settings',
]);
if (empty($geocoder_settings)) {
$geocoder_settings = $this->options['expose']['geocoder_plugin_settings'];
}
if (empty($geocoder_settings)) {
$geocoder_settings = [];
}
$geocoder_options = [];
foreach ($this->geocoderManager
->getDefinitions() as $id => $definition) {
if (empty($definition['frontendCapable'])) {
continue;
}
$geocoder_options[$id] = $definition['name'];
}
if ($geocoder_options) {
$form['expose']['input_by_geocoding_widget'] = [
'#type' => 'checkbox',
'#title' => $this
->t('Use geocoding widget to retrieve boundary values'),
'#default_value' => $this->options['expose']['input_by_geocoding_widget'],
];
$form['expose']['geocoder_plugin_settings'] = [
'#type' => 'container',
'#states' => [
'visible' => [
'input[name="options[expose][input_by_geocoding_widget]"]' => [
'checked' => TRUE,
],
],
],
];
$geocoder_container =& $form['expose']['geocoder_plugin_settings'];
$geocoder_container['plugin_id'] = [
'#type' => 'select',
'#options' => $geocoder_options,
'#title' => $this
->t('Geocoder plugin'),
'#default_value' => $geocoder_settings['plugin_id'],
'#ajax' => [
'callback' => [
get_class($this->geocoderManager),
'addGeocoderSettingsFormAjax',
],
'wrapper' => 'boundary-geocoder-plugin-settings',
'effect' => 'fade',
],
];
if (!empty($geocoder_settings['plugin_id'])) {
$geocoder_plugin = $this->geocoderManager
->getGeocoder($geocoder_settings['plugin_id'], $geocoder_settings['settings']);
}
elseif (current(array_keys($geocoder_options))) {
$geocoder_plugin = $this->geocoderManager
->getGeocoder(current(array_keys($geocoder_options)));
}
if (!empty($geocoder_plugin)) {
$geocoder_settings_form = $geocoder_plugin
->getOptionsForm();
if ($geocoder_settings_form) {
$geocoder_container['settings'] = $geocoder_settings_form;
}
}
if (empty($geocoder_container['settings'])) {
$geocoder_container['settings'] = [
'#type' => 'html_tag',
'#tag' => 'span',
'#value' => $this
->t("No settings available."),
];
}
$geocoder_container['settings'] = array_replace_recursive($geocoder_container['settings'], [
'#flatten' => TRUE,
'#prefix' => '<div id="boundary-geocoder-plugin-settings">',
'#suffix' => '</div>',
]);
}
parent::buildExposeForm($form, $form_state);
}
public function buildExposedForm(&$form, FormStateInterface $form_state) {
parent::buildExposedForm($form, $form_state);
if (!$this->options['expose']['input_by_geocoding_widget'] || !empty($this->options['expose']['geocoder_plugin_settings'])) {
return;
}
$identifier = $this->options['expose']['identifier'];
if (empty($form[$identifier]) && empty($form[$identifier . '_wrapper'])) {
return;
}
$geocoder_configuration = $this->options['expose']['geocoder_plugin_settings']['settings'];
$geocoder_plugin = $this->geocoderManager
->getGeocoder($this->options['expose']['geocoder_plugin_settings']['plugin_id'], $geocoder_configuration);
if (empty($geocoder_plugin)) {
return;
}
if (!empty($form[$identifier . '_wrapper'])) {
$form[$identifier . '_wrapper'][$identifier]['lat_north_east']['#type'] = 'hidden';
$form[$identifier . '_wrapper'][$identifier]['lng_north_east']['#type'] = 'hidden';
$form[$identifier . '_wrapper'][$identifier]['lat_south_west']['#type'] = 'hidden';
$form[$identifier . '_wrapper'][$identifier]['lng_south_west']['#type'] = 'hidden';
$geocoder_plugin
->formAttachGeocoder($form[$identifier . '_wrapper'][$identifier], $identifier);
}
else {
$form[$identifier]['lat_north_east']['#type'] = 'hidden';
$form[$identifier]['lng_north_east']['#type'] = 'hidden';
$form[$identifier]['lat_south_west']['#type'] = 'hidden';
$form[$identifier]['lng_south_west']['#type'] = 'hidden';
$geocoder_plugin
->formAttachGeocoder($form[$identifier], $identifier);
}
$form = BubbleableMetadata::mergeAttachments($form, [
'#attached' => [
'library' => [
'geolocation/geolocation.views.filter.geocoder',
],
'drupalSettings' => [
'geolocation' => [
'geocoder' => [
'viewsFilterGeocoder' => [
$identifier => [
'type' => 'boundary',
],
],
],
],
],
],
]);
}
public function acceptExposedInput($input) {
if (!empty($this->value['lat_north_east']) && !empty($this->value['lng_north_east']) && !empty($this->value['lat_south_west']) && !empty($this->value['lng_south_west'])) {
return TRUE;
}
$return_value = parent::acceptExposedInput($input);
if ($this->options['expose']['input_by_geocoding_widget'] && !empty($this->options['expose']['geocoder_plugin_settings']['plugin_id'])) {
$this->value = $input[$this->options['expose']['identifier']];
$geocoder_configuration = $this->options['expose']['geocoder_plugin_settings']['settings'];
$geocoder_plugin = $this->geocoderManager
->getGeocoder($this->options['expose']['geocoder_plugin_settings']['plugin_id'], $geocoder_configuration);
if (!empty($geocoder_plugin) && !empty($input[$this->options['expose']['identifier']]['geolocation_geocoder_address'])) {
$location_data = $geocoder_plugin
->geocode($input[$this->options['expose']['identifier']]['geolocation_geocoder_address']);
if (!empty($location_data['boundary'])) {
$this->value = array_replace($input[$this->options['expose']['identifier']], $location_data['boundary']);
}
}
}
if (empty($this->value)) {
$this->value = [];
}
return $return_value;
}
protected function valueForm(&$form, FormStateInterface $form_state) {
parent::valueForm($form, $form_state);
$form['value']['#tree'] = TRUE;
$value_element =& $form['value'];
$value_element += [
'lat_north_east' => [
'#type' => 'textfield',
'#title' => $this
->t('North East Boundary - Latitude'),
'#default_value' => !empty($this->value['lat_north_east']) ? $this->value['lat_north_east'] : '',
'#weight' => 10,
],
'lng_north_east' => [
'#type' => 'textfield',
'#title' => $this
->t('North East Boundary - Longitude'),
'#default_value' => !empty($this->value['lng_north_east']) ? $this->value['lng_north_east'] : '',
'#weight' => 20,
],
'lat_south_west' => [
'#type' => 'textfield',
'#title' => $this
->t('South West Boundary - Latitude'),
'#default_value' => !empty($this->value['lat_south_west']) ? $this->value['lat_south_west'] : '',
'#weight' => 30,
],
'lng_south_west' => [
'#type' => 'textfield',
'#title' => $this
->t('South West Boundary - Longitude'),
'#default_value' => !empty($this->value['lng_south_west']) ? $this->value['lng_south_west'] : '',
'#weight' => 40,
],
];
}
public function query() {
if (!$this->query instanceof Sql) {
return;
}
if (empty($this->value)) {
return;
}
$lat_north_east = $this->value['lat_north_east'];
$lng_north_east = $this->value['lng_north_east'];
$lat_south_west = $this->value['lat_south_west'];
$lng_south_west = $this->value['lng_south_west'];
if (!is_numeric($lat_north_east) || !is_numeric($lng_north_east) || !is_numeric($lat_south_west) || !is_numeric($lng_south_west)) {
return;
}
$this->query
->addWhereExpression($this->options['group'], self::getBoundaryQueryFragment($this
->ensureMyTable(), $this->realField, $lat_north_east, $lng_north_east, $lat_south_west, $lng_south_west));
}
}