name);
}
}
/**
* Implementation of hook_schema().
*/
function location_schema() {
$schema['location'] = array(
'description' => 'Locational data managed by location.module.',
'fields' => array(
'lid' => array(
'description' => 'Primary Key: Unique location ID.',
'type' => 'serial',
'unsigned' => TRUE,
'not null' => TRUE,
),
'name' => array(
'description' => 'Place Name.',
'type' => 'varchar',
'length' => 255,
'default' => '',
'not null' => TRUE,
),
'street' => array(
'description' => 'Street address, line 1.',
'type' => 'varchar',
'length' => 255,
'default' => '',
'not null' => TRUE,
),
'additional' => array(
'description' => 'Street address, line 2.',
'type' => 'varchar',
'length' => 255,
'default' => '',
'not null' => TRUE,
),
'city' => array(
'description' => 'City.',
'type' => 'varchar',
'length' => 255,
'default' => '',
'not null' => TRUE,
),
'province' => array(
'description' => 'State / Province code.',
'type' => 'varchar',
'length' => 16,
'default' => '',
'not null' => TRUE,
),
'postal_code' => array(
'description' => 'Postal / ZIP code.',
'type' => 'varchar',
'length' => 16,
'default' => '',
'not null' => TRUE,
),
'country' => array(
'description' => 'Two letter ISO country code.',
'type' => 'char',
'length' => 2,
'not null' => TRUE,
'default' => '',
),
'latitude' => array(
'description' => 'Location latitude (decimal degrees).',
'type' => 'numeric',
'precision' => 10,
'scale' => 6, // @@@ Shouldn't these all be 7?
'not null' => TRUE,
'default' => 0.0,
),
'longitude' => array(
'description' => 'Location longitude (decimal degrees).',
'type' => 'numeric',
'precision' => 10,
'scale' => 6,
'not null' => TRUE,
'default' => 0.0,
),
'source' => array(
'description' => 'Source of the latitude and longitude data (Geocoder, user entered, invalid, etc.)',
'type' => 'int',
'size' => 'tiny',
'default' => 0,
'not null' => TRUE,
),
// @@@ Historical civicrm field that isn't applicable to location, I think..
'is_primary' => array(
'description' => 'Is this the primary location of an object? (unused, civicrm legacy field?).',
'type' => 'int',
'size' => 'tiny',
'default' => 0,
'not null' => TRUE,
),
),
'primary key' => array('lid'),
);
$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_revisions}.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'),
),
);
$schema['zipcodes'] = array(
'description' => 'Location.module zipcode database.',
'fields' => array(
'zip' => array(
'description' => 'Postal / ZIP code.',
'type' => 'varchar',
'length' => 16,
'not null' => TRUE,
'default' => '0', // @@@ Why?
),
'city' => array(
'description' => 'City.',
'type' => 'varchar',
'length' => 30,
'not null' => TRUE,
'default' => '',
),
'state' => array(
'description' => 'Province / State.',
'type' => 'varchar',
'length' => 30,
'not null' => TRUE,
'default' => '',
),
'latitude' => array(
'description' => 'Location latitude (decimal degrees).',
'type' => 'numeric',
'precision' => 10,
'scale' => 6,
'not null' => TRUE,
'default' => 0.0,
),
'longitude' => array(
'description' => 'Location longitude (decimal degrees).',
'type' => 'numeric',
'precision' => 10,
'scale' => 6,
'not null' => TRUE,
'default' => 0.0,
),
// @@@ Not used, an artifact of the original data dump format.
'timezone' => array(
'description' => 'Timezone (unused).',
'type' => 'int',
'size' => 'tiny',
'not null' => TRUE,
'default' => 0,
),
// @@@ Not used, an artifact of the original data dump format.
'dst' => array(
'description' => 'Daylight Savings Time (unused).',
'type' => 'int',
'size' => 'tiny',
'not null' => TRUE,
'default' => 0,
),
'country' => array(
'description' => 'Two letter ISO country code.',
'type' => 'char',
'length' => 2,
'not null' => TRUE,
'default' => '',
),
),
// @@@ This pk is invalid, see issue queue.
//'primary key' => array('country', 'zip'),
// @@@ These need reworked.
'indexes' => array(
'pc' => array('country', 'zip'),
'zip' => array('zip'),
// @@@ No combined one?
'latitude' => array('latitude'),
'longitude' => array('longitude'),
'country' => array('country'),
),
);
// Copied from system.module.
$schema['cache_location'] = array(
'description' => t('Generic cache table for caching things not separated out into their own tables. Contributed modules may also use this to store cached items.'),
'fields' => array(
'cid' => array(
'description' => t('Primary Key: Unique cache ID.'),
'type' => 'varchar',
'length' => 255,
'not null' => TRUE,
'default' => ''),
'data' => array(
'description' => t('A collection of data to cache.'),
'type' => 'blob',
'not null' => FALSE,
'size' => 'big'),
'expire' => array(
'description' => t('A Unix timestamp indicating when the cache entry should expire, or 0 for never.'),
'type' => 'int',
'not null' => TRUE,
'default' => 0),
'created' => array(
'description' => t('A Unix timestamp indicating when the cache entry was created.'),
'type' => 'int',
'not null' => TRUE,
'default' => 0),
'headers' => array(
'description' => t('Any custom HTTP headers to be added to cached data.'),
'type' => 'text',
'not null' => FALSE),
'serialized' => array(
'description' => t('A flag to indicate whether content is serialized (1) or not (0).'),
'type' => 'int',
'size' => 'small',
'not null' => TRUE,
'default' => 0)
),
'indexes' => array('expire' => array('expire')),
'primary key' => array('cid'),
);
//New location country table (needed for sorting
$schema['location_country'] = array(
'description' => 'Country data managed by location.module.',
'fields' => array(
'code' => array(
'description' => 'Primary Key: Two letter ISO Country Code',
'type' => 'char',
'length' => 2,
'not null' => TRUE,
),
'name' => array(
'description' => 'Full Country Name ',
'type' => 'varchar',
'length' => 255,
'default' => '',
'not null' => TRUE,
),
),
'primary key' => array('code'),
);
return $schema;
}
/**
* Legacy update 1.
* Convert tables to utf8.
*/
function location_update_1() {
// return _system_update_utf8(array('location', 'zipcodes'));
}
/**
* Legacy update 2.
* Fix a bug with the "us" entry in the "location_configured_countries" var.
*/
function location_update_2() {
$configured_countries = variable_get('location_configured_countries', array());
if ($configured_countries['us']) {
$configured_countries['us'] = 'us';
variable_set('location_configured_countries', $configured_countries);
}
return array();
}
/**
* Legacy update 3.
* Allow for postgresql support by renaming the oid column, which is a reserved
* name on postgresql.
*/
function location_update_3() {
$ret = array();
switch ($GLOBALS['db_type']) {
case 'mysql':
case 'mysqli':
$ret[] = update_sql("ALTER TABLE {location} CHANGE oid eid int unsigned NOT NULL default '0'");
break;
}
drupal_set_message("The schema for location module has been updated. The update is such that you may want to re-resave any views you have that may include locations.");
if (module_exists('views')) {
views_invalidate_cache();
}
return $ret;
}
/***************************************************************
PostgreSQL must be supported in all updates after this comment
***************************************************************/
/**
* Legacy update 4.
* Add "lid" as the new location key.
*/
function location_update_4() {
$ret = array();
switch ($GLOBALS['db_type']) {
case 'mysql':
case 'mysqli':
$ret[] = update_sql("ALTER TABLE {location} ADD COLUMN lid int(10) unsigned NOT NULL default '0' AFTER eid");
$result = db_query("SELECT eid, type FROM {location}");
$next_id = 0;
while ($row = db_fetch_object($result)) {
$next_id++;
db_query("UPDATE {location} SET lid = %d WHERE eid = %d AND type = '%s'", $next_id, $row->eid, $row->type);
}
$ret[] = update_sql("ALTER TABLE {location} DROP PRIMARY KEY");
$ret[] = update_sql("ALTER TABLE {location} ADD PRIMARY KEY (lid)");
db_query("INSERT INTO {sequences} (name, id) VALUES ('{location}_lid', %d)", $next_id);
$ret[] = update_sql("ALTER TABLE {location} ADD COLUMN is_primary tinyint NOT NULL default '0'");
$ret[] = update_sql("UPDATE {location} SET is_primary = 1 WHERE type = 'user'");
break;
case 'pgsql':
// help me
break;
}
foreach (node_get_types() as $type => $name) {
$new_setting = variable_get('location_'. $type, 0) ? 1 : 0;
variable_del('location_'. $type);
variable_set('location_maxnum_'. $type, $new_setting);
variable_set('location_defaultnum_'. $type, $new_setting);
}
return $ret;
}
/**
* Legacy update 5.
* Postgresql support that was missing from previous update.
*/
function location_update_5() {
$ret = array();
switch ($GLOBALS['db_type']) {
case 'pgsql':
$ret[] = update_sql("ALTER TABLE {location} DROP CONSTRAINT {location}_pkey");
$ret[] = update_sql("ALTER TABLE {location} RENAME TO {location}_old");
$ret[] = update_sql("CREATE TABLE {location} (
lid serial CHECK (lid >= 0),
eid int NOT NULL default '0' CHECK (eid >= 0),
type varchar(6) NOT NULL default '',
name varchar(255) default NULL,
street varchar(255) default NULL,
additional varchar(255) default NULL,
city varchar(255) default NULL,
province varchar(16) default NULL,
postal_code varchar(16) default NULL,
country char(2) default NULL,
latitude decimal(10,6) default NULL,
longitude decimal(10,6) default NULL,
source smallint default '0',
is_primary smallint default '0',
PRIMARY KEY (lid)
)");
$ret[] = update_sql("INSERT INTO {location}
(eid, type, name, street, additional, city, province, postal_code, country, latitude,
longitude, source) SELECT eid, type, name, street, additional, city, province,
postal_code, country, latitude, longitude, source FROM {location}_old");
$ret[] = update_sql("DROP TABLE {location}_old");
$ret[] = update_sql("UPDATE {location} SET is_primary = 1 WHERE type = 'user'");
break;
}
return $ret;
}
/**
* Legacy update 6.
* Use correct country code for Sweeden.
*/
function location_update_6() {
$ret = array();
switch ($GLOBALS['db_type']) {
case 'mysql':
case 'mysqli':
$ret[] = update_sql("UPDATE {location} SET country = 'se' WHERE country = 'sw'");
break;
case 'pgsql':
$ret[] = update_sql("UPDATE {location} SET country = 'se' WHERE country = 'sw'");
break;
}
return $ret;
}
/**
* Update 7 (Location 2.x)
* Generalize google geocoding so you don't have to enter the api key over and over.
*/
function location_update_7() {
$ret = array();
$services = array('google');
$general_geocoders_in_use = array();
switch ($GLOBALS['db_type']) {
case 'mysql':
case 'mysqli':
$result = db_query('SELECT * FROM {variable} WHERE name REGEXP \'^location_geocode_[a-z][a-z]$\'');
while ($row = db_fetch_object($result)) {
$value_decoded = unserialize($row->value);
if (!in_array($value_decoded, $services)) {
$ret[] = update_sql('UPDATE {variable} SET value = \''. serialize($value_decoded .'|'. substr($row->name, 17)) .'\' WHERE name = \''. $row->name .'\'');
}
else {
$general_geocoders_in_use[$value_decoded] = $value_decoded;
}
}
$key = db_result(db_query('SELECT value FROM {variable} WHERE name REGEXP \'^location_geocode_[a-z][a-z]_google_apikey$\' LIMIT 1'));
$ret[] = update_sql('DELETE FROM {variable} WHERE name REGEXP \'^location_geocode_[a-z][a-z]_google_apikey$\'');
$ret[] = update_sql('INSERT INTO {variable} (name, value) VALUES (\'location_geocode_google_apikey\', \''. $key .'\')');
$ret[] = update_sql('DELETE FROM {cache} WHERE cid = \'variables\'');
variable_set('location_general_geocoders_in_use', $general_geocoders_in_use);
break;
case 'pgsql':
$result = db_query('SELECT * FROM {variable} WHERE name REGEXP \'^location_geocode_[a-z][a-z]$\'');
while ($row = db_fetch_object($result)) {
$value_decoded = unserialize($row->value);
if (!in_array($value_decoded, $services)) {
$ret[] = update_sql('UPDATE {variable} SET value = \''. serialize($value_decoded .'|'. substr($row->name, 17)) .'\' WHERE name = \''. $row->name .'\'');
}
else {
$general_geocoders_in_use[$value_decoded] = $value_decoded;
}
}
$key = db_result(db_query('SELECT value FROM {variable} WHERE name REGEXP \'^location_geocode_[a-z][a-z]_google_apikey$\' LIMIT 1'));
$ret[] = update_sql('DELETE FROM {variable} WHERE name REGEXP \'^location_geocode_[a-z][a-z]_google_apikey$\'');
$ret[] = update_sql('INSERT INTO {variable} (name, value) VALUES (\'location_geocode_google_apikey\', \''. $key .'\')');
$ret[] = update_sql('DELETE FROM {cache} WHERE cid = \'variables\'');
variable_set('location_general_geocoders_in_use', $general_geocoders_in_use);
break;
}
return $ret;
}
/**
* Location 3.x update 1.
* Add location specific cache table.
*/
function location_update_5300() {
$ret = array();
switch ($GLOBALS['db_type']) {
case 'mysql':
case 'mysqli':
$ret[] = update_sql("CREATE TABLE {cache_location} (
cid varchar(255) NOT NULL default '',
data longblob,
expire int NOT NULL default '0',
created int NOT NULL default '0',
headers text,
PRIMARY KEY (cid),
INDEX expire (expire)
) /*!40100 DEFAULT CHARACTER SET UTF8 */ ");
break;
case 'pgsql':
$ret[] = update_sql("CREATE TABLE {cache_location} (
cid varchar(255) NOT NULL default '',
data bytea,
expire int NOT NULL default '0',
created int NOT NULL default '0',
headers text,
PRIMARY KEY (cid)
)");
$ret[] = update_sql("CREATE INDEX {cache_location}_expire_idx ON {cache_location} (expire)");
break;
}
return $ret;
}
/**
* 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.
*/
function location_update_5301() {
$ret = array();
switch ($GLOBALS['db_type']) {
case 'mysql':
case 'mysqli':
db_query("
CREATE TABLE {location_instance} (
nid int UNSIGNED DEFAULT NULL,
vid int UNSIGNED DEFAULT NULL,
uid int UNSIGNED DEFAULT NULL,
genid varchar(255) NOT NULL default '',
lid int UNSIGNED NOT NULL DEFAULT '0',
INDEX {location_instance}_nid_idx (nid),
INDEX {location_instance}_vid_idx (vid),
INDEX {location_instance}_uid_idx (uid),
INDEX {location_instance}_genid_idx (genid),
INDEX {location_instance}_lid_idx (lid)
) /*!40100 DEFAULT CHARACTER SET utf8 */");
break;
case 'pgsql':
$ret[] = update_sql("
CREATE TABLE {location_instance} (
nid int DEFAULT NULL CHECK (nid >= 0 OR nid IS NULL),
vid int DEFAULT NULL CHECK (vid >= 0 OR vid IS NULL),
uid int DEFAULT NULL CHECK (uid >= 0 OR uid IS NULL),
genid varchar(255) NOT NULL default '',
lid int NOT NULL DEFAULT '0' CHECK (lid >= 0)
)");
$ret[] = update_sql('CREATE INDEX {location_instance}_nid_idx ON {location_instance} (nid)');
$ret[] = update_sql('CREATE INDEX {location_instance}_vid_idx ON {location_instance} (vid)');
$ret[] = update_sql('CREATE INDEX {location_instance}_uid_idx ON {location_instance} (uid)');
$ret[] = update_sql('CREATE INDEX {location_instance}_lid_idx ON {location_instance} (lid)');
$ret[] = update_sql('CREATE INDEX {location_instance}_genid_idx ON {location_instance} (genid)');
break;
}
// 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.
$ret[] = update_sql("INSERT INTO {location_instance} (nid,vid,lid) (SELECT nr.nid, nr.vid, l.lid FROM {node_revisions} nr INNER JOIN {node_revisions} nr2 ON nr.nid = nr2.nid INNER JOIN {location} l ON nr2.vid = l.eid AND l.type = 'node')");
// Users is much simpler.
$ret[] = update_sql("INSERT INTO {location_instance} (uid,lid) (SELECT eid, lid FROM {location} WHERE type = 'user')");
// Aug 18 2008:
// Save everything else in genid.
switch ($GLOBALS['db_type']) {
case 'mysql':
case 'mysqli':
$ret[] = update_sql("INSERT INTO {location_instance} (genid, lid) (SELECT CONCAT(type, ':', eid), lid FROM {location} WHERE type <> 'user' AND type <> 'node')");
break;
case 'pgsql':
$ret[] = update_sql("INSERT INTO {location_instance} (genid, lid) (SELECT type||':'||eid, lid FROM {location} WHERE type <> 'user' AND type <> 'node')");
break;
}
// Remove now unused columns.
$ret[] = update_sql("ALTER TABLE {location} DROP COLUMN type");
$ret[] = update_sql("ALTER TABLE {location} DROP COLUMN eid");
// General cleanup.
variable_del('location_user'); // Removed in favor of permission check.
// 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 LIKE 'location_%s%%'", $field);
while ($row = db_fetch_object($result)) {
$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);
return $ret;
}
/**
* Location 3.x update 3.
* Add genid to {location_instance}.
*/
function location_update_5302() {
$ret = array();
// OK, here's the deal. I retrofitted 5301 on Aug 18 2008 to integrate the genid.
// This was needed to fix the pre location 3.x todo item regarding keeping non
// user, non node data intact. People doing an update after Aug 18 will already
// have the genid column in place, so it can be safely skipped.
if (!variable_get('location_update_5301_retrofit', FALSE)) {
switch ($GLOBALS['db_type']) {
case 'mysql':
case 'mysqli':
$ret[] = update_sql("ALTER TABLE {location_instance} ADD COLUMN genid varchar(255) NOT NULL default '' AFTER uid");
$ret[] = update_sql('CREATE INDEX {location_instance}_genid_idx ON {location_instance} (genid)');
break;
case 'pgsql':
db_add_column($ret, 'location_instance', 'genid', 'varchar(255)', array('not null' => TRUE, 'default' => "''"));
$ret[] = update_sql('CREATE INDEX {location_instance}_genid_idx ON {location_instance} (genid)');
break;
}
}
return $ret;
}
/**
* Location 3.x update 4.
* Shuffle more variables around.
*/
function location_update_5303() {
$ret = array();
$types = array();
$result = db_query("SELECT name FROM {variable} WHERE name LIKE 'location_display_teaser_%'");
while ($row = db_fetch_object($result)) {
$type = substr($row->name, 24);
$types[$type]['teaser'] = variable_get('location_display_teaser_'. $type, TRUE);
$types[$type]['full'] = variable_get('location_display_full_'. $type, TRUE);
$types[$type]['weight'] = variable_get('location_display_weight_'. $type, 0);
// @@@ Combine location_suppress_country and country require settings to set this up?
$types[$type]['hide'] = array();
}
foreach ($types as $type => $value) {
variable_set("location_display_$type", $value);
variable_del("location_display_teaser_$type");
variable_del("location_display_full_$type");
variable_del("location_display_weight_$type");
}
return $ret;
}
// @@@ Does 5303 need rerun in some circumstances?
/**
* Drupal 6 location 3.x update.
*/
function location_update_6301() {
$t = get_t();
drupal_set_message($t('Note: Location.module update 6301 will generate several warnings/failures regarding indexes and primary keys if you are upgrading from one of the 6.x test releases. These warnings can be safely disregarded in this case.'));
$ret = array();
// Update cache table.
db_drop_table($ret, 'cache_location');
$schema['cache_location'] = array(
'description' => t('Generic cache table for caching things not separated out into their own tables. Contributed modules may also use this to store cached items.'),
'fields' => array(
'cid' => array(
'description' => t('Primary Key: Unique cache ID.'),
'type' => 'varchar',
'length' => 255,
'not null' => TRUE,
'default' => ''),
'data' => array(
'description' => t('A collection of data to cache.'),
'type' => 'blob',
'not null' => FALSE,
'size' => 'big'),
'expire' => array(
'description' => t('A Unix timestamp indicating when the cache entry should expire, or 0 for never.'),
'type' => 'int',
'not null' => TRUE,
'default' => 0),
'created' => array(
'description' => t('A Unix timestamp indicating when the cache entry was created.'),
'type' => 'int',
'not null' => TRUE,
'default' => 0),
'headers' => array(
'description' => t('Any custom HTTP headers to be added to cached data.'),
'type' => 'text',
'not null' => FALSE),
'serialized' => array(
'description' => t('A flag to indicate whether content is serialized (1) or not (0).'),
'type' => 'int',
'size' => 'small',
'not null' => TRUE,
'default' => 0)
),
'indexes' => array('expire' => array('expire')),
'primary key' => array('cid'),
);
db_create_table($ret, 'cache_location', $schema['cache_location']);
// LID 0 causes all sorts of issues, and will break our update routine
// unless we handle it beforehand.
// Since we're so nice, we're gonna renumber it for the user.
if (db_result(db_query('SELECT COUNT(*) FROM {location} WHERE lid = 0'))) {
$lid = 1 + db_result(db_query('SELECT MAX(lid) FROM {location}'));
drupal_set_message(t('Note: A location with lid 0 was found in your database. It has been moved to lid %lid. You may wish to verify it manually, as lid 0 is usually a corrupt entry.', array('%lid' => $lid)));
// $lid is safe to inject here.
$ret[] = update_sql("UPDATE {location} SET lid = $lid WHERE lid = 0");
$ret[] = update_sql("UPDATE {location_instance} SET lid = $lid WHERE lid = 0");
}
// Field changes
// {location}
// {location}.lid -- Becomes a serial.
db_drop_primary_key($ret, 'location');
db_change_field($ret, 'location', 'lid', 'lid',
array('type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE),
array('primary key' => array('lid')));
// (The rest of the changes to this table were moved to update 6302 due to a bug.)
// {location_instance}
// Fix oddly named indexes -- Was using the postgresql method for both.
switch ($GLOBALS['db_type']) {
case 'mysql':
case 'mysqli':
db_drop_index($ret, 'location_instance', '{location_instance}_nid_idx');
db_drop_index($ret, 'location_instance', '{location_instance}_vid_idx');
db_drop_index($ret, 'location_instance', '{location_instance}_uid_idx');
db_drop_index($ret, 'location_instance', '{location_instance}_genid_idx');
db_drop_index($ret, 'location_instance', '{location_instance}_lid_idx');
break;
case 'pgsql':
db_drop_index($ret, 'location_instance', 'nid');
db_drop_index($ret, 'location_instance', 'vid');
db_drop_index($ret, 'location_instance', 'uid');
db_drop_index($ret, 'location_instance', 'genid');
db_drop_index($ret, 'location_instance', 'lid');
}
// Fill in nulls.
$ret[] = update_sql('UPDATE {location_instance} SET nid = 0 WHERE nid IS NULL');
$ret[] = update_sql('UPDATE {location_instance} SET vid = 0 WHERE vid IS NULL');
$ret[] = update_sql('UPDATE {location_instance} SET uid = 0 WHERE uid IS NULL');
$ret[] = update_sql("UPDATE {location_instance} SET genid = '' WHERE genid IS NULL");
// {location_instance}.nid
db_change_field($ret, 'location_instance', 'nid', 'nid', array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0));
// {location_instance}.vid
db_change_field($ret, 'location_instance', 'vid', 'vid', array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0));
// {location_instance}.uid
db_change_field($ret, 'location_instance', 'uid', 'uid', array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0));
// {location_instance}.genid
db_change_field($ret, 'location_instance', 'genid', 'genid', array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => ''));
// {location_instance}.lid
db_change_field($ret, 'location_instance', 'lid', 'lid', array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0));
// Readd indexes.
db_add_index($ret, 'location_instance', 'nid', array('nid'));
db_add_index($ret, 'location_instance', 'vid', array('vid'));
db_add_index($ret, 'location_instance', 'uid', array('uid'));
db_add_index($ret, 'location_instance', 'genid', array('genid'));
db_add_index($ret, 'location_instance', 'lid', array('lid'));
// {zipcodes}
// Drop primary key.
db_drop_primary_key($ret, 'zipcodes');
return $ret;
}
/**
* Drupal 6 location 3.x update, part 2.
*/
function location_update_6302() {
$ret = array();
// OK, here's the update to fix the previous update which had a few problems
// when upgrading from pre-rc 6.x versions.
// The "mismatch between mysql and postgresql" was actually applicable to
// 6.x-3.0 pre-rc1 as well, but I didn't notice because I accidentally added
// the not null when reformatting the schema.
$ret[] = update_sql('UPDATE {location} SET is_primary = 0 WHERE is_primary IS NULL');
db_change_field($ret, 'location', 'is_primary', 'is_primary', array('type' => 'int', 'size' => 'tiny', 'default' => 0, 'not null' => TRUE));
// Fix zipcode mismatches caused by the same problem.
// There shouldn't be any rows like this, but it doesn't hurt to be sure.
$ret[] = update_sql('UPDATE {zipcodes} SET zip = 0 WHERE zip IS NULL');
// Set not null.
db_change_field($ret, 'zipcodes', 'zip', 'zip', array('type' => 'varchar', 'length' => 16, 'not null' => TRUE, 'default' => '0'));
// Prepare latitude and longitude for the same.
$ret[] = update_sql('UPDATE {zipcodes} SET latitude = 0.0 WHERE latitude IS NULL');
$ret[] = update_sql('UPDATE {zipcodes} SET longitude = 0.0 WHERE longitude IS NULL');
// Set not null.
db_change_field($ret, 'zipcodes', 'latitude', 'latitude', array('type' => 'numeric', 'not null' => TRUE, 'default' => 0, 'precision' => 10, 'scale' => 6));
db_change_field($ret, 'zipcodes', 'longitude', 'longitude', array('type' => 'numeric', 'not null' => TRUE, 'default' => 0, 'precision' => 10, 'scale' => 6));
// Prepare country.
$ret[] = update_sql("UPDATE {zipcodes} SET country = '' WHERE country IS NULL");
// Set not null.
db_change_field($ret, 'zipcodes', 'country', 'country', array('type' => 'char', 'length' => 2, 'not null' => TRUE, 'default' => ''));
// Fix up possible {location} problems from previous update that could be caused if you had NULLed fields.
// Set defaults
$ret[] = update_sql("UPDATE {location} SET name = '' WHERE name IS NULL");
$ret[] = update_sql("UPDATE {location} SET street = '' WHERE street IS NULL");
$ret[] = update_sql("UPDATE {location} SET additional = '' WHERE additional IS NULL");
$ret[] = update_sql("UPDATE {location} SET city = '' WHERE city IS NULL");
$ret[] = update_sql("UPDATE {location} SET province = '' WHERE province IS NULL");
$ret[] = update_sql("UPDATE {location} SET postal_code = '' WHERE postal_code IS NULL");
$ret[] = update_sql("UPDATE {location} SET country = '' WHERE country IS NULL");
$ret[] = update_sql('UPDATE {location} SET latitude = 0.0 WHERE latitude IS NULL');
$ret[] = update_sql('UPDATE {location} SET longitude = 0.0 WHERE longitude IS NULL');
$ret[] = update_sql('UPDATE {location} SET source = 0 WHERE source IS NULL');
// {location}.name -- NOT NULL
db_change_field($ret, 'location', 'name', 'name', array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => ''));
// {location}.street -- NOT NULL
db_change_field($ret, 'location', 'street', 'street', array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => ''));
// {location}.additional -- NOT NULL
db_change_field($ret, 'location', 'additional', 'additional', array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => ''));
// {location}.city -- NOT NULL
db_change_field($ret, 'location', 'city', 'city', array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => ''));
// {location}.province -- NOT NULL
db_change_field($ret, 'location', 'province', 'province', array('type' => 'varchar', 'length' => 16, 'not null' => TRUE, 'default' => ''));
// {location}.postal_code -- NOT NULL
db_change_field($ret, 'location', 'postal_code', 'postal_code', array('type' => 'varchar', 'length' => 16, 'not null' => TRUE, 'default' => ''));
// {location}.country -- NOT NULL
db_change_field($ret, 'location', 'country', 'country', array('type' => 'char', 'length' => 2, 'not null' => TRUE, 'default' => ''));
// {location}.latitude
db_change_field($ret, 'location', 'latitude', 'latitude', array('type' => 'numeric', 'precision' => 10, 'scale' => 6, 'not null' => TRUE, 'default' => 0.0));
// {location}.longitude
db_change_field($ret, 'location', 'longitude', 'longitude', array('type' => 'numeric', 'precision' => 10, 'scale' => 6, 'not null' => TRUE, 'default' => 0.0));
// {location}.source
db_change_field($ret, 'location', 'source', 'source', array('type' => 'int', 'size' => 'tiny', 'not null' => TRUE, 'default' => 0));
return $ret;
}
/**
* Drupal 6 location 3.x update, part 3.
*/
function location_update_6303() {
$ret = array();
if (!variable_get('location_update_5304_done', FALSE)) {
// Do the same updates as 5304.
// Delete unused variables.
variable_del('location_configured_countries');
variable_del('location_garbagecollect');
// Update province code for Italy/Forlì-Cesena.
$ret[] = update_sql("UPDATE {location} SET province = 'FC' WHERE country = 'it' AND province = 'FO'");
// Update province code for Italy/Pesaro e Urbino.
$ret[] = update_sql("UPDATE {location} SET province = 'PU' WHERE country = 'it' AND province = 'PS'");
// Do one final garbage collection by hand.
$ret[] = update_sql('DELETE FROM {location} WHERE lid NOT IN (SELECT lid FROM {location_instance})');
// Garbage collect {location_phone} by hand.
if (db_table_exists('location_phone')) {
$ret[] = update_sql('DELETE FROM {location_phone} WHERE lid NOT IN (SELECT lid FROM {location})');
}
// Garbage collect {location_fax} by hand.
if (db_table_exists('location_fax')) {
$ret[] = update_sql('DELETE FROM {location_fax} WHERE lid NOT IN (SELECT lid FROM {location})');
}
variable_del('location_update_5304_done');
}
return $ret;
}
/**
* Upgrade all of the settings variables to the new unified system.
*/
function location_update_6304() {
// Skip this update if it was already done on the 5.x side.
if (variable_get('location_5305_done', FALSE)) {
variable_del('location_5305_done');
return array();
}
$ret = array();
$variables = array();
$todelete = array();
$base = array(
'multiple' => array(
'min' => 0,
'max' => 0,
'add' => 3,
),
'form' => array(
'weight' => 0,
'collapsible' => TRUE,
'collapsed' => TRUE,
'fields' => array(),
),
'display' => array(
'weight' => 0,
'hide' => array(),
),
);
// Pull in user settings.
$variables['location_settings_user'] = $base;
$tmp = &$variables['location_settings_user'];
// Users previously could not have multiple locations, initialize with those
// settings.
$tmp['multiple'] = array(
'min' => 0,
'max' => 1,
'add' => 3,
);
$tmp['form']['weight'] = variable_get('location_user_weight', 9);
$tmp['form']['collapsible'] = variable_get('location_user_collapsible', TRUE);
$tmp['form']['collapased'] = variable_get('location_user_collapsed', TRUE);
$tmp['form']['fields'] = variable_get('location_user_fields', array());
// Pull in node settings.
$result = db_query("SELECT name FROM {variable} WHERE name LIKE 'location_maxnum_%'");
while ($row = db_fetch_object($result)) {
$type = substr($row->name, 16);
$todelete[] = $type;
$variables["location_settings_node_$type"] = $base;
$tmp = &$variables["location_settings_node_$type"];
$tmp['multiple']['min'] = 1; // Old behavior was to have the first one be required.
$tmp['multiple']['max'] = variable_get("location_maxnum_$type", 0);
$tmp['multiple']['add'] = variable_get("location_defaultnum_$type", 3);
$tmp['form']['weight'] = variable_get("location_weight_$type", 9);
$tmp['form']['collapsible'] = variable_get("location_collapsible_$type", TRUE);
$tmp['form']['collapsed'] = variable_get("location_collapsed_$type", TRUE);
$tmp['form']['fields'] = variable_get("location_fields_$type", array());
$tmp['rss']['mode'] = variable_get("location_rss_$type", 'simple');
$tmp['display'] = variable_get("location_display_$type", array(
'teaser' => TRUE,
'full' => TRUE,
'weight' => 0,
'hide' => array(),
));
}
foreach ($variables as $name => $value) {
variable_set($name, $value);
}
// Delete old node variables.
foreach ($todelete as $key) {
// variable_del("location_maxnum_$key");
// variable_del("location_defaultnum_$key");
variable_del("location_weight_$key");
variable_del("location_collapsible_$key");
variable_del("location_collapsed_$key");
variable_del("location_fields_$key");
variable_del("location_rss_$key");
variable_del("location_display_$key");
}
// Delete old user variables.
variable_del('location_user_weight');
variable_del('location_user_collapsible');
variable_del('location_user_collapsed');
variable_del('location_user_fields');
return $ret;
}
/**
* Disabled due to some typos, moved to 6306.
*/
function location_update_6305() {
return array();
}
/**
* Add per-location-field weights and defaults.
*/
function location_update_6306() {
// Skip this update if it was already done on the 5.x side.
if (variable_get('location_5306_done', FALSE)) {
variable_del('location_5306_done');
return array();
}
$ret = array();
$result = db_query("SELECT name FROM {variable} WHERE name LIKE 'location_settings_%'");
while ($row = db_fetch_object($result)) {
$var = variable_get($row->name, array());
$collect = $var['form']['fields'];
$var['form']['fields'] = array();
foreach ($collect as $k => $v) {
$var['form']['fields'][$k]['collect'] = $v;
}
// Country 3 has changed to 4 to make requirements code easier.
if (isset($var['form']['fields']['country']['collect']) && $var['form']['fields']['country']['collect'] == 3) {
$var['form']['fields']['country']['collect'] = 4;
}
// Weight and default values don't need to get set for now.
variable_set($row->name, $var);
}
return $ret;
}
/**
* I hate to waste a whole update on this, but people will need to know.
*/
function location_update_6307() {
$ret = array();
drupal_set_message(t("Note: Location module has now split off user location support into a seperate module, called User Locations. It has been enabled for you. If you don't want user locations, visit the modules page and disable it.", array('!url' => url('admin/build/modules'))));
if (module_exists('location')) {
module_enable(array('location_user'));
}
else {
drupal_set_message(t("Note: Refusing to enable location_user.module, as location.module is not currently enabled."));
}
return $ret;
}
/**
* Well, I do have 99 updates to use :P
*/
function location_update_6308() {
$ret = array();
drupal_set_message(t("Note: Location module has now split off node location support into a seperate module, called Node Locations. It has been enabled for you. If you don't want node locations, visit the modules page and disable it.", array('!url' => url('admin/build/modules'))));
if (module_exists('location')) {
module_enable(array('location_node'));
}
else {
drupal_set_message(t("Note: Refusing to enable location_node.module, as location.module is not currently enabled."));
}
return $ret;
}
/**
* There has been a change in the options for the views distance/proximity filter.
* The old options need to be migrated into the new.
*/
function location_update_6309() {
$ret = array();
$updated_views = array();
if (module_exists('views')) {
$views = views_get_all_views();
foreach ($views as $view) {
$modified = FALSE;
// For each view check all filters of all displays for the distance field filter.
foreach ($view->display as $did => $display) {
if (isset($display->display_options['filters']) && !empty($display->display_options['filters'])) {
foreach ($display->display_options['filters'] as $fid => $filter) {
if ($filter['table'] == 'location' && $filter['field'] == 'distance') {
// Set the origin (new option) from the type (old option).
$origin = '';
switch ($filter['type']) {
case 'latlon':
$origin = 'static';
break;
case 'postal':
case 'postal_default':
case 'latlon_gmap':
$origin = $filter['type'];
break;
}
if ($origin) {
$view->display[$did]->display_options['filters'][$fid]['origin'] = $origin;
unset($view->display[$did]->display_options['filters'][$fid]['type']);
$modified = TRUE;
}
}
}
}
}
// Save the view if we changed any options on any diplays.
// Views caches are cleared during save so we don't have to do it.
if ($modified) {
$updated_views[] = $view->name;
$view->save();
}
}
}
if (!empty($updated_views)) {
drupal_set_message(t("Note: The 'Form type' option for the 'Location: Distance / Proximity' filter in views has been changed and is now the 'Origin' option. The following views were using that setting and have been updated to use the new setting: %views.", array('%views' => implode(', ', $updated_views))));
}
return $ret;
}
/**
* Adds the Country code to name table "location_country". It is created from the included array country array.
*/
function location_update_6310() {
//Create the new table
$schema = location_schema() ;
db_create_table($ret, 'location_country', $schema['location_country']);
//Fill it.
$sql = 'INSERT INTO {location_country} (code, name) VALUES ';
$sql2 = '';
$countries = location_get_iso3166_list();
foreach($countries as $code => $name){
$variables = array();
$variables[] = $code;
$variables[] = $name;
$sql2 = "('$code', '$name')";
db_query($sql . $sql2);
}
}