View source
<?php
namespace Drupal\search_api_location_views\Plugin\views\filter;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Form\SubformState;
use Drupal\search_api_location\LocationInput\LocationInputPluginManager;
use Drupal\views\Plugin\views\filter\FilterPluginBase;
use Symfony\Component\DependencyInjection\ContainerInterface;
class SearchApiFilterLocation extends FilterPluginBase {
protected $locationInputManager;
public function __construct(array $configuration, $plugin_id, $plugin_definition, LocationInputPluginManager $location_input_manager) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->locationInputManager = $location_input_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.search_api_location.location_input'));
}
public function adminSummary() {
$pluginId = $this->options['plugin'];
return $this->operator . ' ' . $pluginId;
}
protected function defineOptions() {
$options = parent::defineOptions();
$options['plugin']['default'] = '';
foreach ($this->locationInputManager
->getDefinitions() as $id => $plugin) {
$options["plugin-{$id}"]['default'] = [];
}
$options['value'] = [
'contains' => [
'value' => [
'default' => '',
],
'distance' => [
'contains' => [
'from' => [
'default' => '',
],
'to' => [
'default' => '',
],
],
],
],
];
return $options;
}
public function hasExtraOptions() {
return TRUE;
}
public function buildExtraOptionsForm(&$form, FormStateInterface $form_state) {
$form['plugin'] = [
'#type' => 'select',
'#title' => $this
->t('Input method'),
'#description' => $this
->t('Select the method to use for parsing locations entered by the user.'),
'#options' => $this->locationInputManager
->getInstancesOptions(),
'#default_value' => $this->options['plugin'],
'#required' => TRUE,
];
foreach ($this->locationInputManager
->getDefinitions() as $id => $plugin) {
$settings = !empty($this->options['plugin-' . $id]) ? $this->options['plugin-' . $id] : [];
$plugin = $this->locationInputManager
->createInstance($id, $settings);
$form["plugin-{$id}"] = [
'#type' => 'fieldset',
'#title' => $plugin
->getDescription(),
'#tree' => TRUE,
'#states' => [
'visible' => [
'select[name="options[plugin]"]' => [
'value' => $id,
],
],
],
];
$form["plugin-{$id}"] += $plugin
->buildConfigurationForm($form["plugin-{$id}"], $form_state);
}
return $form;
}
public function submitExtraOptionsForm($form, FormStateInterface $form_state) {
$plugin_id = $form_state
->getValues()['options']['plugin'];
$plugin = $this->locationInputManager
->createInstance($plugin_id, $this->options['plugin-' . $plugin_id]);
$processor_form_state = SubformState::createForSubform($form['plugin-' . $plugin_id], $form, $form_state);
$plugin
->submitConfigurationForm($form['plugin-' . $plugin_id], $processor_form_state);
parent::submitExtraOptionsForm($form, $form_state);
}
public function operatorOptions() {
$options = [
'<' => t('less than'),
'between' => t('between'),
'>' => t('more than'),
];
return $options;
}
protected function valueForm(&$form, FormStateInterface $form_state) {
$plugin_id = $this->options['plugin'];
if (!$plugin_id) {
return;
}
$plugin = $this->locationInputManager
->createInstance($plugin_id, $this->options['plugin-' . $plugin_id]);
$form = $plugin
->getForm($form, $form_state, $this->options + [
'operator_options' => $this
->operatorOptions(),
]);
}
public function query() {
$plugin_id = $this->options['plugin'];
if (!$plugin_id) {
return;
}
$plugin_options = $this->options['plugin-' . $plugin_id];
$plugin = $this->locationInputManager
->createInstance($plugin_id, $plugin_options);
if (!$plugin
->hasInput($this->value, $this->options)) {
return;
}
$location = $plugin
->getParsedInput($this->value);
if (!$location) {
$this
->messenger()
->addWarning($this
->t('The location %location could not be resolved and was ignored.', [
'%location' => $this->value['value'],
]));
return;
}
$location = explode(',', $location, 2);
$query = $this->query;
$location_options = (array) $query
->getOption('search_api_location', []);
$radius = !is_numeric($this->value['distance']['from']) ? NULL : $this->value['distance']['from'];
if ($plugin_options['radius_type'] == 'textfield') {
$units = array_column(search_api_location_get_units(), 'multiplier', 'id');
$multiplier = $units[$plugin_options['radius_units']];
$radius *= $multiplier;
}
$location_options[] = [
'field' => $this->realField,
'lat' => $location[0],
'lon' => $location[1],
'radius' => $radius,
];
$query
->setOption('search_api_location', $location_options);
}
}