You are here

function location_save in Location 7.5

Same name and namespace in other branches
  1. 5.3 location.module \location_save()
  2. 6.3 location.module \location_save()
  3. 7.3 location.module \location_save()
  4. 7.4 location.module \location_save()

Save a location.

This is the central function for saving a location.

Parameters

$location Location array to save.:

$cow Copy-on-write, i.e. whether or not to assign a new lid if something changes.:

$criteria Instance criteria. If the only instances known by location match: the criteria, the lid will be reused, regardless of $cow status. If no criteria is provided, there will be no attempt to reuse lids.

Return value

The lid of the saved location, or FALSE if the location is considered "empty."

1 call to location_save()
location_save_locations in ./location.module
Save associated locations.

File

./location.module, line 1204
Location module main routines. An implementation of a universal API for location manipulation. Provides functions for postal_code proximity searching, deep-linking into online mapping services. Currently, some options are configured through an…

Code

function location_save(&$location, $cow = TRUE, $criteria = array()) {

  // Quick settings fixup.
  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']) {

    // Workaround for people importing / generating locations.
    // Allows things like location_generate.module to work properly.
    $inhibit_geocode = TRUE;
    unset($location['inhibit_geocode']);
  }
  if (isset($location['delete_location']) && $location['delete_location']) {

    // Location is being deleted.
    // Consider it empty and return early.
    $location['lid'] = FALSE;
    return FALSE;
  }

  // If there's already a lid, we're editing an old location. Load it in.
  $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;
  }

  // Pull in fields that hold data currently not editable directly by the user.
  $location = array_merge($oldloc, $location);

  // Note: If the user clears all the fields, the location can still
  // be non-empty if the user didn't have access to everything..
  $filled = array();
  if (location_is_empty($location, $filled)) {

    // This location was empty, we don't need to continue.
    $location['lid'] = FALSE;
    return FALSE;
  }
  $changed = array();
  if (!location_calc_difference($oldloc, $location, $changed)) {

    // We didn't actually need to save anything.
    if (!empty($location['lid'])) {
      return $location['lid'];
    }
    else {

      // Unfilled location (@@@ Then how did we get here?)
      $location['lid'] = FALSE;
      return FALSE;
    }
  }

  // Perform geocoding logic, coordinate normalization, etc.
  _location_geo_logic($location, $changed, $filled, $inhibit_geocode);

  // If we are in COW mode, we *probabaly* need to make a new lid.
  if ($cow) {
    if (isset($location['lid']) && $location['lid']) {
      if (!empty($criteria)) {

        // Check for other instances.
        // See #306171 for more information.
        $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) {

          // If there were a different number of instances than instances matching the criteria,
          // we need a new LID.
          unset($location['lid']);
        }
      }
      else {

        // Criteria was not provided, we need a new LID.
        unset($location['lid']);
      }
    }
  }
  if (!empty($location['lid'])) {
    watchdog('location', 'Conserving lid %lid due to uniqueness.', array(
      '%lid' => $location['lid'],
    ));

    // Using a merge query instead of drupal_write_record to prevent failing to save
    // if the lid happens to not exist in {location}, which has been seen in the wild.
    // Tested in mysql, sqlite, and postgresql.
    $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'];
}