View source
<?php
namespace Drupal\geolocation\Plugin\views\argument;
use Drupal\geolocation\GeolocationCore;
use Drupal\views\Plugin\views\argument\Formula;
use Drupal\views\Plugin\views\query\Sql;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
class ProximityArgument extends Formula implements ContainerFactoryPluginInterface {
protected $operator = '<';
protected $proximity = '';
protected $geolocationCore;
public function __construct(array $configuration, $plugin_id, $plugin_definition, GeolocationCore $geolocation_core) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->geolocationCore = $geolocation_core;
}
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
$geolocation_core = $container
->get('geolocation.core');
return new static($configuration, $plugin_id, $plugin_definition, $geolocation_core);
}
public function buildOptionsForm(&$form, FormStateInterface $form_state) {
parent::buildOptionsForm($form, $form_state);
$form['description']['#markup'] .= $this
->t('<br/> Proximity format should be in the following format: <strong>"37.7749295,-122.41941550000001<=5miles"</strong> (defaults to km).');
}
public function getFormula() {
$values = $this
->getParsedReferenceLocation();
if ($values && $values['lat'] && $values['lng'] && $values['distance']) {
$earth_radius = $values['units'] === 'mile' ? GeolocationCore::EARTH_RADIUS_MILE : GeolocationCore::EARTH_RADIUS_KM;
$formula = $this->geolocationCore
->getProximityQueryFragment($this->tableAlias, $this->realField, $values['lat'], $values['lng'], $earth_radius);
$this->proximity = $values['distance'];
$this->operator = $values['operator'];
return !empty($formula) ? str_replace('***table***', $this->tableAlias, $formula) : FALSE;
}
else {
return FALSE;
}
}
public function query($group_by = FALSE) {
$this
->ensureMyTable();
$placeholder = $this
->placeholder();
$formula = $this
->getFormula() . ' ' . $this->operator . ' ' . $placeholder;
$placeholders = [
$placeholder => $this->proximity,
];
if ($this->query instanceof Sql) {
$this->query
->addWhere(0, $formula, $placeholders, 'formula');
}
}
public function getParsedReferenceLocation() {
static $values;
if (!isset($values)) {
preg_match('/^([0-9\\-.]+),+([0-9\\-.]+)([<>=]+)([0-9.]+)(.*$)/', $this
->getValue(), $values);
$values = is_array($values) ? [
'lat' => isset($values[1]) && is_numeric($values[1]) && $values[1] >= -90 && $values[1] <= 90 ? floatval($values[1]) : FALSE,
'lng' => isset($values[2]) && is_numeric($values[2]) && $values[2] >= -180 && $values[2] <= 180 ? floatval($values[2]) : FALSE,
'operator' => isset($values[3]) && in_array($values[3], [
'<>',
'=',
'>=',
'<=',
'>',
'<',
]) ? $values[3] : '<=',
'distance' => isset($values[4]) ? floatval($values[4]) : FALSE,
'units' => isset($values[5]) && strpos(strtolower($values[5]), 'mile') !== FALSE ? 'mile' : 'km',
] : FALSE;
}
return $values;
}
}