'lt');
$options['proximity']['radius_unit'] = array('default' => GEOFIELD_KILOMETERS);
return $options;
}
/**
* Add form elements to select options for this contextual filter.
*/
function options_form(&$form, &$form_state) {
parent::options_form($form, $form_state);
$form['proximity'] = array(
'#type' => 'fieldset',
'#title' => t('Filter locations by proximity to a reference point'),
);
$form['proximity']['operation'] = array(
'#type' => 'select',
'#title' => t('Select locations'),
'#options' => array(
'lt' => t('Inside radius'),
'gt' => t('Outside radius'),
),
'#default_value' => $this->options['operation'],
'#description' => t("Reference point coordinates (lat,lon) and distance are typically appended to the URL. A fallback may be entered above under Provide default value as either a Fixed value or as PHP Code.
In all cases use this format: lat,lon distance. You may omit either lat,lon or distance. Instead of spaces and comma's, you can use underscores."),
);
$form['proximity']['radius_unit'] = array(
'#type' => 'select',
'#title' => t('Unit of distance'),
'#options' => array(
GEOFIELD_KILOMETERS => t('kilometer'),
GEOFIELD_MILES => t('mile'),
),
'#default_value' => $this->options['radius_unit'],
'#description' => t('Select the unit of distance.'),
);
}
/**
* Set up the where clause for the contextual filter argument.
*/
function query($group_by = FALSE) {
// Get and process arguments
foreach ($this->view->argument as $argument) {
if ($argument->field == 'field_geofield_distance') {
// Expect and parse this format: "lat,lon dist"
$arg_string = $this->view->args[$argument->position];
$args = array_filter(preg_split(GEOFIELD_PROXIMITY_REGEXP_PATTERN, $arg_string));
// Use next() on $args as after array_filter() we cannot be sure what the
// element indices are.
$lat = reset($args);
$lon = next($args);
$dist = next($args);
if (count($args) == 3) { // we're good to proceed
break;
}
// Either distance or lat,lon where omitted. See if we can get these
// from either the Fixed or PHP Code default values.
if (empty($this->options['default_argument_options'])) { // nope
return;
}
$default = $this->options['default_argument_options'];
if (!empty($default['argument'])) {
$defaults = preg_split(GEOFIELD_PROXIMITY_REGEXP_PATTERN, $default['argument']);
}
elseif (!empty($default['code'])) {
$defaults = preg_split(GEOFIELD_PROXIMITY_REGEXP_PATTERN, php_eval(''));
}
else {
return;
}
$defaults = array_filter($defaults);
if ($lat !== FALSE && $lon !== FALSE) {
// 2 args received, interpret as lat,lon and take distrance from default
if (empty($defaults) || count($defaults) == 2) { // expecting either 1 or 3 numbers
return;
}
$dist = isset($defaults[2]) ? $defaults[2] : reset($defaults);
break;
}
if ($lat !== FALSE && $lon === FALSE) {
// 1 arg received, interpret as distance and take lat,lon from default
$dist = $lat;
$lat = reset($defaults);
$lon = next($defaults);
break;
}
// If we get here, we're dealing with rubbish
return;
}
}
$haversine_args = array(
'earth_radius' => $this->options['proximity']['radius_unit'],
'origin_latitude' => $lat,
'origin_longitude' => $lon,
'destination_latitude' => $this->table . '.' . $this->definition['field_name'] . '_lat',
'destination_longitude' => $this->table . '.' . $this->definition['field_name'] . '_lon',
);
$formula = geofield_haversine($haversine_args);
$operator = ($this->options['proximity']['operation'] == 'gt') ? '>' : '<';
$this->ensure_my_table();
$this->query->add_where_expression(0, "$formula $operator $dist");
}
}