View source
<?php
define('LOCATION_PATH', drupal_get_path('module', 'location'));
define('LOCATION_LATLON_UNDEFINED', 0);
define('LOCATION_LATLON_USER_SUBMITTED', 1);
define('LOCATION_LATLON_GEOCODED_APPROX', 2);
define('LOCATION_LATLON_GEOCODED_EXACT', 3);
define('LOCATION_LATLON_JIT_GEOCODING', 4);
define('LOCATION_USER_DONT_COLLECT', 0);
define('LOCATION_USER_COLLECT', 1);
include_once LOCATION_PATH . '/location.inc';
function location_menu() {
$items = array();
$items['location/autocomplete'] = array(
'access arguments' => array(
'access content',
),
'page callback' => '_location_autocomplete',
'type' => MENU_CALLBACK,
);
$items['admin/config/content/location'] = array(
'title' => 'Location',
'description' => 'Settings for Location module',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'location_admin_settings',
),
'file' => 'location.admin.inc',
'access arguments' => array(
'administer site configuration',
),
'type' => MENU_NORMAL_ITEM,
);
$items['admin/config/content/location/general'] = array(
'title' => 'General settings',
'description' => 'TEST',
'type' => MENU_DEFAULT_LOCAL_TASK,
);
$items['admin/config/content/location/bundle'] = array(
'title' => 'Bundles',
'description' => 'Configure bundles for working with locations.',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'location_overview_bundles',
),
'file' => 'location.admin.inc',
'access arguments' => array(
'admininster site configuration',
),
'type' => MENU_LOCAL_TASK,
);
$items['admin/config/content/location/bundle/%location_bundle'] = array(
'title' => 'Bundle overview',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'location_unimplemented_form',
4,
),
'access arguments' => array(
'administer site configuration',
),
'type' => MENU_NORMAL_ITEM,
);
$items['admin/config/content/location/bundle/%location_bundle/edit'] = array(
'title' => 'Edit',
'type' => MENU_DEFAULT_LOCAL_TASK,
);
$items['admin/config/content/location/bundle/%location_bundle/delete'] = array(
'title' => 'Bundle overview',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'location_unimplemented_form',
4,
),
'access arguments' => array(
'administer site configuration',
),
'type' => MENU_CALLBACK,
);
$items['admin/config/content/location/maplinking'] = array(
'title' => 'Map links',
'description' => 'Configure generation of links to external mapping sites.',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'location_map_link_options_form',
),
'access arguments' => array(
'administer site configuration',
),
'file' => 'location.admin.inc',
'type' => MENU_LOCAL_TASK,
'weight' => 1,
);
$items['admin/config/content/location/geocoding'] = array(
'title' => 'Geocoding options',
'description' => 'Configure how Location geocodes addresses.',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'location_geocoding_options_form',
),
'access arguments' => array(
'administer site configuration',
),
'file' => 'location.admin.inc',
'type' => MENU_LOCAL_TASK,
'weight' => 2,
);
$items['admin/config/content/location/geocoding/%/%'] = array(
'page callback' => 'location_geocoding_parameters_page',
'page arguments' => array(
4,
5,
),
'access arguments' => array(
'administer site configuration',
),
'type' => MENU_CALLBACK,
);
$items['admin/config/content/location/util'] = array(
'title' => 'Location utilities',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'location_util_form',
),
'access arguments' => array(
'administer site configuration',
),
'file' => 'location.admin.inc',
'type' => MENU_LOCAL_TASK,
'weight' => 3,
);
return $items;
}
function location_api_variant() {
return 2;
}
function location_permission() {
return array(
'submit latitude/longitude' => array(
'title' => t('Submit Latitude / Longitude'),
'description' => t('Allow the user to submit raw coordinates.'),
),
'view location directory' => array(
'title' => t('View location directory'),
'description' => t('Allow the user to view the location directory view.'),
),
'view node location table' => array(
'title' => t('View node location table'),
'description' => t('Allow the user to view the node location table view.'),
),
'view user location table' => array(
'title' => t('View user location table'),
'description' => t('Allow the user to view the user location table view.'),
),
);
}
function location_help($path, $arg) {
switch ($path) {
case 'admin/help#location':
$output = '<p>' . t('The location module allows you to associate a geographic location with content and users. Users can do proximity searches by postal code. This is useful for organizing communities that have a geographic presence.') . '</p>';
$output .= '<p>' . t('To administer locative information for content, use the content type administration page. To support most location enabled features, you will need to install the country specific include file. To support postal code proximity searches for a particular country, you will need a database dump of postal code data for that country. As of June 2007 only U.S. and German postal codes are supported.') . '</p>';
$output .= t('<p>You can</p>
<ul>
<li>administer locative information at <a href="@admin-node-configure-types">Administer >> Content management >> Content types</a> to configure a type and see the locative information.</li>
<li>administer location at <a href="@admin-settings-location">Administer >> Site configuration >> Location</a>.</li>
<li>use a database dump for a U.S. and/or German postal codes table that can be found at <a href="@external-http-cvs-drupal-org">zipcode database</a>.</li>
', array(
'@admin-node-configure-types' => url('admin/content/types'),
'@admin-settings-location' => url('admin/settings/location'),
'@external-http-cvs-drupal-org' => 'http://cvs.drupal.org/viewcvs/drupal/contributions/modules/location/database/',
)) . '</ul>';
$output .= '<p>' . t('For more information please read the configuration and customization handbook <a href="@location">Location page</a>.', array(
'@location' => 'http://www.drupal.org/handbook/modules/location/',
)) . '</p>';
return $output;
}
}
function location_element_info() {
return array(
'location_element' => array(
'#input' => TRUE,
'#process' => array(
'_location_expand_location',
),
'#tree' => TRUE,
'#location_settings' => array(),
'#required' => FALSE,
'#attributes' => array(
'class' => array(
'location',
),
),
'#element_validate' => array(
'location_element_validate',
),
'#theme' => 'theme_fieldset',
),
'location_settings' => array(
'#input' => TRUE,
'#process' => array(
'_location_expand_location_settings',
),
'#collapsible' => TRUE,
'#collapsed' => TRUE,
'#tree' => TRUE,
'#theme' => 'location_settings',
),
);
}
function location_theme() {
return array(
'location_settings' => array(
'render element' => 'element',
),
'locations' => array(
'template' => 'locations',
'variables' => array(
'locations' => NULL,
'hide' => array(),
),
),
'location' => array(
'template' => 'location',
'variables' => array(
'location' => NULL,
'hide' => array(),
),
),
'location_latitude_dms' => array(
'variables' => array(
'latitude',
),
),
'location_longitude_dms' => array(
'variables' => array(
'longitude',
),
),
'location_map_link_options' => array(
'render element' => 'form',
),
'location_geocoding_options' => array(
'render element' => 'form',
),
'location_element' => array(
'arguments' => array(
'element',
),
),
'location_distance' => array(
'template' => 'location_distance',
'arguments' => array(
'distance' => 0,
'units' => 'km',
),
),
'location_bundle_overview' => array(
'variables' => array(
'name' => NULL,
'bundle' => NULL,
),
),
);
}
function location_views_api() {
return array(
'api' => 3,
);
}
function location_ctools_plugin_directory($module, $plugin) {
if ($module == 'ctools' && !empty($plugin)) {
return 'plugins/' . $plugin;
}
}
function _location_expand_location($element) {
drupal_add_css(drupal_get_path('module', 'location') . '/location.css');
$element['#tree'] = TRUE;
if (!isset($element['#title'])) {
$element['#title'] = t('Location');
}
if (empty($element['#location_settings'])) {
$element['#location_settings'] = array();
}
if (!isset($element['#default_value']) || $element['#default_value'] == 0) {
$element['#default_value'] = array();
}
$element['location_settings'] = array(
'#type' => 'value',
'#value' => $element['#location_settings'],
);
unset($element['#location_settings']);
$settings =& $element['location_settings']['#value'];
if (isset($element['#default_value']['lid']) && $element['#default_value']['lid']) {
$element['lid'] = array(
'#type' => 'value',
'#value' => $element['#default_value']['lid'],
);
}
location_normalize_settings($settings, $element['#required']);
$defaults = location_empty_location($settings);
if (isset($element['lid']['#value']) && $element['lid']['#value']) {
$defaults = location_load_location($element['lid']['#value']);
}
$fsettings =& $settings['form']['fields'];
$fdefaults = $defaults;
foreach ($element['#default_value'] as $k => $v) {
$fdefaults[$k] = $v;
}
$fields = location_field_names();
foreach ($fields as $field => $title) {
if (!isset($element[$field])) {
if ($fsettings[$field]['collect'] != 0) {
$element[$field] = location_invoke_locationapi($fdefaults[$field], 'field_expand', $field, $fsettings[$field]['collect'], $fdefaults);
$element[$field]['#weight'] = (int) $fsettings[$field]['weight'];
}
}
}
if (!isset($element['street'])) {
unset($element['additional']);
}
if (user_access('submit latitude/longitude') && $fsettings['locpick']['collect']) {
$element['locpick'] = array(
'#weight' => $fsettings['locpick']['weight'],
);
if (location_has_coordinates($defaults, FALSE)) {
$element['locpick']['current'] = array(
'#type' => 'fieldset',
'#title' => t('Current coordinates'),
'#attributes' => array(
'class' => array(
'location-current-coordinates-fieldset',
),
),
);
$element['locpick']['current']['current_latitude'] = array(
'#type' => 'item',
'#title' => t('Latitude'),
'#markup' => $defaults['latitude'],
);
$element['locpick']['current']['current_longitude'] = array(
'#type' => 'item',
'#title' => t('Longitude'),
'#markup' => $defaults['longitude'],
);
$source = t('Unknown');
switch ($defaults['source']) {
case LOCATION_LATLON_USER_SUBMITTED:
$source = t('User-submitted');
break;
case LOCATION_LATLON_GEOCODED_APPROX:
$source = t('Geocoded (Postal code level)');
break;
case LOCATION_LATLON_GEOCODED_EXACT:
$source = t('Geocoded (Exact)');
}
$element['locpick']['current']['current_source'] = array(
'#type' => 'item',
'#title' => t('Source'),
'#markup' => $source,
);
}
$element['locpick']['user_latitude'] = array(
'#type' => 'textfield',
'#title' => t('Latitude'),
'#default_value' => isset($element['#default_value']['locpick']['user_latitude']) ? $element['#default_value']['locpick']['user_latitude'] : '',
'#size' => 16,
'#attributes' => array(
'class' => array(
'container-inline',
),
),
'#maxlength' => 20,
'#required' => $fsettings['locpick']['collect'] == 2,
);
$element['locpick']['user_longitude'] = array(
'#type' => 'textfield',
'#title' => t('Longitude'),
'#default_value' => isset($element['#default_value']['locpick']['user_longitude']) ? $element['#default_value']['locpick']['user_longitude'] : '',
'#size' => 16,
'#maxlength' => 20,
'#required' => $fsettings['locpick']['collect'] == 2,
);
$element['locpick']['instructions'] = array(
'#type' => 'markup',
'#weight' => 1,
'#prefix' => '<div class=\'description\'>',
'#markup' => '<br /><br />' . t('If you wish to supply your own latitude and longitude, you may enter them above. If you leave these fields blank, the system will attempt to determine a latitude and longitude for you from the entered address. To have the system recalculate your location from the address, for example if you change the address, delete the values for these fields.'),
'#suffix' => '</div>',
);
if (function_exists('gmap_get_auto_mapid') && variable_get('location_usegmap', FALSE)) {
$mapid = gmap_get_auto_mapid();
$map = array_merge(gmap_defaults(), gmap_parse_macro(variable_get('location_locpick_macro', '[gmap]')));
$map['id'] = $mapid;
$map['points'] = array();
$map['pointsOverlays'] = array();
$map['lines'] = array();
$map['behavior']['locpick'] = TRUE;
$map['behavior']['collapsehack'] = TRUE;
if (location_has_coordinates($defaults, FALSE)) {
$map['latitude'] = (double) $defaults['latitude'];
$map['longitude'] = (double) $defaults['longitude'];
$map['markers'][] = array(
'latitude' => $defaults['latitude'],
'longitude' => $defaults['longitude'],
'markername' => 'small gray',
'offset' => 0,
'opts' => array(
'clickable' => FALSE,
),
);
}
$element['locpick']['user_latitude']['#map'] = $mapid;
gmap_widget_setup($element['locpick']['user_latitude'], 'locpick_latitude');
$element['locpick']['user_longitude']['#map'] = $mapid;
gmap_widget_setup($element['locpick']['user_longitude'], 'locpick_longitude');
$element['locpick']['map'] = array(
'#type' => 'gmap',
'#weight' => -1,
'#gmap_settings' => $map,
);
$element['locpick']['map_instructions'] = array(
'#type' => 'markup',
'#weight' => 2,
'#prefix' => '<div class=\'description\'>',
'#markup' => t('You may set the location by clicking on the map, or dragging the location marker. To clear the location and cause it to be recalculated, click on the marker.'),
'#suffix' => '</div>',
);
}
}
if (isset($defaults['lid']) && !empty($defaults['lid'])) {
$element['delete_location'] = array(
'#type' => 'checkbox',
'#title' => t('Delete'),
'#default_value' => isset($fdefaults['delete_location']) ? $fdefaults['delete_location'] : FALSE,
'#description' => t('Check this box to delete this location.'),
);
}
$element += element_info('fieldset');
drupal_alter('location_element', $element);
return $element;
}
function _location_expand_location_settings($element) {
$element['#tree'] = TRUE;
$element['#theme'] = 'location_settings';
if (!isset($element['#title'])) {
$element['#title'] = t('Location Fields');
}
if (!isset($element['#default_value']) || $element['#default_value'] == 0) {
$element['#default_value'] = array();
}
$element['#tree'] = TRUE;
$defaults = $element['#default_value'];
if (!isset($defaults) || !is_array($defaults)) {
$defaults = array();
}
$temp = location_invoke_locationapi($element, 'defaults');
foreach ($temp as $k => $v) {
if (!isset($defaults[$k])) {
$defaults[$k] = array();
}
$defaults[$k] = array_merge($v, $defaults[$k]);
}
$fields = location_field_names();
$options = array(
0 => t('Do not collect'),
1 => t('Allow'),
2 => t('Require'),
4 => t('Force Default'),
);
foreach ($fields as $field => $title) {
$element[$field] = array(
'#type' => 'fieldset',
'#tree' => TRUE,
);
$element[$field]['name'] = array(
'#type' => 'item',
'#markup' => $title,
);
$element[$field]['collect'] = array(
'#type' => 'select',
'#default_value' => $defaults[$field]['collect'],
'#options' => $options,
);
$temp = $defaults[$field]['default'];
$element[$field]['default'] = location_invoke_locationapi($temp, 'field_expand', $field, 1, $defaults);
$defaults[$field]['default'] = $temp;
$element[$field]['weight'] = array(
'#type' => 'weight',
'#delta' => 100,
'#default_value' => $defaults[$field]['weight'],
);
}
return $element;
}
function theme_location_settings($variables) {
$element = $variables['element'];
$rows = array();
$header = array(
array(
'data' => t('Name'),
'colspan' => 2,
),
t('Collect'),
t('Default'),
t('Weight'),
);
$element['country']['default']['#required'] = TRUE;
unset($element['country']['collect']['#options'][0]);
foreach (element_children($element) as $key) {
$element[$key]['weight']['#attributes']['class'] = array(
'location-settings-weight',
);
unset($element[$key]['default']['#title']);
$row = array();
$row[] = array(
'data' => '',
'class' => array(
'location-settings-drag',
),
);
$row[] = drupal_render($element[$key]['name']);
$row[] = drupal_render($element[$key]['collect']);
$row[] = drupal_render($element[$key]['default']);
$row[] = array(
'data' => drupal_render($element[$key]['weight']),
'class' => array(
'delta-order',
),
);
$rows[] = array(
'#weight' => (int) $element[$key]['weight']['#value'],
'data' => $row,
'class' => array(
'draggable',
),
);
}
uasort($rows, 'element_sort');
foreach ($rows as $k => $v) {
unset($rows[$k]['#weight']);
}
drupal_add_tabledrag('location-settings-table', 'order', 'sibling', 'location-settings-weight');
$output = theme('table', array(
'header' => $header,
'rows' => $rows,
'attributes' => array(
'id' => 'location-settings-table',
),
));
return $output;
}
function location_field_names($all = FALSE) {
static $fields;
static $allfields;
if ($all) {
if (empty($allfields)) {
$dummy = array();
$allfields = location_invoke_locationapi($dummy, 'fields');
$virtual = location_invoke_locationapi($dummy, 'virtual fields');
$allfields += $virtual;
}
return $allfields;
}
else {
if (empty($fields)) {
$dummy = array();
$fields = location_invoke_locationapi($dummy, 'fields');
}
return $fields;
}
}
function location_locationapi(&$obj, $op, $a3 = NULL, $a4 = NULL, $a5 = NULL) {
switch ($op) {
case 'fields':
return array(
'name' => t('Location name'),
'street' => t('Street location'),
'additional' => t('Additional'),
'city' => t('City'),
'province' => t('State/Province'),
'postal_code' => t('Postal code'),
'country' => t('Country'),
'locpick' => t('Coordinate Chooser'),
);
case 'virtual fields':
return array(
'province_name' => t('Province name'),
'country_name' => t('Country name'),
'map_link' => t('Map link'),
'coords' => t('Coordinates'),
);
case 'defaults':
return array(
'lid' => array(
'default' => FALSE,
),
'name' => array(
'default' => '',
'collect' => 1,
'weight' => 2,
),
'street' => array(
'default' => '',
'collect' => 1,
'weight' => 4,
),
'additional' => array(
'default' => '',
'collect' => 1,
'weight' => 6,
),
'city' => array(
'default' => '',
'collect' => 0,
'weight' => 8,
),
'province' => array(
'default' => '',
'collect' => 0,
'weight' => 10,
),
'postal_code' => array(
'default' => '',
'collect' => 0,
'weight' => 12,
),
'country' => array(
'default' => variable_get('site_default_country', 'us'),
'collect' => 1,
'weight' => 14,
),
'locpick' => array(
'default' => FALSE,
'collect' => 1,
'weight' => 20,
'nodiff' => TRUE,
),
'latitude' => array(
'default' => 0,
),
'longitude' => array(
'default' => 0,
),
'source' => array(
'default' => LOCATION_LATLON_UNDEFINED,
),
'is_primary' => array(
'default' => 0,
),
'delete_location' => array(
'default' => FALSE,
'nodiff' => TRUE,
),
);
case 'validate':
if (!empty($obj['country'])) {
if (!empty($obj['province'])) {
$provinces = location_get_provinces($obj['country']);
$found = FALSE;
$p = strtoupper($obj['province']);
foreach ($provinces as $k => $v) {
if ($p == strtoupper($k) || $p == strtoupper($v)) {
$found = TRUE;
break;
}
}
if (!$found) {
form_error($a3['province'], t('The specified province was not found in the specified country.'));
}
}
}
if (!empty($obj['locpick']) && is_array($obj['locpick'])) {
if (_location_floats_are_equal($obj['locpick']['user_latitude'], 0) xor _location_floats_are_equal($obj['locpick']['user_longitude'], 0)) {
$ref =& $a3['locpick']['user_latitude'];
if (_location_floats_are_equal($obj['locpick']['user_longitude'], 0)) {
$ref =& $a3['locpick']['user_longitude'];
}
form_error($ref, t('You must fill out both latitude and longitude or you must leave them both blank.'));
}
}
break;
case 'field_expand':
switch ($a3) {
case 'name':
return array(
'#type' => 'textfield',
'#title' => t('Location name'),
'#default_value' => $obj,
'#size' => 64,
'#maxlength' => 255,
'#description' => t('e.g. a place of business, venue, meeting point'),
'#attributes' => NULL,
'#required' => $a4 == 2,
);
case 'street':
return array(
'#type' => 'textfield',
'#title' => t('Street'),
'#default_value' => $obj,
'#size' => 64,
'#maxlength' => 255,
'#required' => $a4 == 2,
);
case 'additional':
return array(
'#type' => 'textfield',
'#title' => t('Additional'),
'#default_value' => $obj,
'#size' => 64,
'#maxlength' => 255,
);
case 'city':
return array(
'#type' => 'textfield',
'#title' => t('City'),
'#default_value' => $obj,
'#size' => 64,
'#maxlength' => 255,
'#description' => NULL,
'#attributes' => NULL,
'#required' => $a4 == 2,
);
case 'province':
drupal_add_js(drupal_get_path('module', 'location') . '/location_autocomplete.js');
if (isset($a5['country']) && is_string($a5['country'])) {
$country = $a5['country'];
}
elseif (isset($a5['country']['default']) && is_string($a5['country']['default'])) {
$country = $a5['country']['default'];
}
else {
$country = variable_get('site_default_country', 'us');
}
return array(
'#type' => 'textfield',
'#title' => t('State/Province'),
'#autocomplete_path' => 'location/autocomplete/' . $country,
'#default_value' => variable_get('location_use_province_abbreviation', 1) ? $obj : location_province_name($country, $obj),
'#size' => 64,
'#maxlength' => 64,
'#description' => NULL,
'#attributes' => array(
'class' => array(
'location_auto_province',
),
),
'#required' => $a4 == 2,
);
case 'country':
if ($a4 == 4) {
return array(
'#type' => 'value',
'#value' => $obj,
);
}
else {
$options = array_merge(array(
'' => t('Please select'),
'xx' => t('NOT LISTED'),
), location_get_iso3166_list());
return array(
'#type' => 'select',
'#title' => t('Country'),
'#default_value' => $obj,
'#options' => $options,
'#description' => NULL,
'#required' => $a4 == 2,
'#attributes' => array(
'class' => array(
'location_auto_country',
),
),
);
}
break;
case 'postal_code':
return array(
'#type' => 'textfield',
'#title' => t('Postal code'),
'#default_value' => $obj,
'#size' => 16,
'#maxlength' => 16,
'#required' => $a4 == 2,
);
}
break;
case 'isunchanged':
switch ($a3) {
case 'lid':
if (empty($obj[$a3]) && empty($a4)) {
return TRUE;
}
break;
case 'latitude':
case 'longitude':
if (_location_floats_are_equal($obj[$a3], $a4)) {
return TRUE;
}
break;
case 'country':
if (trim($obj[$a3]) == trim($a4)) {
return TRUE;
}
break;
case 'province_name':
case 'country_name':
case 'map_link':
case 'coords':
case 'locpick':
case 'delete_location':
return TRUE;
}
break;
}
}
function location_geocoding_parameters_page($country_iso, $service) {
drupal_set_title(t('Configure parameters for %service geocoding', array(
'%service' => $service,
)), PASS_THROUGH);
$breadcrumbs = drupal_get_breadcrumb();
$breadcrumbs[] = l('location', 'admin/settings/location');
$breadcrumbs[] = l('geocoding', 'admin/settings/location/geocoding');
$countries = location_get_iso3166_list();
$breadcrumbs[] = l($countries[$country_iso], 'admin/settings/location/geocoding', array(
'fragment' => $country_iso,
));
drupal_set_breadcrumb($breadcrumbs);
return drupal_get_form('location_geocoding_parameters_form', $country_iso, $service);
}
function location_geocoding_parameters_form(&$form_state, $country_iso, $service) {
location_load_country($country_iso);
$geocode_settings_form_function_specific = 'location_geocode_' . $country_iso . '_' . $service . '_settings';
$geocode_settings_form_function_general = $service . '_geocode_settings';
if (function_exists($geocode_settings_form_function_specific)) {
return system_settings_form($geocode_settings_form_function_specific());
}
location_load_geocoder($service);
if (function_exists($geocode_settings_form_function_general)) {
return system_settings_form($geocode_settings_form_function_general());
}
else {
return system_settings_form(array(
'#type' => 'markup',
'#markup' => t('No configuration parameters are necessary, or a form to take such paramters has not been implemented.'),
));
}
}
function location_load_locations($id, $key = 'vid') {
if (empty($id)) {
return array();
}
$query = db_select('location_instance', 'l');
$lid_field = $query
->addField('l', 'lid');
$query
->condition($key, $id);
$result = $query
->execute();
$locations = array();
foreach ($result as $lid) {
$locations[] = location_load_location($lid->{$lid_field});
}
return $locations;
}
function location_save_locations(&$locations, $criteria) {
if (isset($locations) && is_array($locations) && !empty($criteria) && is_array($criteria)) {
foreach (array_keys($locations) as $key) {
location_save($locations[$key], TRUE, $criteria);
}
$query = db_select('location_instance', 'l');
$lid_field = $query
->addField('l', 'lid');
foreach ($criteria as $key => $value) {
$query
->condition($key, $value);
}
$oldlids = $query
->execute()
->fetchCol();
$query = db_delete('location_instance');
foreach ($criteria as $key => $value) {
$query
->condition($key, $value);
}
$query
->execute();
$newlids = array();
$query = db_insert('location_instance')
->fields(array(
'nid',
'vid',
'uid',
'genid',
'lid',
));
foreach ($locations as $location) {
if ($location['lid'] !== FALSE) {
$newlids[] = $location['lid'];
$instance = array(
'nid' => 0,
'vid' => 0,
'uid' => 0,
'genid' => '',
'lid' => $location['lid'],
);
foreach ($criteria as $k => $v) {
$instance[$k] = $v;
}
$query
->values($instance);
}
}
$query
->execute();
foreach (array_diff($oldlids, $newlids) as $check) {
$count = db_query('SELECT COUNT(*) FROM {location_instance} WHERE lid = :lid', array(
':lid' => $check,
))
->fetchField();
if ($count !== FALSE && $count == 0) {
watchdog('location', 'Deleting unreferenced location with LID %lid.', array(
'%lid' => $check,
));
$location = array(
'lid' => $check,
);
location_invoke_locationapi($location, 'delete');
db_delete('location')
->condition('lid', $location['lid'])
->execute();
}
}
}
}
function location_load_location($lid) {
$location = db_query('SELECT * FROM {location} WHERE lid = :lid', array(
':lid' => $lid,
))
->fetchAssoc();
if (empty($location)) {
$location = array(
'lid' => $lid,
);
}
if (isset($location['source']) && $location['source'] == LOCATION_LATLON_USER_SUBMITTED) {
$location['locpick'] = array(
'user_latitude' => $location['latitude'],
'user_longitude' => $location['longitude'],
);
}
if (isset($location['source']) && $location['source'] == LOCATION_LATLON_JIT_GEOCODING) {
if (variable_get('location_jit_geocoding', FALSE)) {
_location_geo_logic($location, array(
'street' => 1,
), array());
db_update('location')
->fields(array(
'latitude',
'longitude',
'source',
))
->values($location)
->condition('lid', $location['lid'])
->execute();
}
}
$location['province_name'] = '';
$location['country_name'] = '';
if (!empty($location['country'])) {
$location['country_name'] = location_country_name($location['country']);
if (!empty($location['province'])) {
$location['province_name'] = location_province_name($location['country'], $location['province']);
}
}
$location = array_merge($location, location_invoke_locationapi($location, 'load', $lid));
return $location;
}
function _location_autocomplete($country, $string = '') {
$counter = 0;
$string = strtolower($string);
$string = '/^' . preg_quote($string) . '/';
$matches = array();
if (strpos($country, ',') !== FALSE) {
$provinces = array();
$country = explode(',', $country);
foreach ($country as $c) {
$provinces = $provinces + location_get_provinces($c);
}
}
else {
$provinces = location_get_provinces($country);
}
if (!empty($provinces)) {
while (list($code, $name) = each($provinces)) {
if ($counter < 5) {
if (preg_match($string, strtolower($name))) {
$matches[$name] = $name;
++$counter;
}
}
}
}
drupal_json_output($matches);
}
function _location_floats_are_equal($x, $y) {
$x = floatval($x);
$y = floatval($y);
return abs(max($x, $y) - min($x, $y)) < pow(10, -6);
}
function location_has_coordinates($location, $canonical = FALSE) {
if ($canonical) {
return $location['source'] != LOCATION_LATLON_UNDEFINED;
}
if (empty($location['latitude']) || empty($location['longitude'])) {
return FALSE;
}
if (_location_floats_are_equal($location['latitude'], 0.0) || _location_floats_are_equal($location['longitude'], 0.0)) {
return FALSE;
}
return TRUE;
}
function location_invoke_locationapi(&$location, $op, $a3 = NULL, $a4 = NULL, $a5 = NULL) {
$return = array();
foreach (module_implements('locationapi') as $name) {
$function = $name . '_locationapi';
$result = $function($location, $op, $a3, $a4, $a5);
if (isset($result) && is_array($result)) {
$return = array_merge($return, $result);
}
elseif (isset($result)) {
$return[] = $result;
}
}
return $return;
}
function _location_patch_locpick(&$location) {
$inhibit_geocode = FALSE;
if (!empty($location['locpick'])) {
$location['locpick']['user_latitude'] = trim($location['locpick']['user_latitude']);
$location['locpick']['user_longitude'] = trim($location['locpick']['user_longitude']);
}
if (!empty($location['locpick']['user_latitude']) && !empty($location['locpick']['user_longitude'])) {
$location['source'] = LOCATION_LATLON_USER_SUBMITTED;
$location['latitude'] = $location['locpick']['user_latitude'];
$location['longitude'] = $location['locpick']['user_longitude'];
$inhibit_geocode = TRUE;
}
return $inhibit_geocode;
}
function location_save(&$location, $cow = TRUE, $criteria = array()) {
if (!isset($location['location_settings'])) {
$location['location_settings'] = array();
}
location_normalize_settings($location['location_settings']);
$inhibit_geocode = FALSE;
if (isset($location['inhibit_geocode']) && $location['inhibit_geocode']) {
$inhibit_geocode = TRUE;
unset($location['inhibit_geocode']);
}
if (isset($location['delete_location']) && $location['delete_location']) {
$location['lid'] = FALSE;
return FALSE;
}
$oldloc = location_empty_location($location['location_settings']);
if (isset($location['lid']) && !empty($location['lid'])) {
$oldloc = (array) location_load_location($location['lid']);
}
if (_location_patch_locpick($location)) {
$inhibit_geocode = TRUE;
}
$location = array_merge($oldloc, $location);
$filled = array();
if (location_is_empty($location, $filled)) {
$location['lid'] = FALSE;
return FALSE;
}
$changed = array();
if (!location_calc_difference($oldloc, $location, $changed)) {
if (!empty($location['lid'])) {
return $location['lid'];
}
else {
$location['lid'] = FALSE;
return FALSE;
}
}
_location_geo_logic($location, $changed, $filled, $inhibit_geocode);
if ($cow) {
if (isset($location['lid']) && $location['lid']) {
if (!empty($criteria)) {
$query = db_select('location_instance', 'l');
foreach ($criteria as $key => $value) {
$query
->condition($key, $value);
}
$associated = $query
->countQuery()
->execute()
->fetchField();
$all = db_query("SELECT COUNT(*) FROM {location_instance} WHERE lid = :lid", array(
':lid' => $location['lid'],
))
->fetchField();
if ($associated != $all) {
unset($location['lid']);
}
}
else {
unset($location['lid']);
}
}
}
if (!empty($location['lid'])) {
watchdog('location', 'Conserving lid %lid due to uniqueness.', array(
'%lid' => $location['lid'],
));
$fields = array();
foreach (array(
'name',
'street',
'additional',
'city',
'province',
'postal_code',
'country',
'latitude',
'longitude',
'source',
) as $key) {
if (isset($location[$key])) {
$fields[$key] = $location[$key];
}
}
db_merge('location')
->key(array(
'lid' => $location['lid'],
))
->fields($fields)
->execute();
}
else {
unset($location['lid']);
drupal_write_record('location', $location);
}
location_invoke_locationapi($location, 'save');
return $location['lid'];
}
function location_calc_difference($oldloc, $newloc, &$changes) {
location_strip($oldloc);
location_strip($newloc);
$location_changed = FALSE;
foreach ($newloc as $k => $v) {
if (!isset($oldloc[$k])) {
$changes[$k] = TRUE;
$location_changed = TRUE;
continue;
}
elseif ($oldloc[$k] === $v) {
$changes[$k] = FALSE;
continue;
}
$results = location_invoke_locationapi($newloc, 'isunchanged', $k, $oldloc[$k]);
$waschanged = TRUE;
foreach ($results as $r) {
if ($r) {
$waschanged = FALSE;
$changes[$k] = FALSE;
}
}
if ($waschanged) {
$changes[$k] = TRUE;
$location_changed = TRUE;
}
}
if (!$location_changed) {
return FALSE;
}
return TRUE;
}
function location_is_empty($location, &$filled) {
if (empty($location)) {
return TRUE;
}
if (isset($location['delete_location']) && $location['delete_location']) {
return TRUE;
}
_location_patch_locpick($location);
$settings = isset($location['location_settings']) ? $location['location_settings'] : array();
$emptyloc = location_empty_location($settings);
return !location_calc_difference($emptyloc, $location, $filled);
}
function location_empty_location($settings) {
$location = array();
$defaults = location_invoke_locationapi($location, 'defaults');
if (isset($settings['form']['fields'])) {
foreach ($settings['form']['fields'] as $k => $v) {
if (isset($defaults[$k])) {
$defaults[$k] = array_merge($defaults[$k], $v);
}
}
}
foreach ($defaults as $k => $v) {
if (isset($v['default'])) {
$location[$k] = $v['default'];
}
}
return $location;
}
function location_strip(&$location) {
static $tmp;
if (!isset($tmp)) {
$tmp = array();
$defaults = location_invoke_locationapi($location, 'defaults');
foreach ($defaults as $k => $v) {
if (!isset($v['nodiff'])) {
$tmp[$k] = TRUE;
}
}
}
foreach ($location as $k => $v) {
if (!isset($tmp[$k])) {
unset($location[$k]);
}
}
}
function location_normalize_settings(&$settings, $required = TRUE) {
if (!isset($settings['form'])) {
$settings['form'] = array();
}
if (!isset($settings['form']['fields'])) {
$settings['form']['fields'] = array();
}
$dummy = array();
$ds = location_invoke_locationapi($dummy, 'defaults');
foreach ($ds as $k => $v) {
if (!isset($settings['form']['fields'][$k])) {
$settings['form']['fields'][$k] = array();
}
$settings['form']['fields'][$k] = array_merge($v, $settings['form']['fields'][$k]);
}
if (!$required) {
foreach ($settings['form']['fields'] as $k => $v) {
if (isset($v['collect'])) {
if ($v['collect'] == 2) {
$settings['form']['fields'][$k]['collect'] = 1;
}
}
}
}
}
function _location_geo_logic(&$location, $changed, $filled, $inhibit_geocode = FALSE) {
if (!$inhibit_geocode) {
if ($changed['street'] || $changed['additional'] || $changed['city'] || $changed['province'] || $changed['country'] || $changed['postal_code'] || $location['source'] == LOCATION_LATLON_USER_SUBMITTED) {
if ($data = location_latlon_exact($location)) {
$location['source'] = LOCATION_LATLON_GEOCODED_EXACT;
$location['latitude'] = $data['lat'];
$location['longitude'] = $data['lon'];
}
elseif ($data = location_get_postalcode_data($location)) {
$location['source'] = LOCATION_LATLON_GEOCODED_APPROX;
$location['latitude'] = $data['lat'];
$location['longitude'] = $data['lon'];
}
else {
$location['source'] = LOCATION_LATLON_UNDEFINED;
$location['latitude'] = 0;
$location['longitude'] = 0;
}
}
}
while ($location['latitude'] > 90) {
$location['latitude'] -= 180;
}
while ($location['latitude'] < -90) {
$location['latitude'] += 180;
}
while ($location['longitude'] > 180) {
$location['longitude'] -= 360;
}
while ($location['longitude'] < -180) {
$location['longitude'] += 360;
}
if (!empty($location['postal_code'])) {
if (empty($location['city']) || empty($location['province'])) {
if ($data = location_get_postalcode_data($location)) {
$location['city'] = $data['city'];
$location['province'] = $data['province'];
}
}
}
if (!empty($location['province']) && !empty($location['country'])) {
$location['province'] = location_province_code($location['country'], $location['province']);
}
}
function location_element_validate($element, &$form_state) {
location_invoke_locationapi($element['#value'], 'validate', $element);
}
function location_dd_to_dms($coord) {
$negative = $coord < 0 ? TRUE : FALSE;
$coord = abs($coord);
$degrees = floor($coord);
$coord -= $degrees;
$coord *= 60;
$minutes = floor($coord);
$coord -= $minutes;
$coord *= 60;
$seconds = round($coord, 6);
return array(
$degrees,
$minutes,
$seconds,
$negative,
);
}
function theme_location_latitude_dms($variables) {
$latitude = $variables['latitude'];
$output = '';
list($degrees, $minutes, $seconds, $negative) = location_dd_to_dms($latitude);
$output .= "{$degrees}° {$minutes}' {$seconds}\" ";
if (!$negative) {
$output .= 'N';
}
else {
$output .= 'S';
}
return $output;
}
function theme_location_longitude_dms($variables) {
$longitude = $variables['longitude'];
$output = '';
list($degrees, $minutes, $seconds, $negative) = location_dd_to_dms($longitude);
$output .= "{$degrees}° {$minutes}' {$seconds}\" ";
if (!$negative) {
$output .= 'E';
}
else {
$output .= 'W';
}
return $output;
}
function location_token_values($type, $object = NULL) {
require_once drupal_get_path('module', 'location') . '/location.token.inc';
return _location_token_values($type, $object);
}
function location_token_list($type = 'all') {
require_once drupal_get_path('module', 'location') . '/location.token.inc';
return _location_token_list($type);
}
if (module_exists('location_search')) {
function location_search($op = 'search', $keys = NULL) {
return _location_search($op, $keys);
}
}
function template_preprocess_location(&$variables) {
$location = $variables['location'];
$location['map_link'] = TRUE;
if (is_array($variables['hide'])) {
foreach ($variables['hide'] as $key) {
unset($location[$key]);
if ($key == 'coords') {
unset($location['latitude']);
unset($location['longitude']);
}
}
}
$fields = location_field_names(TRUE);
if (is_array($fields)) {
foreach ($fields as $key => $value) {
$variables[$key] = '';
if (!empty($location[$key]) && !is_array($location[$key])) {
$variables[$key] = check_plain($location[$key]);
}
}
}
$variables['map_link'] = '';
if (!empty($location['map_link'])) {
$variables['map_link'] = location_map_link($variables['location']);
}
$variables['latitude'] = '';
$variables['latitude_dms'] = '';
if (!empty($location['latitude'])) {
$variables['latitude'] = check_plain($location['latitude']);
$variables['latitude_dms'] = theme('location_latitude_dms', array(
'latitude' => $location['latitude'],
));
}
$variables['longitude'] = '';
$variables['longitude_dms'] = '';
if (!empty($location['longitude'])) {
$variables['longitude'] = check_plain($location['longitude']);
$variables['longitude_dms'] = theme('location_longitude_dms', array(
'longitude' => $location['longitude'],
));
}
if (!empty($location['country']) && location_standardize_country_code($location['country'])) {
$variables['template_files'][] = 'location-' . $location['country'];
}
if (!isset($location['province'])) {
$location['province'] = '';
}
if (!isset($location['province_name'])) {
$location['province_name'] = '';
}
$variables['province_print'] = variable_get('location_use_province_abbreviation', 1) ? $location['province'] : $location['province_name'];
}
function template_preprocess_location_distance(&$variables) {
$units = $variables['units'];
unset($variables['units']);
if ($units == 'km') {
$variables['shortunit'] = 'km';
$variables['longunit'] = 'kilometer(s)';
}
if ($units == 'mi') {
$variables['shortunit'] = 'mi';
$variables['longunit'] = 'mile(s)';
}
$variables['distance'] = (double) $variables['distance'];
}
function template_preprocess_locations(&$variables) {
if (isset($variables['locations']) && is_array($variables['locations'])) {
$locs = $variables['locations'];
}
else {
$locs = array();
}
$variables['locations'] = array();
$variables['rawlocs'] = $locs;
foreach ($locs as $location) {
$variables['locations'][] = theme('location', array(
'location' => $location,
'hide' => $variables['hide'],
));
}
}
function location_settings($old = FALSE) {
if (empty($old)) {
$old = array();
}
$form = array(
'#type' => 'fieldset',
'#title' => t('Locative information'),
'#tree' => TRUE,
);
$form['multiple'] = array(
'#type' => 'fieldset',
'#title' => t('Number of locations'),
'#tree' => TRUE,
'#weight' => 2,
);
$form['multiple']['min'] = array(
'#type' => 'select',
'#title' => t('Minimum number of locations'),
'#options' => drupal_map_assoc(range(0, 100)),
'#default_value' => isset($old['multiple']['min']) ? $old['multiple']['min'] : 0,
'#description' => t('The number of locations that are required to be filled in.'),
);
$form['multiple']['max'] = array(
'#type' => 'select',
'#title' => t('Maximum number of locations'),
'#options' => drupal_map_assoc(range(0, 100)),
'#default_value' => isset($old['multiple']['max']) ? $old['multiple']['max'] : 1,
'#description' => t('The maximum number of locations that can be associated.'),
);
$form['multiple']['add'] = array(
'#type' => 'select',
'#title' => t('Number of locations that can be added at once'),
'#options' => drupal_map_assoc(range(0, 100)),
'#default_value' => isset($old['multiple']['add']) ? $old['multiple']['add'] : 1,
'#description' => t('The number of empty location forms to show when editing.'),
);
$form['form'] = array(
'#type' => 'fieldset',
'#title' => t('Collection settings'),
'#tree' => TRUE,
'#weight' => 4,
);
$form['form']['weight'] = array(
'#type' => 'weight',
'#title' => t('Location form weight'),
'#default_value' => isset($old['form']['weight']) ? $old['form']['weight'] : 0,
'#description' => t('Weight of the location box in the add / edit form. Lower values will be displayed higher in the form.'),
);
$form['form']['collapsible'] = array(
'#type' => 'checkbox',
'#title' => t('Collapsible'),
'#default_value' => isset($old['form']['collapsible']) ? $old['form']['collapsible'] : TRUE,
'#description' => t('Make the location box collapsible.'),
);
$form['form']['collapsed'] = array(
'#type' => 'checkbox',
'#title' => t('Collapsed'),
'#default_value' => isset($old['form']['collapsed']) ? $old['form']['collapsed'] : TRUE,
'#description' => t('Display the location box collapsed.'),
);
$form['form']['fields'] = array(
'#type' => 'location_settings',
'#default_value' => isset($old['form']['fields']) ? $old['form']['fields'] : array(),
);
$form['display'] = array(
'#type' => 'fieldset',
'#title' => t('Display Settings'),
'#tree' => TRUE,
'#weight' => 6,
);
$form['display']['weight'] = array(
'#type' => 'weight',
'#title' => t('Display Weight'),
'#default_value' => isset($old['display']['weight']) ? $old['display']['weight'] : 0,
);
$fields = location_field_names(TRUE);
$form['display']['hide'] = array(
'#type' => 'checkboxes',
'#title' => t('Hide fields from display'),
'#default_value' => isset($old['display']['hide']) ? $old['display']['hide'] : array(),
'#options' => $fields,
);
return $form;
}
function location_form($settings, $locations) {
if (!isset($settings['multiple']['max']) || $settings['multiple']['max'] == 0) {
return array();
}
$numloc = count($locations);
$numforms = min($numloc + $settings['multiple']['add'], $settings['multiple']['max']);
$form = array(
'#type' => 'fieldset',
'#title' => format_plural($numforms, 'Location', 'Locations'),
'#tree' => TRUE,
'#attributes' => array(
'class' => array(
'locations',
),
),
'#weight' => $settings['form']['weight'],
'#collapsible' => $settings['form']['collapsible'],
'#collapsed' => $settings['form']['collapsed'],
);
for ($i = 0; $i < $numforms; $i++) {
$required = FALSE;
if ($i < $settings['multiple']['min']) {
$required = TRUE;
}
$form[$i] = array(
'#type' => 'location_element',
'#title' => t('Location #%number', array(
'%number' => $i + 1,
)),
'#default_value' => isset($locations[$i]) ? $locations[$i] : NULL,
'#location_settings' => $settings,
'#required' => $required,
);
}
if ($numforms == 1) {
$form[0]['#title'] = t('Location');
$form[0]['#collapsible'] = $form['#collapsible'];
$form[0]['#collapsed'] = $form['#collapsed'];
}
return $form;
}
function location_display($settings, $locations) {
if (!isset($settings['display']['hide'])) {
return array();
}
$hide = array_keys(array_filter($settings['display']['hide']));
return array(
'#type' => 'markup',
'#markup' => theme('locations', array(
'locations' => $locations,
'hide' => $hide,
)),
'#weight' => $settings['display']['weight'],
);
}
function location_google_geocode_accuracy_codes() {
return array(
0 => t('Unknown location'),
1 => t('Country level accuracy'),
2 => t('Region (state, province, prefecture, etc.) level accuracy'),
3 => t('Sub-region (county, municipality, etc.) level accuracy'),
4 => t('Town (city, village) level accuracy'),
5 => t('Post code (zip code) level accuracy'),
6 => t('Street level accuracy'),
7 => t('Intersection level accuracy'),
8 => t('Address level accuracy'),
9 => t('Premise (building name, property name, shopping center, etc.) level accuracy'),
);
}
function location_entity_info() {
$return = array(
'location' => array(
'label' => t('Location'),
'base table' => 'location_locations',
'revision table' => 'location_location_revisions',
'path callback' => 'location_path',
'fieldable' => TRUE,
'object keys' => array(
'id' => 'lid',
'revision' => 'lvid',
'bundle' => 'bundle',
),
'bundle keys' => array(
'bundle' => 'bundle',
),
'bundles' => array(),
'view modes' => array(
'standalone' => array(
'label' => t('Standalone page'),
),
'rss' => array(
'label' => t('RSS'),
),
),
),
);
$result = db_query('SELECT * FROM {location_bundles}');
foreach ($result as $bundle) {
$return['location']['bundles'][$bundle->bundle] = array(
'label' => $bundle->name,
'admin' => array(
'path' => 'admin/config/location/bundle/%location_bundle',
'real path' => 'admin/config/location/bundle/' . str_replace('_', '-', $bundle->bundle),
'bundle argument' => 4,
'access arguments' => array(
'administer content types',
),
),
);
}
return $return;
}
function location_path($location) {
return 'location/' . $location->lid;
}
function location_bundle_load($arg) {
return db_query('SELECT * FROM {location_bundles} WHERE bundle = :bundle', array(
':bundle' => $arg,
))
->fetch();
}
function location_unimplemented_form($form, &$form_state, $arg = array()) {
$form['about'] = array(
'#type' => 'markup',
'#markup' => '<h1>TODO: implement this.</h1>',
);
$form['data'] = array(
'#type' => 'markup',
'#markup' => check_plain(print_r($arg, TRUE)),
);
return $form;
}