View source
<?php
namespace Drupal\geolocation\Plugin\views\argument;
use Drupal\views\Plugin\views\argument\Formula;
use Drupal\views\Plugin\views\query\Sql;
use Drupal\Core\Form\FormStateInterface;
use Drupal\geolocation\ProximityTrait;
class ProximityArgument extends Formula {
use ProximityTrait;
protected $operator = '<';
protected $distance = 0;
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<=5mi"</strong> (defaults to km).');
}
public function getFormula() {
$values = $this
->getParsedReferenceLocation();
if (!empty($values) && isset($values['lat']) && isset($values['lng']) && isset($values['distance'])) {
$distance = self::convertDistance((double) $values['distance'], $values['unit']);
$formula = self::getProximityQueryFragment($this->tableAlias, $this->realField, $values['lat'], $values['lng']);
$this->operator = $values['operator'];
$this->distance = $distance;
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();
if (!$formula) {
return;
}
$formula .= ' ' . $this->operator . ' ' . $placeholder;
$placeholders = [
$placeholder => $this->distance,
];
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,
'unit' => isset($values[5]) ? $values[5] : 'km',
] : FALSE;
}
return $values;
}
}