function location_nodeapi in Location 5
Implementation of hook_nodeapi().
File
- ./
location.module, line 783
Code
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) {
// For now, validation just makes sure that required fields have any value
// If syntax specific checks are implemented for locations in the future, they can be called as well.
foreach (location_field_names() as $field_name => $display_name) {
$workflow_setting = variable_get('location_' . $field_name . '_' . $node->type, $field_name == 'country' ? 1 : 0);
// We only enforce required fields on the first location if there are multiple locations
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]);
}
// Check if the (province, country) pair is valid
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.'));
}
}
}
// Check if submitted lat/lon are valid
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':
// handy to have these field names later
$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']);
// At this point, we know that the user has permission to submit lat/lons and that the
// submitted lat/lons are either blank or valid numbers. Now, we need to find out determine
// the source of these lat/lons since they can either be prefilled from postalcode data
// or manually entered by the user.
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 the user does NOT have permission to explicitly set a lat/lon for the given location, we still want to check
// whether this location was previously assigned a lat/lon manually or whether it was determined via geocoding.
// If the lat/lon was determined from geocoding, then we will want to update the lat/lon using postal codes.
// If the lat/lon was user-submitted, then we don't want to allow the current editor to change the lat/lon
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 no city and/or province were supplied in the address (whether the user left it blank or whether the user did not have the option
// of entering them) then we want to use the data we have based strictly on the postal code.
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'];
}
// Finally, if there are multiple forms, it's possible for the default country to still be selected with all the other fields blank, and
// very possible that the user didn't intend to fill out that default country value. So, we use the following rules to determine whether
// a location is bogus or not:
// IF $index == 0, then
// --> if no other fields are enabled, we consider the country to be important and save the location
// --> if other fields are enabled, but are all left blank, we consider the location empty and don't save
// --> if latitude and longitude coordinates are entered then we save the location
// IF $index != 1, then
// --> if country is default and no other fields are saved, we don't save
// --> if latitude and longitude coordinates are entered then we save the location
$keep = FALSE;
if (!empty($node->locations[$index]['country']) || !empty($node->locations[$index]['latitude']) && !empty($node->locations[$index]['longitude'])) {
if ($index == 0) {
// first location
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 {
// Else we have to check all the other fields to make sure they're not empty
foreach ($location_fields as $field) {
if ($field != 'country' && !empty($node->locations[$index][$field])) {
$keep = TRUE;
break;
}
}
}
}
else {
// not first location
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 (!$teaser) {
//drupal_set_html_head(location_geocode_meta_tags($node->location));
//}
}
}
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', 'value' => "<geo:lat>\n ". $node->locations[$index]['lat'] ."</geo:lat>\n <geo:long>". $node->locations[$index]['lon'] ."</geo:long>\n", 'namespace' => array('geo' => 'xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#"'));
$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'],
),
),
);
//$items[] = array('key' => 'geourl:latitude', 'value' => $node->locations[$index]['lat'], 'namespace' => array('geourl' => 'xmlns:geourl="http://geourl.org/rss/module/"'));
//$items[] = array('key' => 'geourl:longitude', 'value' => $node->locations[$index]['lon']);
}
}
}
return $items;
break;
}
}