View source
<?php
define('GEOFIELD_KILOMETERS', 6371);
define('GEOFIELD_METERS', 6371000);
define('GEOFIELD_MILES', 3959);
define('GEOFIELD_YARDS', 6975175);
define('GEOFIELD_FEET', 20925525);
define('GEOFIELD_NAUTICAL_MILES', 3444);
function geofield_element_info() {
return array(
'geofield_latlon' => array(
'#input' => TRUE,
'#process' => array(
'geofield_latlon_element_process',
),
'#element_validate' => array(
'geofield_latlon_element_validate',
),
'#theme' => array(
'geofield_latlon',
),
'#theme_wrappers' => array(
'fieldset',
),
),
'geofield_bounds' => array(
'#input' => TRUE,
'#process' => array(
'geofield_bounds_element_process',
),
'#element_validate' => array(
'geofield_bounds_element_validate',
),
'#theme' => array(
'geofield_bounds',
),
'#theme_wrappers' => array(
'fieldset',
),
),
'geofield_proximity' => array(
'#input' => FALSE,
'#tree' => TRUE,
'#theme_wrappers' => array(
'geofield_proximity',
),
'#process' => array(
'geofield_proximity_element_process',
),
),
);
}
function geofield_latlon_element_process($element, &$form_values) {
$element['#tree'] = TRUE;
$element['#input'] = TRUE;
$element['lat'] = array(
'#type' => 'textfield',
'#title' => t('Latitude'),
'#required' => !empty($element['#required']) ? $element['#required'] : FALSE,
'#default_value' => !empty($element['#default_value']['lat']) ? $element['#default_value']['lat'] : '',
'#attributes' => array(
'class' => array(
'geofield-lat',
),
),
);
$element['lon'] = array(
'#type' => 'textfield',
'#title' => t('Longitude'),
'#required' => !empty($element['#required']) ? $element['#required'] : FALSE,
'#default_value' => !empty($element['#default_value']['lon']) ? $element['#default_value']['lon'] : '',
'#attributes' => array(
'class' => array(
'geofield-lon',
),
),
);
unset($element['#value']);
$element['#required'] = FALSE;
if (!empty($element['#geolocation']) && $element['#geolocation'] == TRUE) {
$element['#attached']['js'][] = drupal_get_path('module', 'geofield') . '/js/geolocation.js';
$element['geocode'] = array(
'#type' => 'button',
'#value' => t('Find my location'),
'#name' => 'geofield-html5-geocode-button',
);
$element['#attributes']['class'] = array(
'auto-geocode',
);
}
return $element;
}
function geofield_latlon_element_validate($element, &$form_values) {
$components = array(
'lat' => array(
'title' => 'Latitude',
'range' => 90,
),
'lon' => array(
'title' => 'Longitude',
'range' => 180,
),
);
$allFilled = TRUE;
$anyFilled = FALSE;
foreach ($components as $key => $component) {
if (!empty($element[$key]['#value'])) {
if (!is_numeric($element[$key]['#value'])) {
form_error($element[$key], t('@title: @component_title is not numeric.', array(
'@title' => $element['#title'],
'@component_title' => $component['title'],
)));
}
elseif (abs($element[$key]['#value']) > $component['range']) {
form_error($element[$key], t('@title: @component_title is out of bounds.', array(
'@title' => $element['#title'],
'@component_title' => $component['title'],
)));
}
}
if ($element[$key]['#value'] == '') {
$allFilled = FALSE;
}
else {
$anyFilled = TRUE;
}
}
if ($anyFilled && !$allFilled) {
foreach ($components as $key => $component) {
if ($element[$key]['#value'] == '') {
form_error($element[$key], t('@title: @component_title must be filled too.', array(
'@title' => $element['#title'],
'@component_title' => $component['title'],
)));
}
}
}
}
function geofield_bounds_element_process($element, &$form_values) {
$element['#tree'] = TRUE;
$element['top'] = array(
'#type' => 'textfield',
'#title' => t('Top'),
'#required' => !empty($element['#required']) ? $element['#required'] : FALSE,
'#default_value' => !empty($element['#default_value']['top']) ? $element['#default_value']['top'] : '',
'#attributes' => array(
'class' => array(
'geofield-top',
),
),
);
$element['right'] = array(
'#type' => 'textfield',
'#title' => t('Right'),
'#required' => !empty($element['#required']) ? $element['#required'] : FALSE,
'#default_value' => !empty($element['#default_value']['right']) ? $element['#default_value']['right'] : '',
'#attributes' => array(
'class' => array(
'geofield-right',
),
),
);
$element['bottom'] = array(
'#type' => 'textfield',
'#title' => t('Bottom'),
'#required' => !empty($element['#required']) ? $element['#required'] : FALSE,
'#default_value' => !empty($element['#default_value']['bottom']) ? $element['#default_value']['bottom'] : '',
'#attributes' => array(
'class' => array(
'geofield-bottom',
),
),
);
$element['left'] = array(
'#type' => 'textfield',
'#title' => t('Left'),
'#required' => !empty($element['#required']) ? $element['#required'] : FALSE,
'#default_value' => !empty($element['#default_value']['left']) ? $element['#default_value']['left'] : '',
'#attributes' => array(
'class' => array(
'geofield-left',
),
),
);
unset($element['#value']);
$element['#required'] = FALSE;
return $element;
}
function geofield_bounds_element_validate($element, &$form_values) {
$components = array(
'top' => array(
'title' => 'Top',
'range' => 90,
),
'right' => array(
'title' => 'Right',
'range' => 180,
),
'bottom' => array(
'title' => 'Bottom',
'range' => 90,
),
'left' => array(
'title' => 'Left',
'range' => 180,
),
);
$allFilled = TRUE;
$anyFilled = FALSE;
foreach ($components as $key => $component) {
if (!empty($element[$key]['#value'])) {
if (!is_numeric($element[$key]['#value'])) {
form_error($element[$key], t('@title: @component_title is not numeric.', array(
'@title' => $element['#title'],
'@component_title' => $component['title'],
)));
}
elseif (abs($element[$key]['#value']) > $component['range']) {
form_error($element[$key], t('@title: @component_title is out of bounds.', array(
'@title' => $element['#title'],
'@component_title' => $component['title'],
)));
}
}
if ($element[$key]['#value'] == '') {
$allFilled = FALSE;
}
else {
$anyFilled = TRUE;
}
}
if ($anyFilled && !$allFilled) {
foreach ($components as $key => $component) {
if ($element[$key]['#value'] == '') {
form_error($element[$key], t('@title: @component_title must be filled too.', array(
'@title' => $element['#title'],
'@component_title' => $component['title'],
)));
}
}
}
}
function geofield_proximity_element_process($element, &$form_state, $form) {
$element['#attributes'] = array(
'class' => array(
'clearfix',
),
);
$element['#tree'] = TRUE;
$element['#attached']['css'] = array(
drupal_get_path('module', 'geofield') . '/css/proximity-element.css',
);
$element['distance'] = array(
'#type' => 'textfield',
'#title' => t('Distance'),
'#default_value' => !empty($element['#default_value']['distance']) ? $element['#default_value']['distance'] : '',
'#title_display' => 'invisible',
'#element_validate' => array(
'element_validate_number',
),
);
if (!empty($element['#geofield_range']) && $element['#geofield_range'] == TRUE) {
$element['distance2'] = array(
'#type' => 'textfield',
'#title' => t('Distance End'),
'#default_value' => !empty($element['#default_value']['distance2']) ? $element['#default_value']['distance2'] : '',
'#title_display' => 'invisible',
'#element_validate' => array(
'element_validate_number',
),
);
}
$element['unit'] = array(
'#type' => 'select',
'#options' => geofield_radius_options(),
'#title' => t('Unit'),
'#default_value' => !empty($element['#default_value']['unit']) ? $element['#default_value']['unit'] : GEOFIELD_KILOMETERS,
'#title_display' => 'invisible',
);
$element['origin'] = array(
'#type' => !empty($element['#origin_element']) ? $element['#origin_element'] : 'textfield',
'#title' => t('Origin'),
'#prefix' => '<span class="geofield-proximity-origin-from">' . t('from') . '</span>',
'#title_display' => 'invisible',
'#required' => !empty($element['#required']) ? $element['#required'] : FALSE,
'#default_value' => !empty($element['#default_value']['origin']) ? $element['#default_value']['origin'] : FALSE,
);
if (!empty($element['#origin_options'])) {
$element['origin'] = array_merge($element['origin'], $element['#origin_options']);
}
if (isset($element['#element_validate'])) {
array_push($element['#element_validate'], 'geofield_proximity_search_validate');
}
else {
$element['#element_validate'] = array(
'geofield_proximity_search_validate',
);
}
return $element;
}
function geofield_proximity_search_validate($element, &$form_state) {
if (!empty($element['origin']['#value']) && trim($element['origin']['#value']) != '' && empty($element['distance']['#value'])) {
form_set_error(implode('][', $element['#array_parents']) . '][distance', t('@title must be set when @origin is specified.', array(
'@title' => $element['distance']['#title'],
'@origin' => $element['origin']['#title'],
)));
}
}
function geofield_theme($existing, $type, $theme, $path) {
return array(
'geofield_latlon' => array(
'arguments' => array(
'element' => NULL,
),
'render element' => 'element',
),
'geofield_proximity' => array(
'render element' => 'element',
),
);
}
function theme_geofield_proximity($vars) {
$element = $vars['element'];
$attributes = !empty($element['#wrapper_attributes']) ? $element['#wrapper_attributes'] : array(
'class' => array(),
);
$attributes['class'][] = 'geofield-proximity-field-wrapper';
$attributes['class'][] = 'clearfix';
$wrapper_attributes = array();
$wrapper_attributes['class'][] = 'clearfix';
if (isset($element['#children'])) {
$element['#children'] = '<div id="' . $element['#id'] . '" ' . drupal_attributes($wrapper_attributes) . '>' . $element['#children'] . '</div>';
}
$output = '<div ' . drupal_attributes($attributes) . '>' . theme('form_element', $element) . '</div>';
return $output;
}
function theme_geofield_latlon($vars) {
return drupal_render($vars['element']['lat']) . drupal_render($vars['element']['lon']) . drupal_render($vars['element']['geocode']);
}
function geofield_radius_options() {
return array(
GEOFIELD_KILOMETERS => t('Kilometers'),
GEOFIELD_METERS => t('Meters'),
GEOFIELD_MILES => t('Miles'),
GEOFIELD_YARDS => t('Yards'),
GEOFIELD_FEET => t('Feet'),
GEOFIELD_NAUTICAL_MILES => t('Nautical Miles'),
);
}