redirect.install in Redirect 7.2
Same filename and directory in other branches
Install, update and uninstall functions for the redirect module.
File
redirect.installView source
<?php
/**
* @file
* Install, update and uninstall functions for the redirect module.
*/
/**
* Implements hook_schema().
*/
function redirect_schema() {
$schema['redirect'] = array(
'description' => 'Stores information on redirects.',
'fields' => array(
'rid' => array(
'type' => 'serial',
'not null' => TRUE,
'description' => 'Primary Key: Unique redirect ID.',
),
'hash' => array(
'type' => 'varchar',
'length' => 64,
'not null' => TRUE,
'description' => 'A unique hash based on source, source_options, and language.',
),
'type' => array(
'type' => 'varchar',
'length' => 64,
'not null' => TRUE,
'default' => '',
'description' => "The redirect type; if value is 'redirect' it is a normal redirect handled by the module.",
),
'uid' => array(
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
'default' => 0,
'description' => 'The {users}.uid of the user who created the redirect.',
),
'source' => array(
'type' => 'varchar',
'length' => 900,
'not null' => TRUE,
'description' => 'The source path to redirect from.',
),
'source_options' => array(
'type' => 'blob',
'not null' => TRUE,
'serialize' => TRUE,
'description' => 'A serialized array of source options.',
),
'redirect' => array(
'type' => 'varchar',
'length' => 900,
'not null' => TRUE,
'description' => 'The destination path to redirect to.',
),
'redirect_options' => array(
'type' => 'blob',
'not null' => TRUE,
'serialize' => TRUE,
'description' => 'A serialized array of redirect options.',
),
'language' => array(
'description' => 'The language this redirect is for; if blank, the alias will be used for unknown languages.',
'type' => 'varchar',
'length' => 12,
'not null' => TRUE,
'default' => 'und',
),
'status_code' => array(
'type' => 'int',
'size' => 'small',
'not null' => TRUE,
'description' => 'The HTTP status code to use for the redirect.',
),
'count' => array(
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
'default' => 0,
'description' => 'The number of times the redirect has been used.',
),
'access' => array(
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
'default' => 0,
'description' => 'The timestamp of when the redirect was last accessed.',
),
'status' => array(
'type' => 'int',
'size' => 'small',
'not null' => TRUE,
'default' => 1,
'description' => 'Boolean indicating whether the redirect is enabled (visible to non-administrators).',
),
),
'primary key' => array(
'rid',
),
'unique keys' => array(
'hash' => array(
'hash',
),
),
'indexes' => array(
'expires' => array(
'type',
'access',
),
'status_source_language' => array(
'status',
// Limit the number of characters used by the index.
// That allows avoiding the risk to have a PDOException
// caused the DB index limitations of some databases.
// see https://www.drupal.org/project/redirect/issues/2057615.
array(
'source',
255,
),
'language',
),
'redirect' => array(
'redirect',
),
),
);
return $schema;
}
/**
* Implements hook_install().
*/
function redirect_install() {
// If the path redirect table exists then run the migration.
if (db_table_exists('path_redirect')) {
$file = drupal_get_path('module', 'redirect') . '/redirect.install';
$batch = array(
'title' => t('Migrating redirects'),
'operations' => array(
array(
'_redirect_migrate_path_redirect_redirects',
array(),
),
),
'finished' => '_redirect_migrate_finished_callback',
'file' => $file,
);
batch_set($batch);
}
}
/**
* Implements hook_uninstall().
*/
function redirect_uninstall() {
drupal_load('module', 'redirect');
$variables = array_keys(redirect_variables());
foreach ($variables as $variable) {
variable_del($variable);
}
}
/**
* Add the {redirect}.count field.
*/
function redirect_update_1() {
$field = array(
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
'default' => 0,
'description' => 'The number of times the redirect has been used.',
);
db_add_field('redirect', 'count', $field);
}
/**
* Add the {redirect}.uid field.
*/
function redirect_update_2() {
$field = array(
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
'default' => 0,
'description' => 'The {users}.uid of the user who created the redirect.',
);
db_add_field('redirect', 'uid', $field);
db_update('redirect')
->fields(array(
'uid' => 1,
))
->execute();
}
/**
* Enable bootstrap status for the module.
*/
function redirect_update_3() {
db_update('system')
->fields(array(
'bootstrap' => 1,
))
->condition('type', 'module')
->condition('name', 'redirect')
->execute();
}
/**
* Change empty redirect types to 'redirect'.
*/
function redirect_update_4() {
db_update('redirect')
->fields(array(
'type' => 'redirect',
))
->condition('type', '')
->execute();
}
/**
* Rename {redirect}.last_used to {redirect}.access.
*/
function redirect_update_5() {
if (db_field_exists('redirect', 'last_used')) {
db_drop_index('redirect', 'expires');
db_change_field('redirect', 'last_used', 'access', array(
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
'default' => 0,
'description' => 'The timestamp of when the redirect was last accessed.',
));
db_add_index('redirect', 'expires', array(
'type',
'access',
));
}
}
/**
* Add an index on the source and language columns in the redirect table.
*/
function redirect_update_6() {
if (!db_index_exists('redirect', 'source_language')) {
db_add_index('redirect', 'source_language', array(
'source',
'language',
));
}
}
/**
* Rebuild the registry and clear the entity info cache.
*/
function redirect_update_7100() {
if (!class_exists('RedirectController')) {
registry_rebuild();
entity_info_cache_clear();
}
}
/**
* Add status field.
*/
function redirect_update_7101() {
$status_schema = array(
'type' => 'int',
'size' => 'small',
'not null' => TRUE,
'default' => 1,
'description' => 'Boolean indicating whether the redirect is enabled (visible to non-administrators).',
);
if (!db_field_exists('redirect', 'status')) {
db_add_field('redirect', 'status', $status_schema);
}
else {
db_change_field('redirect', 'status', 'status', $status_schema);
}
if (db_index_exists('redirect', 'source_language')) {
db_drop_index('redirect', 'source_language');
}
if (!db_index_exists('redirect', 'status_source_language')) {
db_add_index('redirect', 'status_source_language', array(
'status',
'source',
'language',
));
}
}
/**
* Disable redirects that could cause infinite loops.
*/
function redirect_update_7102() {
$rids = db_query("SELECT r.rid FROM {redirect} r INNER JOIN {url_alias} u ON r.source = u.alias AND r.redirect = u.source AND r.language = u.language")
->fetchCol();
if ($rids) {
// Disable redirects
$count = db_update('redirect')
->fields(array(
'status' => 0,
))
->condition('rid', $rids)
->execute();
$disabled_redirects_message = format_plural($count, '1 circular redirect causing infinite loop was disabled.', '@count circular redirects causing infinite loop were disabled.');
return $disabled_redirects_message;
}
else {
return t('No circular redirects were found that could cause infinite loops.');
}
}
/**
* Migrate a path redirect redirect to a redirect redirect.
*/
function _redirect_migrate_path_redirect_redirect($old_redirect) {
$redirect = new stdClass();
redirect_object_prepare($redirect);
$source_parsed = redirect_parse_url($old_redirect->source);
$redirect->source = $source_parsed['url'];
if (!empty($source_parsed['query'])) {
$redirect->source_options['query'] = $source_parsed['query'];
}
$redirect_parsed = redirect_parse_url($old_redirect->redirect) + array(
'query' => drupal_get_query_array($old_redirect->query),
'fragment' => $old_redirect->fragment,
);
$redirect->redirect = $redirect_parsed['url'];
if (!empty($redirect_parsed['query'])) {
$redirect->redirect_options['query'] = $redirect_parsed['query'];
}
if (!empty($redirect_parsed['fragment'])) {
$redirect->redirect_options['fragment'] = $redirect_parsed['fragment'];
}
if (!empty($redirect_parsed['https'])) {
$redirect->redirect_options['https'] = TRUE;
}
// Make sure empty language codes get migrated to use the new constant.
$redirect->language = empty($old_redirect->language) ? LANGUAGE_NONE : $old_redirect->language;
// Default status codes get a value of 0.
if ($old_redirect->type != variable_get('redirect_default_status_code', 301)) {
$redirect->status_code = (int) $old_redirect->type;
}
redirect_hash($redirect);
if (redirect_load_by_hash($redirect->hash)) {
// If a redirect with the same hash already exists, then it needs to be
// skipped.
$redirect->success = FALSE;
}
else {
// Add the redirect to the database.
db_insert('redirect')
->fields(array(
'hash' => $redirect->hash,
'type' => 'redirect',
'uid' => 1,
'source' => $redirect->source,
'source_options' => serialize($redirect->source_options),
'redirect' => $redirect->redirect,
'redirect_options' => serialize($redirect->redirect_options),
'language' => $redirect->language,
'status_code' => $redirect->status_code,
'status' => 1,
'count' => 0,
'access' => $old_redirect->last_used,
))
->execute();
// Migrating this redirect succeeded.
$redirect->success = TRUE;
}
return $redirect;
}
/**
* Migrate data and variables from the Drupal 6 path_redirect module.
*/
function _redirect_migrate_path_redirect_redirects(&$context) {
if (!isset($context['sandbox']['progress']) && db_table_exists('path_redirect')) {
$context['sandbox']['progress'] = 0;
$context['sandbox']['current_rid'] = 0;
$context['sandbox']['max'] = db_query('SELECT COUNT(rid) FROM {path_redirect}')
->fetchField();
$context['results']['skipped'] = array();
}
if (empty($context['sandbox']['max'])) {
$context['finished'] = 1;
return t('No redirects to migrate.');
}
// Ensure the redirect module is loaded since we need to use its functions.
drupal_load('module', 'redirect');
$query = db_query_range("SELECT * FROM {path_redirect} WHERE rid > :rid ORDER BY rid", 0, 25, array(
':rid' => $context['sandbox']['current_rid'],
));
foreach ($query as $old_redirect) {
$redirect = _redirect_migrate_path_redirect_redirect($old_redirect);
if (empty($redirect->success)) {
$context['results']['skipped'][$old_redirect->rid] = t('RID @rid: @from to @to', array(
'@rid' => $old_redirect->rid,
'@from' => redirect_url($redirect->source, $redirect->source_options),
'@to' => redirect_url($redirect->redirect, $redirect->redirect_options),
));
}
$context['sandbox']['progress']++;
$context['sandbox']['current_rid'] = $old_redirect->rid;
}
$context['finished'] = $context['sandbox']['progress'] / $context['sandbox']['max'];
if ($context['finished'] >= 1) {
// Once finished, drop the old table.
db_drop_table('path_redirect');
// Migrate variables.
_redirect_migrate_path_redirect_variables();
// Remove the path_redirect entry from the system table.
db_delete('system')
->condition('name', 'path_redirect')
->execute();
// Record how many redirects were migrated, and how many were skipped.
$context['results']['skipped_count'] = count($context['results']['skipped']);
$context['results']['migrated'] = $context['sandbox']['progress'] - $context['results']['skipped_count'];
}
}
/**
* Set an appropriate message when the batch migration is complete.
*/
function _redirect_migrate_finished_callback($success, $results, $operations) {
if ($success) {
// Show a message about how many redirects were migrated, and how many
// were skipped.
$message = t('Migrated !migrated redirects.', array(
'!migrated' => $results['migrated'],
));
if (!empty($results['skipped'])) {
$message .= ' ' . t('The following !skipped redirects were not migrated since there were already existing redirects for the path and language combination:', array(
'!skipped' => $results['skipped_count'],
));
$message .= theme('item_list', array(
'items' => $results['skipped'],
));
}
}
else {
$message = t('There was a problem with the migration from path_redirect.');
}
drupal_set_message($message);
}
/**
* Migrate path redirect variables to redirect variables.
*/
function _redirect_migrate_path_redirect_variables() {
// Port path_redirect variables.
$variables = array(
'path_redirect_default_status' => 'redirect_default_status_code',
'path_redirect_purge_inactive' => 'redirect_purge_inactive',
'path_redirect_retain_query_string' => 'redirect_passthrough_querystring',
'path_redirect_auto_redirect' => 'redirect_auto_redirect',
'path_redirect_redirect_warning' => 'redirect_warning',
'path_redirect_allow_bypass' => NULL,
);
foreach ($variables as $old_variable => $new_variable) {
if (!empty($new_variable)) {
$old_value = variable_get($old_variable);
$new_value = variable_get($new_variable);
// Only if the old variable exists, and the new variable hasn't been set
// yet, do we set the new variable with the old value.
if (isset($old_value) && !isset($new_value)) {
variable_set($new_variable, $old_value);
}
}
// Delete the old path redirect variable.
variable_del($old_variable);
}
}
/**
* Change fields 'redirect_options', 'source_options' to blob type.
*/
function redirect_update_7103() {
db_change_field('redirect', 'redirect_options', 'redirect_options', array(
'type' => 'blob',
));
db_change_field('redirect', 'source_options', 'source_options', array(
'type' => 'blob',
));
}
/**
* Add an index on the redirect column in the redirect table.
*/
function redirect_update_7104() {
if (!db_index_exists('redirect', 'redirect')) {
db_add_index('redirect', 'redirect', array(
'redirect',
));
}
}
Functions
Name | Description |
---|---|
redirect_install | Implements hook_install(). |
redirect_schema | Implements hook_schema(). |
redirect_uninstall | Implements hook_uninstall(). |
redirect_update_1 | Add the {redirect}.count field. |
redirect_update_2 | Add the {redirect}.uid field. |
redirect_update_3 | Enable bootstrap status for the module. |
redirect_update_4 | Change empty redirect types to 'redirect'. |
redirect_update_5 | Rename {redirect}.last_used to {redirect}.access. |
redirect_update_6 | Add an index on the source and language columns in the redirect table. |
redirect_update_7100 | Rebuild the registry and clear the entity info cache. |
redirect_update_7101 | Add status field. |
redirect_update_7102 | Disable redirects that could cause infinite loops. |
redirect_update_7103 | Change fields 'redirect_options', 'source_options' to blob type. |
redirect_update_7104 | Add an index on the redirect column in the redirect table. |
_redirect_migrate_finished_callback | Set an appropriate message when the batch migration is complete. |
_redirect_migrate_path_redirect_redirect | Migrate a path redirect redirect to a redirect redirect. |
_redirect_migrate_path_redirect_redirects | Migrate data and variables from the Drupal 6 path_redirect module. |
_redirect_migrate_path_redirect_variables | Migrate path redirect variables to redirect variables. |