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_USER_DONT_COLLECT', 0);
define('LOCATION_USER_COLLECT', 1);
include_once LOCATION_PATH . '/location.inc';
include_once LOCATION_PATH . '/location.theme';
foreach (variable_get('location_general_geocoders_in_use', array()) as $geocoder) {
include_once LOCATION_PATH . '/geocoding/' . $geocoder . '.inc';
}
function location_menu($may_cache = FALSE) {
$items = array();
if ($may_cache) {
$items[] = array(
'path' => 'search/location',
'title' => t('By location'),
'callback' => 'location_search_view',
'access' => user_access('search content by location'),
'type' => MENU_LOCAL_TASK,
'weight' => 9,
);
$items[] = array(
'path' => 'admin/settings/location/main',
'title' => t('Main settings'),
'type' => MENU_DEFAULT_LOCAL_TASK,
);
$items[] = array(
'path' => 'admin/settings/location/maplinking',
'title' => t('Map links'),
'callback' => 'location_map_link_options_page',
'access' => user_access('administer site configuration'),
'type' => MENU_LOCAL_TASK,
'weight' => 1,
);
$items[] = array(
'path' => 'admin/settings/location/geocoding',
'title' => t('Geocoding options'),
'callback' => 'location_geocoding_options_page',
'access' => user_access('administer site configuration'),
'type' => MENU_LOCAL_TASK,
'weight' => 2,
);
$items[] = array(
'path' => 'admin/settings/location',
'title' => t('Location'),
'description' => t('Settings for Location module'),
'callback' => 'drupal_get_form',
'callback arguments' => array(
'location_admin_settings',
),
'access' => user_access('administer site configuration'),
'type' => MENU_NORMAL_ITEM,
);
}
return $items;
}
function location_perm() {
return array(
'search content by location',
'submit latitude/longitude',
);
}
function location_help($section) {
switch ($section) {
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_search_view() {
$location_params = array(
'postal_code' => $_GET['postal_code'],
'country' => $_GET['country'] ? $_GET['country'] : variable_get('location_default_country', 'us'),
);
$proximity_params = array(
'distance' => $_GET['distance'],
'unit' => $_GET['unit'],
);
$output .= drupal_get_form('location_search_form', $location_params, $proximity_params);
if ($_GET['postal_code'] && $_GET['country'] && $_GET['distance'] && $_GET['country']) {
$output .= location_search_results($location_params, $proximity_params);
}
return $output;
}
function location_search_form($location_params = array(), $proximity_params = array()) {
$form = array();
$location_search_distance_unit_setting = variable_get('location_search_distance_unit', 0);
$proximity_suppressed_values = $location_search_distaince_unit_setting ? array(
'unit' => $location_search_distance_unit_setting,
) : array();
$form['proximity'] = location_proximity_form($proximity_params, $proximity_suppressed_values);
$location_suppressed_values = variable_get('location_suppress_country', 0) ? array(
'country' => variable_get('location_default_country', 'us'),
) : array();
$form['location'] = location_form(array(
'postal_code',
'country',
), $location_params, array(
'postal_code',
'country',
), $location_suppressed_values, '', 'nearby_postalcodes_bylocation');
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Search'),
);
$form['#submit'] = array_merge($form['#submit'] ? $form['#submit'] : array(), array(
'location_search_form_submit' => array(),
));
return $form;
}
function location_search_form_validate($form_id, &$form_values) {
if (!$form_values['postal_code']) {
}
if (!$form_values['country']) {
}
}
function location_search_form_submit($form_id, &$form_values) {
return array(
'search/location',
'postal_code=' . $form_values['postal_code'] . '&country=' . $form_values['country'] . '&distance=' . $form_values['distance'] . '&unit=' . $form_values['unit'],
);
}
function location_search_results($location_params, $proximity_params) {
$start_time = microtime();
$latlon = location_latlon_rough($location_params);
if (!$latlon['lat'] || !$latlon['lon']) {
drupal_set_message(t('No search results; could not determine the location of the submitted postal code.'));
return '';
}
$distance_float = _location_convert_distance_to_meters($proximity_params['distance'], $proximity_params['unit']);
$latrange = earth_latitude_range($latlon['lon'], $latlon['lat'], $distance_float);
$lonrange = earth_longitude_range($latlon['lon'], $latlon['lat'], $distance_float);
$count_query = 'SELECT COUNT(n.nid) AS count FROM {node} n INNER JOIN {location} l ON n.vid = l.eid WHERE l.type =\'node\' AND l.latitude > %f AND l.latitude < %f AND l.longitude > %f AND l.longitude < %f AND ' . earth_distance_sql($latlon['lon'], $latlon['lat']) . ' < %f';
$query = 'SELECT n.nid, l.*, ' . earth_distance_sql($latlon['lon'], $latlon['lat'], 'l') . ' as distance FROM {node} n INNER JOIN {location} l ON n.vid = l.eid WHERE l.type =\'node\' AND l.latitude > %f AND l.latitude < %f AND l.longitude > %f AND l.longitude < %f AND ' . earth_distance_sql($latlon['lon'], $latlon['lat']) . ' < %f GROUP BY n.nid ORDER by distance';
$query_args = array(
$latrange[0],
$latrange[1],
$lonrange[0],
$lonrange[1],
$distance_float,
);
$pager_count_query = 'SELECT COUNT(DISTINCT nid) AS count FROM {node} n INNER JOIN {location} l ON n.vid = l.eid WHERE l.type =\'node\' AND l.latitude > ' . $latrange[0] . ' AND l.latitude < ' . $latrange[1] . ' AND l.longitude > ' . $lonrange[0] . ' AND l.longitude < ' . $lonrange[1] . ' AND ' . earth_distance_sql($latlon['lon'], $latlon['lat']) . ' < ' . $distance_float;
$pager_query = 'SELECT n.nid, n.vid, l.*, ' . earth_distance_sql($latlon['lon'], $latlon['lat'], 'l') . ' AS distance FROM {node} n INNER JOIN {location} l ON n.vid = l.eid WHERE l.type =\'node\' AND l.latitude > ' . $latrange[0] . ' AND l.latitude < ' . $latrange[1] . ' AND l.longitude > ' . $lonrange[0] . ' AND l.longitude < ' . $lonrange[1] . ' AND ' . earth_distance_sql($latlon['lon'], $latlon['lat']) . ' < ' . $distance_float . ' GROUP BY n.nid ORDER by distance';
$result = pager_query(db_rewrite_sql($query), 10, 0, db_rewrite_sql($count_query), $query_args);
$result_count = db_result(db_query(db_rewrite_sql($count_query), $query_args));
if (!$result_count) {
$output = theme('box', t('Your search yielded no results.'), '');
}
else {
$results_offset = isset($_GET['from']) ? $_GET['from'] : 0;
$page_count = db_num_rows($result);
$output = '<p>' . t('Displaying results %a - %b of %count for search on %c', array(
'%a' => $results_offset + 1,
'%b' => $results_offset + $page_count,
'%count' => $result_count,
'%c' => filter_xss($_GET['postal_code']),
)) . '</p>';
while ($row = db_fetch_object($result)) {
$extra = array();
unset($location_line);
if ($row->postal_code || $row->city) {
$location_line = t('Local to ');
if ($row->postal_code && $row->city) {
if ($row->postal_code) {
$location_line .= $row->postal_code;
}
if ($row->postal_code && $row->city) {
$location_line .= ' (' . $row->city;
$location_line .= $row->province ? ', ' . $row->province : '';
$location_line .= ')';
}
elseif ($row->city) {
$location_line .= $row->city . ($row->province ? ', ' . $row->province : '');
}
}
}
if ($location_line) {
$extra['location'] = $location_line;
}
if ($row->postal_code == $location_params['postal_code'] && $row->country == $location_params['country'] || $row->distance < 10) {
$extra['distance'] = t('Result is <strong>also from %postal_code</strong>', array(
'%postal_code' => $location_params['postal_code'],
));
}
else {
$adjusted_distance = round($row->distance / ($proximity_params['unit'] == 'km' ? 1000.0 : 1609.347), 1);
if ($adjusted_distance != 1) {
$distance_unit = $edit['distance_unit'] == 'km' ? t('km') : t('miles');
}
else {
$distance_unit = $edit['distance_unit'] == 'km' ? t('km') : t('mile');
}
$extra['distance'] = t('Approximately %distance %distanceunit from <strong>%location</strong> ', array(
'%distance' => round($adjusted_distance, 1),
'%distanceunit' => $distance_unit,
'%location' => $location_params['postal_code'],
));
}
$node = node_load($row->nid);
$output .= theme('search_item', array(
'link' => url('node/' . $row->nid),
'title' => $node->title,
'type' => $node->type,
'user' => db_result(db_query('SELECT name FROM {users} WHERE uid = %d', $node->uid)),
'date' => $node->created,
'snippet' => $row->teaser,
'extra' => $extra,
), 'node');
}
$output .= theme('pager');
}
return $output;
}
function location_map_link_options_page() {
return drupal_get_form('location_map_link_options_form');
}
function location_map_link_options_form() {
$form = array();
$form['countries'] = array(
'#type' => 'markup',
'#value' => '',
);
foreach (location_configured_countries() as $country_iso => $country_name) {
$form['countries'][$country_iso] = array(
'#type' => 'markup',
'#value' => '',
);
$form['countries'][$country_iso]['label_' . $country_iso] = array(
'#type' => 'markup',
'#value' => $country_name,
);
$mapping_options = array();
$provider_function = 'location_map_link_' . $country_iso . '_providers';
$default_provider_function = 'location_map_link_' . $country_iso . '_default_providers';
$checked = variable_get('location_map_link_' . $country_iso, function_exists($default_provider_function) ? $default_provider_function() : array());
if (function_exists($provider_function)) {
foreach ($provider_function() as $name => $details) {
$mapping_options[$name] = '<a href="' . $details['url'] . '">' . $details['name'] . '</a> (<a href="' . $details['tos'] . '">Terms of Use</a>)';
}
}
if (count($mapping_options)) {
$form['countries'][$country_iso]['location_map_link_' . $country_iso] = array(
'#title' => '',
'#type' => 'checkboxes',
'#default_value' => $checked,
'#options' => $mapping_options,
);
}
else {
$form['countries'][$country_iso]['location_map_link_' . $country_iso] = array(
'#type' => 'markup',
'#value' => t('None supported.'),
);
}
}
$form['#theme'] = 'location_map_link_options';
return system_settings_form($form);
}
function location_field_names() {
return array(
'name' => t('Location name'),
'street' => t('Street location'),
'city' => t('City'),
'province' => t('State/Province'),
'postal_code' => t('Postal code'),
'country' => t('Country'),
);
}
function location_geocoding_parameters_page($country_iso, $service) {
drupal_set_title(t('Configure parameters for %service geocoding', array(
'%service' => $service,
)));
$breadcrumbs = drupal_get_breadcrumb();
$breadcrumbs[] = l('location', 'admin/settings/locaiton');
$breadcrumbs[] = l('geocoding', 'admin/settings/location/geocoding');
$countries = location_get_iso3166_list();
$breadcrumbs[] = l($countries[$country_iso], 'admin/settings/location/geocoding', array(), NULL, $country_iso);
drupal_set_breadcrumb($breadcrumbs);
return drupal_get_form('location_geocoding_parameters_form', $country_iso, $service);
}
function location_geocoding_parameters_form($country_iso, $service) {
$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());
}
elseif (function_exists($geocode_settings_form_function_general)) {
return system_settings_form($geocode_settings_form_function_general());
}
else {
return system_settings_form(array(
'#type' => 'markup',
'#value' => t('No configuration parameters are necessary, or a form to take such paramters has not been implemented.'),
));
}
}
function location_geocoding_options_page() {
$iso = arg(4);
$service = arg(5);
if (!empty($iso) || !empty($service)) {
return location_geocoding_parameters_page($iso, $service);
}
return drupal_get_form('location_geocoding_options_form');
}
function location_geocoding_options_form() {
$form = array();
$form['countries'] = array();
$general_geocoders_list = location_get_general_geocoder_list();
$general_geocoders_data = array();
$general_geocoders_countries = array();
foreach ($general_geocoders_list as $geocoder_name) {
include_once LOCATION_PATH . '/geocoding/' . $geocoder_name . '.inc';
$info_function = $geocoder_name . '_geocode_info';
if (function_exists($info_function)) {
$general_geocoders_data[$geocoder_name] = $info_function();
}
$countries_function = $geocoder_name . '_geocode_country_list';
if (function_exists($countries_function)) {
$general_geocoders_countries[$geocoder_name] = $countries_function();
}
}
foreach (location_configured_countries() as $country_iso => $country_name) {
$geocoding_options = array();
$form['countries'][$country_iso] = array(
'#type' => 'markup',
'#value' => '',
);
$form['countries'][$country_iso]['label_' . $country_iso] = array(
'#type' => 'markup',
'#value' => '<div id="' . $country_iso . '">' . $country_name . '</div>',
);
$country_specific_provider_function = 'location_geocode_' . $country_iso . '_providers';
if (function_exists($country_specific_provider_function)) {
foreach ($country_specific_provider_function() as $name => $details) {
$geocoding_options[$name . '|' . $country_iso] = '<a href="' . $details['url'] . '">' . $details['name'] . '</a> (<a href="' . $details['tos'] . '">Terms of Use</a>)';
}
}
foreach ($general_geocoders_list as $geocoder_name) {
if (in_array($country_iso, $general_geocoders_countries[$geocoder_name])) {
$geocoding_options[$geocoder_name] = '<a href="' . $general_geocoders_data[$geocoder_name]['url'] . '">' . $general_geocoders_data[$geocoder_name]['name'] . '</a> (<a href="' . $general_geocoder_data[$geocoder_name]['tos'] . '">Terms of Use</a>)';
}
}
if (count($geocoding_options)) {
$geocoding_options = array_merge(array(
'none' => t('None'),
), $geocoding_options);
$form['countries'][$country_iso]['location_geocode_' . $country_iso] = array(
'#type' => 'radios',
'#default_value' => variable_get('location_geocode_' . $country_iso, 'none'),
'#options' => $geocoding_options,
);
}
else {
$form['countries'][$country_iso]['location_geocode_' . $country_iso] = array(
'#type' => 'markup',
'#value' => t('None supported.'),
);
}
$current_value = variable_get('location_geocode_' . $country_iso, 'none');
if ($current_value == 'none') {
$form['countries'][$country_iso]['location_geocode_config_link_' . $country_iso] = array(
'#type' => 'markup',
'#value' => t('No service selected for country.'),
);
}
else {
$current_val_chopped = substr($current_value, 0, strpos($current_value, '|'));
$geocode_settings_form_function_specific = 'location_geocode_' . $country_iso . '_' . $current_val_chopped . '_settings';
$geocode_settings_form_function_general = $current_value . '_geocode_settings';
if (function_exists($geocode_settings_form_function_specific)) {
$form['countries'][$country_iso]['location_geocode_config_link_' . $country_iso] = array(
'#type' => 'markup',
'#value' => l(t('Configure parameters'), 'admin/settings/location/geocoding/' . $country_iso . '/' . $current_val_chopped),
);
}
elseif (function_exists($geocode_settings_form_function_general)) {
$form['countries'][$country_iso]['location_geocode_config_link_' . $country_iso] = array(
'#type' => 'markup',
'#value' => l(t('Configure parameters'), 'admin/settings/location/geocoding/' . $country_iso . '/' . $current_value),
);
}
else {
$form['countries'][$country_iso]['location_geocode_config_link_' . $country_iso] = array(
'#type' => 'markup',
'#value' => t('No configuration necessary for selected service.'),
);
}
}
}
$form['#theme'] = 'location_geocoding_options';
return system_settings_form($form);
}
function location_geocoding_options_form_submit($form_id, $form_values) {
$general_geocoders = location_get_general_geocoder_list();
$general_geocoders_in_use = array();
foreach ($form_values as $key => $value) {
if (substr($key, 0, 17) == 'location_geocode_') {
if (in_array($value, $general_geocoders)) {
$general_geocoders_in_use[$value] = $value;
}
}
}
variable_set('location_general_geocoders_in_use', $general_geocoders_in_use);
}
function location_form_alter($form_id, &$form) {
if ($form_id == 'location_geocoding_options_form') {
$form['#submit'] = array_merge(array(
'location_geocoding_options_form_submit' => array(),
'system_settings_form_submit' => array(),
), $form['#submit'] ? $form['#submit'] : array());
}
elseif ($form_id == 'node_type_form') {
$type = $form['#node_type']->type;
$form['#validate'] = array_merge(is_array($form['#validate']) ? $form['#validate'] : array(), array(
'location_node_settings_validate' => array(),
));
$form['location'] = array_merge(is_array($form['location']) ? $form['location'] : array(), array(
'#type' => 'fieldset',
'#title' => t('Locative information'),
'#collapsible' => TRUE,
'#collapsed' => TRUE,
'#weight' => 0,
));
$form['location']['multiple_locations'] = array_merge(is_array($form['location']['multiple_locations']) ? $form['location']['multiple_locations'] : array(), array(
'#type' => 'fieldset',
'#title' => t('Number of locations'),
'#collapsible' => FALSE,
'#collapsed' => FALSE,
'#weight' => 0,
));
$form['location']['multiple_locations']['location_maxnum'] = array(
'#type' => 'select',
'#title' => t('Maximum number of locations allowed for this type.'),
'#default_value' => variable_get('location_maxnum_' . $type, 0),
'#options' => drupal_map_assoc(range(0, 100)),
'#description' => t('This setting determines the maximum number of locations that can be assigned to a node of this type. This number must be greater than or equal to the default number of location forms selected below. By selecting a number greater than zero, users will be able to add a full or partial address(es) to each node of this type (depending on which fields you enable or require below).'),
);
$form['location']['multiple_locations']['location_defaultnum'] = array(
'#type' => 'select',
'#title' => t('Default number of location forms'),
'#default_value' => variable_get('location_defaultnum_' . $type, 0),
'#options' => drupal_map_assoc(range(0, 10)),
'#description' => t('This setting only applies when you have enabled locations for this node type. It determines how many blank location forms will show up on the original edit-screen for a node of this type. It also only applies when you have enabled a maximum of 1 or more locations to be submitted for this node type.'),
);
$options = array();
for ($i = -10; $i < 11; $i++) {
$options[$i] = $i;
}
$form['location']['location_weight'] = array(
'#prefix' => '<div style="margin-left: 40px">',
'#type' => 'select',
'#title' => t('Location weight'),
'#options' => $options,
'#default_value' => variable_get('location_weight_' . $type, 9),
'#description' => t('Weight of the location box in the input form. Lowest values will be displayed higher in the form.'),
);
$form['location']['location_collapsible'] = array(
'#type' => 'checkbox',
'#title' => t('Collapsible'),
'#return_value' => 1,
'#default_value' => variable_get('location_collapsible_' . $type, 1),
'#description' => t('Make the location box collapsible.'),
);
$form['location']['location_collapsed'] = array(
'#type' => 'checkbox',
'#title' => t('Collapsed'),
'#return_value' => 1,
'#default_value' => variable_get('location_collapsed_' . $type, 1),
'#description' => t('Display the location box collapsed.'),
);
$form['location']['location_addanother'] = array(
'#type' => 'checkbox',
'#title' => t('Add another location from node view page'),
'#return_value' => 1,
'#default_value' => variable_get('location_addanother_' . $type, 0),
'#description' => t('Display the "Add another location" option on the node view page.'),
);
$form['location']['required_field_notice'] = array(
'#type' => 'markup',
'#value' => '<p><strong>' . t('NOTE:') . '</strong> ' . t('Locations fields you choose to require will only be required for the first location if you have allowed more than one location to be submitted for this node type.') . '</p>',
);
$form['location']['location_name'] = array(
'#type' => 'radios',
'#title' => t('Location names'),
'#default_value' => variable_get('location_name_' . $type, $default),
'#options' => array(
t('Do not collect location names (e.g. place of business) for this node type.'),
t('Allow location names for content of this type.'),
t('Require location names for content of this type.'),
),
);
$form['location']['location_street'] = array(
'#type' => 'radios',
'#title' => t('Street locations'),
'#default_value' => variable_get('location_street_' . $type, $default),
'#options' => array(
t('Do not collect a street location for content of this type.'),
t('Allow street locations to be submitted for content of this type.'),
t('Require street locations to be submitted for content of this type.'),
),
);
$form['location']['location_city'] = array(
'#type' => 'radios',
'#title' => t('City names'),
'#default_value' => variable_get('location_city_' . $type, 0),
'#options' => array(
t('Do not collect city names for content of this type.'),
t('Allow city names to be submitted for content of this type.'),
t('Require city names to be submitted for content of this type.'),
),
);
$form['location']['location_province'] = array(
'#type' => 'radios',
'#title' => 'State/Province names',
'#default_value' => variable_get('location_province_' . $type, 0),
'#options' => array(
t('Do not collect state/province names for content of this type.'),
t('Allow state/province names to be submitted for content of this type.'),
t('Require state/province names to be submitted for content of this type.'),
),
);
$form['location']['location_postal_code'] = array(
'#type' => 'radios',
'#title' => 'Postal codes',
'#default_value' => variable_get('location_postal_code_' . $type, 0),
'#options' => array(
t('Do not collect postal codes for content of this type.'),
t('Allow postal codes to be submitted for content of this type.'),
t('Require postal codes to be submitted for content of this type.'),
),
);
$form['location']['location_country'] = array(
'#type' => 'radios',
'#title' => 'Country names',
'#default_value' => variable_get('location_country_' . $type, 1),
'#options' => array(
1 => t('Allow country names to be submitted for content of this type.'),
2 => t('Require country names to be submitted for content of this type.'),
),
'#description' => t('The selection of a country can be hidden and/or forced to a default country selection by going to the <a href="@location_settings">location settings page</a> and checking the box marked "Hide country selection" and selecting a country from the drop down select labelled "Default country selection".', array(
'@location_settings' => url('admin/settings/location'),
)),
'#suffix' => '</div>',
);
if (function_exists('views_invalidate_cache')) {
views_invalidate_cache();
}
}
elseif (isset($form['type']['#value']) && $form['type']['#value'] . '_node_form' == $form_id && variable_get('location_maxnum_' . $form['type']['#value'], 0)) {
$node = $form['#node'];
$location_fields = array();
$required_fields = array();
foreach (array_keys(location_field_names()) as $field_name) {
$workflow_setting = variable_get('location_' . $field_name . '_' . $node->type, $field_name == 'country' ? 1 : 0);
if ($workflow_setting) {
$location_fields[] = $field_name;
if ($workflow_setting == 2) {
$required_fields[] = $field_name;
}
}
}
$location_form_count = $node->nid ? max(count($node->locations), variable_get('location_defaultnum_' . $node->type, 1)) : variable_get('location_defaultnum_' . $node->type, 1);
$form['locations'] = array_merge(is_array($form['locations']) ? $form['locations'] : array(), array(
'#type' => 'fieldset',
'#title' => format_plural($location_form_count, 'Location', 'Locations'),
'#tree' => TRUE,
'#attributes' => array_merge(is_array($form['locations']['#attributes']) ? $form['locations']['#attributes'] : array(), array(
'class' => 'locations',
)),
'#weight' => variable_get('location_weight_' . $form['type']['#value'], 9),
'#collapsible' => variable_get('location_collapsible_' . $form['type']['#value'], 0) == 0 ? FALSE : TRUE,
'#collapsed' => variable_get('location_collapsed_' . $form['type']['#value'], 0) == 0 ? FALSE : TRUE,
));
for ($index = 0; $index < $location_form_count; $index++) {
$form['locations'][$index] = array_merge(is_array($form['locations'][$index]) ? $form['locations'][$index] : array(), array(
'#type' => 'fieldset',
'#title' => t('Location #%number', array(
'%number' => $index + 1,
)),
'#tree' => TRUE,
'#attributes' => array(
'class' => 'location',
),
));
}
if ($location_form_count == 1) {
$form['locations'][0]['#title'] = t('Location');
}
for ($index = 0; $index < $location_form_count; $index++) {
if (!isset($node->locations[$index]['country']) || $node->locations[$index]['country'] == '') {
$node->locations[$index]['country'] = variable_get('location_default_country', 'us');
}
}
$suppressed_values = variable_get('location_suppress_country', 0) ? array(
'country' => variable_get('location_default_country', 'us'),
) : array();
if ($_POST['op'] == t('Preview') || $_POST['op'] == t('Submit') && form_get_errors()) {
for ($index = 0; $index < $location_form_count; $index++) {
$form['locations'][$index] = array_merge($form['locations'][$index], location_form($location_fields, $node->locations[$index] ? $node->locations[$index] : array(), $index == 0 ? $required_fields : array(), $suppressed_values));
}
}
else {
for ($index = 0; $index < $location_form_count; $index++) {
if (!isset($form['locations'][$index])) {
$form['locations'][$index] = array();
}
$form['locations'][$index] = array_merge($form['locations'][$index], location_form($location_fields, $node->locations[$index] ? location_api2form($node->locations[$index]) : array(), $index == 0 ? $required_fields : array(), $suppressed_values));
}
}
if (user_access('submit latitude/longitude')) {
for ($index = 0; $index < $location_form_count; $index++) {
$form['locations'][$index][] = array(
'#type' => 'markup',
'#value' => "<br/>\n",
);
if ($node->nid || isset($node->locations[$index]['previous_source'])) {
$form['locations'][$index]['previous_source'] = array(
'#type' => 'hidden',
'#value' => $node->locations[$index]['source'],
);
$form['locations'][$index]['previous_latitude'] = array(
'#type' => 'hidden',
'#value' => $node->locations[$index]['latitude'],
);
$form['locations'][$index]['previous_longitude'] = array(
'#type' => 'hidden',
'#value' => $node->locations[$index]['longitude'],
);
}
$form['locations'][$index] = array_merge($form['locations'][$index], location_latlon_form(t('If you wish to supply your own latitude/longitude, you may do so here. Leaving these fields blank means that the system will determine a latitude/longitude for you, if possible.'), $node->locations[$index] ? location_api2form($node->locations[$index]) : array()));
}
}
for ($index = 0; $index < $location_form_count; $index++) {
$form['locations'][$index]['lid'] = array(
'#type' => 'hidden',
'#value' => $node->locations[$index]['lid'],
);
}
}
}
function location_node_settings_validate($form_id, $form_values) {
$type = $form_values['type'];
$maxnum_name = 'location_maxnum_' . $type;
$defaultnum_name = 'location_defaultnum_' . $type;
if ($form_values[$defaultnum_name] > $form_values[$maxnum_name]) {
form_set_error($defaultnum_name, t("Your default number of location-forms that show up can't be greater than the maximum number of locations allowed for this node type."));
}
if (!$form_values[$defaultnum_name] && $form_values[$maxnum_name]) {
form_set_error($defaultnum_name, t("You must have at least 1 default location-form enabled if you are going to allow locations to be submitted for nodes of this type. If you don't intend to allow locations to be submitted for nodes of this type, set the maximum number of locations allowed for this type to 0."));
}
}
function location_nodeapi(&$node, $op, $teaser = NULL, $page = NULL) {
if (!variable_get('location_maxnum_' . $node->type, 0)) {
return;
}
switch ($op) {
case 'validate':
foreach ($node->locations as $index => $location) {
foreach (location_field_names() as $field_name => $display_name) {
$workflow_setting = variable_get('location_' . $field_name . '_' . $node->type, $field_name == 'country' ? 1 : 0);
if ($index == 0) {
if (variable_get('location_' . $field_name . '_' . $node->type, 0) == 2) {
if (isset($node->locations[$index][$field_name]) && !strlen(trim($node->locations[$index][$field_name]))) {
form_set_error('locations][' . $index . '][' . $field_name, t('The field %field is required.', array(
'%field' => $display_name,
)));
}
}
}
$node->locations[$index][$field_name] = trim($node->locations[$index][$field_name]);
}
if (isset($node->locations[$index]['province']) && !empty($node->locations[$index]['province']) && $node->locations[$index]['province'] != 'xx' && isset($node->locations[$index]['country']) && !empty($node->locations[$index]['country']) && $node->locations[$index]['country'] != 'xx') {
$province_list_function = 'location_province_list_' . $node->locations[$index]['country'];
if (function_exists($province_list_function)) {
$translated_location = location_form2api($node->locations[$index]);
if (!in_array($translated_location['province'], array_keys($province_list_function()))) {
form_set_error('locations][' . $index . '][province', t('Please make sure to select a state/province from the country you have selected.'));
}
}
}
if (user_access('submit latitude/longitude')) {
if (!strlen(trim($node->locations[$index]['latitude'])) && strlen(trim($node->locations[$index]['longitude'])) || strlen(trim($node->locations[$index]['latitude'])) && !strlen(trim($node->locations[$index]['longitude']))) {
form_set_error('locations][' . $index . '][latitude', t('You must fill out both longitude and latitude or you must leave them both blank.'));
form_set_error('locations][' . $index . '][longitude', NULL);
}
elseif (strlen(trim($node->locations[$index]['latitude'])) && strlen(trim($node->locations[$index]['longitude']))) {
if (!is_numeric($node->locations[$index]['latitude']) || $node->locations[$index]['latitude'] > 90.0 || $node->locations[$index]['latitude'] < -90.0) {
form_set_error('locations][' . $index . '][latitude', t('Your latitude must be a numeric value between -90.0 and 90.0.'));
}
if (!is_numeric($node->locations[$index]['longitude']) || $node->locations[$index]['longitude'] > 180.0 || $node->locations[$index]['longitude'] < -180.0) {
form_set_error('locations][' . $index . '][longitude', t('Your longitude must be a numeric value between -180.0 and 180.0.'));
}
}
}
}
break;
case 'insert':
case 'update':
$location_fields = array();
$required_fields = array();
foreach (array_keys(location_field_names()) as $field_name) {
$workflow_setting = variable_get('location_' . $field_name . '_' . $node->type, $field_name == 'country' ? 1 : 0);
if ($workflow_setting) {
$location_fields[] = $field_name;
if ($workflow_setting == 2) {
$required_fields[] = $field_name;
}
}
}
foreach ($node->locations as $index => $location) {
$node->locations[$index] = location_form2api($node->locations[$index]);
if (user_access('submit latitude/longitude')) {
$node->locations[$index]['latitude'] = trim($node->locations[$index]['latitude']);
$node->locations[$index]['longitude'] = trim($node->locations[$index]['longitude']);
if (!empty($node->locations[$index]['latitude']) && !empty($node->locations[$index]['longitude'])) {
if (($data = location_latlon_exact($node->locations[$index])) && _location_floats_are_equal(floatval($node->locations[$index]['latitude']), floatval($data['lat'])) && _location_floats_are_equal(floatval($node->locations[$index]['longitude']), floatval($data['lon']))) {
$node->locations[$index]['lat'] = $node->locations[$index]['latitude'];
$node->locations[$index]['lon'] = $node->locations[$index]['longitude'];
$node->locations[$index]['source'] = LOCATION_LATLON_GEOCODED_EXACT;
}
elseif (($data = location_get_postalcode_data($node->locations[$index])) && _location_floats_are_equal(floatval($node->locations[$index]['latitude']), floatval($data['lat'])) && _location_floats_are_equal(floatval($node->locations[$index]['longitude']), floatval($data['lon']))) {
$node->locations[$index]['lat'] = $node->locations[$index]['latitude'];
$node->locations[$index]['lon'] = $node->locations[$index]['longitude'];
$node->locations[$index]['source'] = LOCATION_LATLON_GEOCODED_APPROX;
}
else {
$node->locations[$index]['lat'] = $node->locations[$index]['latitude'];
$node->locations[$index]['lon'] = $node->locations[$index]['longitude'];
$node->locations[$index]['source'] = LOCATION_LATLON_USER_SUBMITTED;
}
}
else {
if ($data = location_latlon_exact($node->locations[$index])) {
$node->locations[$index]['latitude'] = $data['lat'];
$node->locations[$index]['longitude'] = $data['lon'];
$node->locations[$index]['lat'] = $data['lat'];
$node->locations[$index]['lon'] = $data['lon'];
$node->locations[$index]['source'] = LOCATION_LATLON_GEOCODED_EXACT;
}
elseif ($data = location_get_postalcode_data($node->locations[$index])) {
$node->locations[$index]['latitude'] = $data['lat'];
$node->locations[$index]['longitude'] = $data['lon'];
$node->locations[$index]['lat'] = $data['lat'];
$node->locations[$index]['lon'] = $data['lon'];
$node->locations[$index]['source'] = LOCATION_LATLON_GEOCODED_APPROX;
}
else {
unset($node->locations[$index]['latitude']);
unset($node->locations[$index]['longitude']);
unset($node->locations[$index]['lat']);
unset($node->locations[$index]['lon']);
$node->locations[$index]['source'] = LOCATION_LATLON_UNDEFINED;
}
}
}
else {
if ($node->nid) {
$result = db_query("SELECT * FROM {location} WHERE type = 'node' AND eid = %d", $node->nid);
if ($location = db_fetch_object($result)) {
if ($location->source != LOCATION_LATLON_USER_SUBMITTED) {
if ($data = location_latlon_exact($node->locations[$index])) {
$node->locations[$index]['lat'] = $data['lat'];
$node->locations[$index]['lon'] = $data['lon'];
$node->locations[$index]['latitude'] = $data['lat'];
$node->locations[$index]['longitude'] = $data['lon'];
$node->locations[$index]['source'] = LOCATION_LATLON_GEOCODED_EXACT;
}
elseif ($data = location_get_postalcode_data($node->location)) {
$node->locations[$index]['lat'] = $data['lat'];
$node->locations[$index]['lon'] = $data['lon'];
$node->locations[$index]['latitude'] = $data['lat'];
$node->locations[$index]['longitude'] = $data['lon'];
$node->locations[$index]['source'] = LOCATION_LATLON_GEOCODED_APPROX;
}
else {
unset($node->locations[$index]['lat']);
unset($node->locations[$index]['lon']);
unset($node->locations[$index]['latitude']);
unset($node->locations[$index]['longitude']);
$node->locations[$index]['source'] = LOCATION_LATLON_UNDEFINED;
}
}
}
}
elseif ($data = location_latlon_exact($node->locations[$index])) {
$node->locations[$index]['lat'] = $data['lat'];
$node->locations[$index]['lon'] = $data['lon'];
$node->locations[$index]['latitude'] = $data['lat'];
$node->locations[$index]['longitude'] = $data['lon'];
$node->locations[$index]['source'] = LOCATION_LATLON_GEOCODED_EXACT;
}
elseif ($data = location_get_postalcode_data($node->location)) {
$node->locations[$index]['lat'] = $data['lat'];
$node->locations[$index]['lon'] = $data['lon'];
$node->locations[$index]['latitude'] = $data['lat'];
$node->locations[$index]['longitude'] = $data['lon'];
$node->locations[$index]['source'] = LOCATION_LATLON_GEOCODED_APPROX;
}
else {
unset($node->locations[$index]['lat']);
unset($node->locations[$index]['lon']);
unset($node->locations[$index]['latitude']);
unset($node->locations[$index]['longitude']);
$node->locations[$index]['source'] = LOCATION_LATLON_UNDEFINED;
}
}
if ($data = location_get_postalcode_data($node->locations[$index])) {
$node->locations[$index]['city'] = !isset($node->locations[$index]['city']) || strlen($node->locations[$index]['city']) == 0 ? $data['city'] : $node->locations[$index]['city'];
$node->locations[$index]['province'] = !isset($node->locations[$index]['province']) || strlen($node->locations[$index]['province']) == 0 ? $data['province'] : $node->locations[$index]['province'];
}
$keep = FALSE;
if (!empty($node->locations[$index]['country']) || !empty($node->locations[$index]['latitude']) && !empty($node->locations[$index]['longitude'])) {
if ($index == 0) {
if (in_array('country', $required_fields)) {
$keep = TRUE;
}
if (isset($node->locations[$index]['latitude']) && isset($node->locations[$index]['longitude'])) {
$keep = TRUE;
}
elseif (count($location_fields) == 1) {
$keep = TRUE;
}
else {
foreach ($location_fields as $field) {
if ($field != 'country' && !empty($node->locations[$index][$field])) {
$keep = TRUE;
break;
}
}
}
}
else {
foreach ($location_fields as $field) {
if ($field == 'country' && $node->locations[$index][$field] != variable_get('location_default_country', 'us')) {
$keep = TRUE;
break;
}
elseif (!empty($node->locations[$index]['latitude']) && !empty($node->locations[$index]['longitude'])) {
$keep = TRUE;
break;
}
elseif ($field != 'country' && !empty($node->locations[$index][$field])) {
$keep = TRUE;
break;
}
}
}
}
if ($keep) {
_location_save($node->locations[$index] ? $node->locations[$index] : array(), $node, 'node');
}
else {
if ($node->locations[$index]['lid']) {
db_query('DELETE FROM {location} WHERE lid = %d', $node->locations[$index]['lid']);
location_invoke_locationapi($node->locations[$index], 'delete');
}
}
}
break;
case 'load':
$loaded_data = location_load_locations('node', $node);
return $loaded_data;
case 'view':
if (variable_get('location_display_location', 1)) {
if (isset($_POST) && ($_POST['op'] == t('Preview') || $_POST['op'] == t('Submit') && form_get_errors())) {
$posted_locations = array();
foreach ($node->locations as $index => $location) {
if (count($node->locations[$index])) {
$posted_locations[$index] = location_form2api($node->locations[$index]);
if (!isset($posted_locations[$index]['city']) || strlen(trim($posted_locations[$index]['city'])) == 0) {
$postal_data = location_get_postalcode_data($posted_locations[$index]);
$posted_locations[$index]['city'] = isset($postal_data['city']) ? $postal_data['city'] : '';
}
if (!isset($posted_locations[$index]['province']) || strlen(trim($posted_locations[$index]['province'])) == 0) {
$postal_data = isset($postal_data) ? $postal_data : location_get_postalcode_data($posted_locations[$index]);
$posted_locations[$index]['province'] = isset($postal_data['province']) ? $postal_data['province'] : '';
}
}
}
if ($output = theme('locations', $posted_locations, variable_get('location_suppress_country', 0) ? array(
'country',
) : array())) {
$node->content['locations']['#value'] .= $output;
}
}
else {
if ($themed_locations = theme('locations', $node->locations, variable_get('location_suppress_country', 0) ? array(
'country',
) : array())) {
$node->content['locations']['#value'] .= $themed_locations;
}
}
}
if (variable_get('location_addanother_' . $node->type, 0) && count($node->locations) < variable_get('location_maxnum_' . $node->type, 0) && !$teaser && node_access('update', $node)) {
$node->content['locations']['#value'] .= drupal_get_form('location_extra_form', $node);
}
break;
case 'rss item':
$items = array();
if (is_array($node->locations)) {
foreach ($node->locations as $index => $location) {
if (!is_null($node->locations[$index]['lat']) && !is_null($node->locations[$index]['lon'])) {
$items[] = array(
'key' => 'geo:Point',
'namespace' => array(
'geo' => 'xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#"',
),
'value' => array(
array(
'key' => 'geo:lat',
'value' => $node->locations[$index]['lat'],
),
array(
'key' => 'geo:lon',
'value' => $node->locations[$index]['lon'],
),
),
);
}
}
}
return $items;
break;
}
}
function location_extra_form(&$node) {
$location_fields = array();
$required_fields = array();
foreach (array_keys(location_field_names()) as $field_name) {
$workflow_setting = variable_get('location_' . $field_name . '_' . $node->type, $field_name == 'country' ? 1 : 0);
if ($workflow_setting) {
$location_fields[] = $field_name;
if ($workflow_setting == 2) {
$required_fields[] = $field_name;
}
}
}
$suppressed_values = variable_get('location_suppress_country', 0) ? array(
'country' => variable_get('location_default_country', 'us'),
) : array();
$form['location'] = array(
'#type' => 'fieldset',
'#title' => t('Add another location'),
'#tree' => TRUE,
'#attributes' => array(
'class' => 'location',
),
'#collapsible' => TRUE,
'#collapsed' => TRUE,
);
$form['location'] = array_merge($form['location'], location_form($location_fields, array(
'country' => variable_get('location_default_country', 'us'),
), array(), $suppressed_values));
if (user_access('submit latitude/longitude')) {
$form['location'][] = array(
'#type' => 'markup',
'#value' => "<br/>\n",
);
$form['location'] = array_merge($form['location'], location_latlon_form(t('If you wish to supply your own latitude/longitude, you may do so here. Leaving these fields blank means that the system will determine a latitude/longitude for you, if possible.'), array()));
}
$form['location']['nid'] = array(
'#type' => 'hidden',
'#value' => $node->nid,
);
$form['location']['submit'] = array(
'#type' => 'submit',
'#value' => t('Add location'),
);
return $form;
}
function location_extra_form_validate($form_id, &$form_values) {
foreach ($form_values['location'] as $key => $value) {
$form_values['location'][$key] = trim($value);
}
if (isset($form_values['location']['province']) && !empty($form_values['location']['province']) && $form_values['location']['province'] != 'xx' && isset($form_values['location']['country']) && !empty($form_values['location']['country']) && $form_values['location']['country'] != 'xx') {
$province_list_function = 'location_province_list_' . $form_values['location']['country'];
if (function_exists($province_list_function)) {
$translated_location = location_form2api($form_values['location']);
if (!in_array($translated_location['province'], array_keys($province_list_function()))) {
form_set_error('location][province', t('Please make sure to select a state/province from the country you have selected.'));
}
}
}
if (user_access('submit latitude/longitude')) {
if (!strlen(trim($form_values['location']['latitude'])) && strlen(trim($form_values['location']['longitude'])) || strlen(trim($form_values['location']['latitude'])) && !strlen(trim($form_values['location']['longitude']))) {
form_set_error('location][latitude', t('You must fill out both longitude and latitude or'));
form_set_error('location][longitude', t('you must leave them both blank.'));
}
elseif (strlen(trim($form_values['location']['latitude'])) && strlen(trim($form_values['location']['longitude']))) {
if (!is_numeric($form_values['location']['latitude']) || $form_values['location']['latitude'] > 90.0 || $form_values['location']['latitude'] < -90.0) {
form_set_error('location][latitude', t('Your latitude must be a numeric value between -90.0 and 90.0.'));
}
if (!is_numeric($form_values['location']['longitude']) || $form_values['location']['longitude'] > 180.0 || $form_values['location']['longitude'] < -180.0) {
form_set_error('location][longitude', t('Your longitude must be a numeric value between -180.0 and 180.0.'));
}
}
}
}
function location_extra_form_submit($form_id, &$form_values) {
$location_fields = array();
$required_fields = array();
foreach (array_keys(location_field_names()) as $field_name) {
$workflow_setting = variable_get('location_' . $field_name . '_' . $node->type, $field_name == 'country' ? 1 : 0);
if ($workflow_setting) {
$location_fields[] = $field_name;
if ($workflow_setting == 2) {
$required_fields[] = $field_name;
}
}
}
$form_values['location'] = location_form2api($form_values['location']);
if (user_access('submit latitude/longitude')) {
$form_values['location']['latitude'] = trim($form_values['location']['latitude']);
$form_values['location']['longitude'] = trim($form_values['location']['longitude']);
if (!empty($form_values['location']['latitude']) && !empty($form_values['location']['longitude'])) {
if (($data = location_latlon_exact($form_values['location'])) && _location_floats_are_equal(floatval($form_values['location']['latitude']), floatval($data['lat'])) && _location_floats_are_equal(floatval($form_values['location']['longitude']), floatval($data['lon']))) {
$form_values['location']['lat'] = $form_values['location']['latitude'];
$form_values['location']['lon'] = $form_values['location']['longitude'];
$form_values['location']['source'] = LOCATION_LATLON_GEOCODED_EXACT;
}
elseif (($data = location_get_postalcode_data($form_values['location'])) && _location_floats_are_equal(floatval($form_values['location']['latitude']), floatval($data['lat'])) && _location_floats_are_equal(floatval($form_values['location']['longitude']), floatval($data['lon']))) {
$form_values['location']['lat'] = $form_values['location']['latitude'];
$form_values['location']['lon'] = $form_values['location']['longitude'];
$form_values['location']['source'] = LOCATION_LATLON_GEOCODED_APPROX;
}
else {
$form_values['location']['lat'] = $form_values['location']['latitude'];
$form_values['location']['lon'] = $form_values['location']['longitude'];
$form_values['location']['source'] = LOCATION_LATLON_USER_SUBMITTED;
}
}
else {
if ($data = location_latlon_exact($form_values['location'])) {
$form_values['location']['latitude'] = $data['lat'];
$form_values['location']['longitude'] = $data['lon'];
$form_values['location']['lat'] = $data['lat'];
$form_values['location']['lon'] = $data['lon'];
$form_values['location']['source'] = LOCATION_LATLON_GEOCODED_EXACT;
}
elseif ($data = location_get_postalcode_data($form_values['location'])) {
$form_values['location']['latitude'] = $data['lat'];
$form_values['location']['longitude'] = $data['lon'];
$form_values['location']['lat'] = $data['lat'];
$form_values['location']['lon'] = $data['lon'];
$form_values['location']['source'] = LOCATION_LATLON_GEOCODED_APPROX;
}
else {
unset($form_values['location']['latitude']);
unset($form_values['location']['longitude']);
unset($form_values['location']['lat']);
unset($form_values['location']['lon']);
$form_values['location']['source'] = LOCATION_LATLON_UNDEFINED;
}
}
}
if ($data = location_get_postalcode_data($form_values['location'])) {
$form_values['location']['city'] = !isset($form_values['location']['city']) || strlen($form_values['location']['city']) == 0 ? $data['city'] : $form_values['location']['city'];
$form_values['location']['province'] = !isset($form_values['location']['province']) || strlen($form_values['location']['province']) == 0 ? $data['province'] : $form_values['location']['province'];
}
$node = node_load($form_values['location']['nid']);
_location_save($form_values['location'] ? $form_values['location'] : array(), $node, 'node');
drupal_set_message(t('Your new location has been added. (See below)'));
return 'node/' . $form_values['location']['nid'];
}
function location_load_locations($type, $node_or_user) {
$res = db_query("SELECT * FROM {location} WHERE type = '%s' AND eid = %d ORDER BY lid", $type, $type == 'user' ? $node_or_user->uid : $node_or_user->vid);
$locations = array();
$location = array();
$index = 0;
while ($row = db_fetch_object($res)) {
$locations[$index] = (array) $row;
if (isset($locations[$index]['latitude'])) {
$locations[$index]['lat'] = $locations[$index]['latitude'];
$locations[$index]['lon'] = $locations[$index]['longitude'];
}
if ($extra = location_invoke_locationapi($locations[$index], 'load')) {
$locations[$index] = array_merge($locations[$index], $extra);
}
$index++;
}
$location = count($locations) ? $locations[0] : array();
return array(
'locations' => $locations,
'location' => $location,
);
}
function location_get_configured_countries() {
$configured_countries = variable_get('location_configured_countries', array(
'us' => 1,
));
$configured_countries = is_array($configured_countries) ? $configured_countries : array(
'us' => 1,
);
$return = array();
foreach ($configured_countries as $country => $enabled) {
if ($enabled) {
$return[] = $country;
}
}
return $return;
}
function location_admin_settings() {
cache_clear_all('location:supported-countries', 'cache');
$supported_countries = _location_supported_countries();
$default_country = variable_get('location_default_country', 'us');
$configured_countries = location_get_configured_countries();
$iso_list_sorted = _location_get_iso3166_list();
array_multisort($iso_list_sorted);
$iso_list_sorted = array_merge(array(
'' => '',
), $iso_list_sorted);
if ($default_country && in_array($default_country, array_keys($supported_countries)) && !in_array($default_country, $configured_countries)) {
$configured_countries = variable_get('location_configured_countries', array(
'us' => 1,
));
$configured_countries[$default_country] = 1;
variable_set('location_configured_countries', $configured_countries);
if (function_exists('views_invalidate_cache')) {
views_invalidate_cache();
}
}
$form = array();
$form['location_default_country'] = array(
'#type' => 'select',
'#title' => t('Default country selection'),
'#default_value' => variable_get('location_default_country', 'us'),
'#options' => $iso_list_sorted,
'#description' => t('This will be the country that is automatically selected when a location form is served for a new location.'),
);
$form['location_suppress_country'] = array(
'#type' => 'checkbox',
'#title' => t('Hide country selection'),
'#return_value' => 1,
'#default_value' => variable_get('location_suppress_country', 0),
'#description' => t("If your site is specific to a country and you would like to hide the country field on search forms and content creation forms, check this box. Doing so will automatically assume the country to be the country you have chosen for the 'default country selection' above."),
);
$form['location_search_distance_unit'] = array(
'#type' => 'radios',
'#title' => t('Distance unit for location-based searches'),
'#default_value' => variable_get('location_search_distance_unit', 0),
'#options' => array(
0 => t('Allow both miles and kilometers.'),
'mile' => t('Only allow a search-radius to be specified in miles'),
'km' => t('Only allow a search-radius to be specified in kilometers'),
),
'#description' => t('Select the distance unit that applies when users search for content by a specified location and search-radius.'),
);
$form['location_display_location'] = array(
'#type' => 'radios',
'#title' => t('Toggle location display'),
'#default_value' => variable_get('location_display_location', 1),
'#options' => array(
0 => t('Disable the display of locations.'),
1 => t('Enable the display of locations.'),
),
'#description' => t('If you are interested in turning off locations and having a custom theme control their display, you may want to disable the display of locations so your theme can take that function.'),
);
$form['location_user'] = array(
'#type' => 'radios',
'#title' => 'User locations',
'#default_value' => variable_get('location_user', 0),
'#options' => array(
'Disable',
'Enable',
),
'#description' => t('Collect user addresses (partial or full) if users wish to submit them for their user accounts.'),
);
$form['location_usegmap'] = array(
'#type' => 'checkbox',
'#title' => t('Use a Google Map to set latitude and longitude '),
'#return_value' => 1,
'#default_value' => variable_get('location_usegmap', 1),
'#description' => t('If the gmap.module is installed and <a href="@enabled">enabled</a>, and this is setting is turned on, users that are allowed to manually enter latitude/longitude coordinates will be able to do so with an interactive Google Map. You should also make sure you have entered a <a href="@google_maps_api_key">Google Maps API key</a> into your <a href="@gmap_module_settings">gmap module settings</a>.', array(
'@enabled' => 'admin/build/modules',
'@google_maps_api_key' => 'http://www.google.com/apis/maps',
'@gmap_module_settings' => 'admin/settings/gmap',
)),
);
$form['maplink_external'] = array(
'#type' => 'fieldset',
'#title' => t('Map link'),
);
$form['maplink_external']['location_maplink_external'] = array(
'#type' => 'checkbox',
'#title' => t('Open map link in new window'),
'#default_value' => variable_get('location_maplink_external', 0),
'#description' => t('Select this if you want the map link to open in a separate window'),
);
$form['maplink_external']['location_maplink_external_method'] = array(
'#type' => 'radios',
'#title' => t('Open in new window method'),
'#options' => array(
'target="_blank"' => 'target="_blank"',
'rel="external"' => 'rel="external"',
),
'#default_value' => variable_get('location_maplink_external_method', 'target="_blank"'),
'#description' => t('If you have selected to open map in a new window this controls the method used to open in a new window. target="_blank" will just work but is not XTHML Strict compliant. rel="external" is XHTML Strict compliant but will not open in a new window unless you add some jQuery to your site to add the target attribute. If you are unsure leave set to target="_blank"'),
);
$form['location_configured_countries'] = array(
'#type' => 'checkboxes',
'#title' => t('Enable all <em>available</em> features for locations from the following countries'),
'#default_value' => location_get_configured_countries(),
'#options' => $supported_countries,
'#description' => t('Currently, your Drupal site is capable of supporting extra features (e.g., postal code proximity searches) for locations from this list of countries. Please narrow the list down to countries for which you want to support these extra features. It may be useful for performance to narrow down this list if most the locations in your system are from only a handful of the listed countries.'),
);
return system_settings_form($form);
}
function _location_effective_user_setting() {
return variable_get('location_user', LOCATION_USER_DONT_COLLECT);
}
function location_user($op, &$edit, &$user, $category = NULL) {
$user_setting = _location_effective_user_setting();
if ($user_setting == LOCATION_USER_DONT_COLLECT) {
return;
}
if ($op == 'form' && $category == 'account' && $user_setting == LOCATION_USER_COLLECT) {
$form = array(
1 => array(),
);
$form[0]['location'] = location_form(array(
'street',
'city',
'province',
'postal_code',
'country',
), isset($user->location) && !_location_is_empty($user->location) ? location_api2form($user->location) : array(
'country' => variable_get('location_default_country', 'us'),
), array(), variable_get('location_suppress_country', 0) ? array(
'country' => variable_get('location_default_country', 'us'),
) : array());
$form[0]['location']['#type'] = 'fieldset';
$form[0]['location']['#title'] = t('Location');
$form[0]['location']['#tree'] = TRUE;
$form[0]['location']['#collapsible'] = TRUE;
$form[0]['location']['#description'] = t('Enter as much of your address as you are comfortable with. Your address will only be viewable by those who have the appropriate permissions. The site will be able to automatically link you to driving directions and other features if it already knows your address.');
if ($user->location['lid']) {
$form[0]['location']['lid'] = array(
'#type' => 'hidden',
'#value' => $user->location['lid'],
);
}
return $form;
}
if ($op == 'load' && $user_setting != LOCATION_USER_DONT_COLLECT) {
$res = db_query("SELECT * FROM {location} WHERE type = 'user' AND eid = %d", $user->uid);
if ($location = db_fetch_object($res)) {
$user->location = (array) $location;
}
else {
$user->location = array();
}
}
if (($op == 'update' || $op == 'insert') && $category == 'account') {
$edit['location'] = location_form2api($edit['location']);
if ($data = location_latlon_exact($edit['location'])) {
$edit['location']['source'] = LOCATION_LATLON_GEOCODED_EXACT;
$edit['location']['lat'] = $data['lat'];
$edit['location']['lon'] = $data['lon'];
}
elseif ($data = location_get_postalcode_data($edit['location'])) {
$edit['location']['source'] = LOCATION_LATLON_GEOCODED_APPROX;
$edit['location']['lat'] = $data['lat'];
$edit['location']['lon'] = $data['lon'];
}
else {
unset($edit['location']['lat']);
unset($edit['location']['lon']);
$edit['location']['source'] = LOCATION_LATLON_UNDEFINED;
}
_location_save($edit['location'] ? $edit['location'] : array(), $user, 'user');
unset($edit['location']);
}
if ($user_setting == LOCATION_USER_COLLECT && $op == 'view' && (user_access('administer users') || $GLOBALS['user']->uid == $user->uid) && variable_get('location_display_location', 1) && !_location_is_empty($user->location)) {
$items[] = array(
'value' => theme('location', $user->location),
'class' => 'location',
);
if (user_access('submit latitude/longitude')) {
if ($user->location['latitude'] != NULL && $user->location['longitude'] != NULL) {
$items[] = array(
'title' => t('Coordinates'),
'value' => t('lat: %latitude', array(
'%latitude' => $user->location['latitude'],
)) . '<br/>' . t('lon: %longitude', array(
'%longitude' => $user->location['longitude'],
)),
'class' => 'location',
);
}
}
return array(
t('Location') => $items,
);
}
}
function _location_save($posted_location, &$user_or_node, $type = 'node') {
$field = $type == 'node' ? 'vid' : 'uid';
if (isset($posted_location) && count($posted_location)) {
$lid = $posted_location['lid'] ? $posted_location['lid'] : db_next_id('{location}_lid');
$posted_location['lid'] = $lid;
location_invoke_locationapi($posted_location, 'save');
if (isset($posted_location['lat']) && isset($posted_location['lon'])) {
db_query("DELETE FROM {location} WHERE lid = %d", $lid);
db_query("INSERT INTO {location} (lid, type, eid, name, street, additional, city, province, postal_code, country, latitude, longitude, source) VALUES (%d, '%s', %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%f', '%f', %d)", $lid, $type, $user_or_node->{$field}, !isset($posted_location['name']) || is_null($posted_location['name']) ? '' : $posted_location['name'], !isset($posted_location['street']) || is_null($posted_location['street']) ? '' : $posted_location['street'], !isset($posted_location['additional']) || is_null($posted_location['additional']) ? '' : $posted_location['additional'], !isset($posted_location['city']) || is_null($posted_location['city']) ? '' : $posted_location['city'], !isset($posted_location['province']) || is_null($posted_location['province']) ? '' : $posted_location['province'], !isset($posted_location['postal_code']) || is_null($posted_location['postal_code']) ? '' : $posted_location['postal_code'], !isset($posted_location['country']) || is_null($posted_location['country']) ? NULL : $posted_location['country'], $posted_location['lat'], $posted_location['lon'], $posted_location['source']);
}
else {
db_query("DELETE FROM {location} WHERE lid = %d", $lid);
db_query("INSERT INTO {location} (lid, type, eid, name, street, additional, city, province, postal_code, country, source) VALUES (%d, '%s', %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d)", $lid, $type, $user_or_node->{$field}, !isset($posted_location['name']) || is_null($posted_location['name']) ? '' : $posted_location['name'], !isset($posted_location['street']) || is_null($posted_location['street']) ? '' : $posted_location['street'], !isset($posted_location['additional']) || is_null($posted_location['additional']) ? '' : $posted_location['additional'], !isset($posted_location['city']) || is_null($posted_location['city']) ? '' : $posted_location['city'], !isset($posted_location['province']) || is_null($posted_location['province']) ? '' : $posted_location['province'], !isset($posted_location['postal_code']) || is_null($posted_location['postal_code']) ? '' : $posted_location['postal_code'], !isset($posted_location['country']) || is_null($posted_location['country']) ? NULL : $posted_location['country'], $posted_location['source']);
}
}
}
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_invoke_locationapi(&$location, $op, $a3 = NULL, $a4 = NULL) {
$return = array();
foreach (module_implements('locationapi') as $name) {
$function = $name . '_locationapi';
$result = $function($location, $op, $a3, $a4);
if (isset($result) && is_array($result)) {
$return = array_merge($return, $result);
}
else {
if (isset($result)) {
$return[] = $result;
}
}
}
return $return;
}