You are here

function location_update_5301 in Location 7.3

Same name and namespace in other branches
  1. 5.3 location.install \location_update_5301()
  2. 6.3 location.install \location_update_5301()
  3. 7.5 location.install \location_update_5301()
  4. 7.4 location.install \location_update_5301()

Location 3.x update 2.

Normalize the location table. This allows:

  • Making the loading and saving code cleaner.
  • Fixing a longstanding bug with revisions.
  • Having the same location on multiple nodes/users/both.
  • Garbage collecting unused locations periodically.
  • Having full support for deletions.
  • Full revisions support.

Note that the location_instance table does NOT have a primary key. This is on purpose. It's a N:M join table.

File

./location.install, line 589
Install, update and uninstall functions for the location module.

Code

function location_update_5301() {
  $schema['location_instance'] = array(
    'description' => 'N:M join table to join locations to other tables.',
    'fields' => array(
      'nid' => array(
        'description' => 'Reference to {node}.nid.',
        'type' => 'int',
        'unsigned' => TRUE,
        'not null' => TRUE,
        'default' => 0,
      ),
      'vid' => array(
        'description' => 'Reference to {node_revision}.vid.',
        'type' => 'int',
        'unsigned' => TRUE,
        'not null' => TRUE,
        'default' => 0,
      ),
      'uid' => array(
        'description' => 'Reference to {users}.uid.',
        'type' => 'int',
        'unsigned' => TRUE,
        'not null' => TRUE,
        'default' => 0,
      ),
      'genid' => array(
        'description' => 'Generic reference key.',
        'type' => 'varchar',
        'length' => 255,
        'not null' => TRUE,
        'default' => '',
      ),
      'lid' => array(
        'description' => 'Reference to {location}.lid.',
        'type' => 'int',
        'unsigned' => TRUE,
        'not null' => TRUE,
        'default' => 0,
      ),
    ),
    'indexes' => array(
      'nid' => array(
        'nid',
      ),
      'vid' => array(
        'vid',
      ),
      'uid' => array(
        'uid',
      ),
      'genid' => array(
        'genid',
      ),
      'lid' => array(
        'lid',
      ),
    ),
  );
  db_create_table('location_instance', $schema['location_instance']);

  // Synthesise node location data based on what we have.
  // Storage of locations was previously stored against node revision, BUT the
  // data was not properly duplicated by revision (i.e. only the latest revision
  // carried the data.)
  // Joining like this allows us to backfill all the old revisions with the current
  // data, which is not nice but better than having no data at all when viewing
  // old revisions.
  $query = db_select('node_revision', 'nr');
  $query
    ->join('node_revision', 'nr2', 'nr.nid = nr2.nid');
  $query
    ->join('location', 'l', "nr2.vid = l.eid AND l.type = 'node'");
  $query
    ->addField('nr', 'nid');
  $query
    ->addField('nr', 'vid');
  $query
    ->addField('l', 'lid');
  db_insert('location_instance')
    ->fields(array(
    'nid',
    'vid',
    'lid',
  ))
    ->from($query)
    ->execute();

  // Users is much simpler.
  $query = db_select('location', 'l');
  $query
    ->addField('l', 'eid');
  $query
    ->addField('l', 'lid');
  $query
    ->condition('type', 'user');
  db_insert('location_instance')
    ->fields(array(
    'uid',
    'lid',
  ))
    ->from($query)
    ->execute();

  // Aug 18 2008:
  // Save everything else in genid.
  $query = db_select('location', 'l');
  $query
    ->addExpression("CONCAT(l.type, ':', l.eid)");
  $query
    ->addField('l', 'lid');
  $query
    ->condition('type', 'user', '<>');
  $query
    ->condition('type', 'node', '<>');
  db_insert('location_instance')
    ->fields(array(
    'genid',
    'lid',
  ))
    ->from($query)
    ->execute();

  // Remove now unused columns.
  db_drop_field('location', 'type');
  db_drop_field('location', 'eid');

  // General cleanup.
  // Removed in favor of permission check.
  variable_del('location_user');

  // Variable consolidation (as part of the element based system)
  // We're doing this "raw" so we can be sure we got everything moved over,
  // INCLUDING content types that were deleted in the past.
  // This will let us do better cleanup sometime in the future.
  $data = array();
  $todelete = array();
  foreach (array(
    'name',
    'street',
    'additional',
    'city',
    'province',
    'postal_code',
    'country',
    'phone',
    'fax',
  ) as $field) {
    $result = db_query("SELECT name, value FROM {variable} WHERE name > :name", array(
      ':name' => "location_{$field}%",
    ));
    foreach ($result as $row) {
      $data[substr($row->name, strlen($field) + 10)][$field] = (string) (int) unserialize($row->value);
      $todelete[] = $row->name;
    }
  }
  foreach ($data as $type => $value) {

    // We aren't going to trust that hook_locationapi is operational.
    // So, stick with some conservative defaults.
    $value = array_merge(array(
      'name' => '1',
      'street' => '1',
      // Additional is left out of this list intentionally.
      'city' => '0',
      'province' => '0',
      'postal_code' => '0',
      'country' => '1',
    ), $value);
    if (!isset($value['additional'])) {

      // Initialize additional to match street.
      $value['additional'] = $value['street'];
    }
    variable_set('location_fields_' . $type, $value);
  }
  foreach ($todelete as $key) {
    variable_del($key);
  }

  // This update was retrofitted on Aug 18, 2008. Set a flag for use by
  // the next update in order to handle the case where someone has already
  // updated to EXACTLY schema revision 5301 before the retrofit took effect.
  // People who migrated past this point before that date may have the following
  // inconsistencies:
  // A) location_{field}_{type} variables were not collected for content types
  // that had been deleted in the past.
  // B) Any locations with the 'type' field set to something other than 'node'
  // or 'user' did not get entries in {location_instance}.
  variable_set('location_update_5301_retrofit', TRUE);
}