This repository has been archived on 2025-06-21. You can view files and clone it, but you cannot make any changes to it's state, such as pushing and creating new issues, pull requests or comments.
suitedesk/modules/linkchecker/linkchecker.install

696 lines
23 KiB
Text

<?php
/**
* @file
* Installation file for Link Checker module.
*/
/**
* Defines the minimum MySQL version number this module supports.
*
* Previous versions do not support subselects, but for performance reasons
* the module makes use of them whenever possible. PgSQL do not have this
* kind of limitations in the versions supported by Drupal 6.
*/
define('LINKCHECKER_MINIMUM_MYSQL', '5.0');
/**
* Implementation of hook_install().
*/
function linkchecker_install() {
drupal_install_schema('linkchecker');
$linkchecker_default_impersonate_user = user_load(1);
variable_set('linkchecker_impersonate_user', $linkchecker_default_impersonate_user->name);
}
/**
* Implementation of hook_uninstall().
*/
function linkchecker_uninstall() {
drupal_uninstall_schema('linkchecker');
variable_del('linkchecker_action_status_code_301');
variable_del('linkchecker_action_status_code_404');
variable_del('linkchecker_check_connections_max');
variable_del('linkchecker_check_library');
variable_del('linkchecker_check_links_interval');
variable_del('linkchecker_check_useragent');
variable_del('linkchecker_cleanup_links_last');
variable_del('linkchecker_disable_link_check_for_urls');
variable_del('linkchecker_extract_from_a');
variable_del('linkchecker_extract_from_audio');
variable_del('linkchecker_extract_from_embed');
variable_del('linkchecker_extract_from_iframe');
variable_del('linkchecker_extract_from_img');
variable_del('linkchecker_extract_from_object');
variable_del('linkchecker_extract_from_source');
variable_del('linkchecker_extract_from_video');
variable_del('linkchecker_filter_blacklist');
variable_del('linkchecker_fqdn_only');
variable_del('linkchecker_ignore_response_codes');
variable_del('linkchecker_impersonate_user');
variable_del('linkchecker_scan_blocks');
variable_del('linkchecker_scan_comments');
variable_del('linkchecker_scan_nodetypes');
}
/**
* Implementation of hook_schema().
*/
function linkchecker_schema() {
$schema['linkchecker_links'] = array(
'description' => 'Stores all links.',
'fields' => array(
'lid' => array(
'type' => 'serial',
'not null' => TRUE,
'description' => 'Primary Key: Unique link ID.',
),
'urlhash' => array(
'type' => 'varchar',
'length' => 32,
'not null' => TRUE,
'description' => 'The indexable md5 hash of the {linkchecker_links}.url.',
),
'url' => array(
'type' => 'text',
'not null' => TRUE,
'description' => 'The full qualified link.',
),
'method' => array(
'type' => 'varchar',
'length' => 4,
'default' => 'HEAD',
'not null' => TRUE,
'description' => 'The method for checking links (HEAD, GET, POST).',
),
'code' => array(
'type' => 'int',
'not null' => TRUE,
'default' => -1,
'description' => 'HTTP status code from link checking.',
),
'error' => array(
'type' => 'text',
'not null' => FALSE,
'description' => 'The error message received from the remote server while doing link checking.',
),
'fail_count' => array(
'type' => 'int',
'not null' => TRUE,
'default' => 0,
'description' => 'Fail count of unsuccessful link checks. No flapping detection. (Successful = 0, Unsuccessful = fail_count+1).',
),
'last_checked' => array(
'type' => 'int',
'not null' => TRUE,
'default' => 0,
'description' => 'Timestamp of the last link check.',
),
'status' => array(
'type' => 'int',
'not null' => TRUE,
'default' => 1,
'description' => 'Boolean indicating if a link should be checked or not.',
),
),
'primary key' => array('lid'),
'unique keys' => array('urlhash' => array('urlhash')),
'indexes' => array(
'method' => array('method'),
'code' => array('code'),
'fail_count' => array('fail_count'),
'last_checked' => array('last_checked'),
'status' => array('status'),
),
);
$schema['linkchecker_boxes'] = array(
'description' => 'Stores all link references for boxes.',
'fields' => array(
'bid' => array(
'type' => 'int',
'not null' => TRUE,
'description' => 'Primary Key: Unique {boxes}.bid.',
),
'lid' => array(
'type' => 'int',
'not null' => TRUE,
'description' => 'Primary Key: Unique {linkchecker_links}.lid.',
),
),
'primary key' => array('bid', 'lid'),
'indexes' => array('lid' => array('lid')),
);
$schema['linkchecker_nodes'] = array(
'description' => 'Stores all link references for nodes.',
'fields' => array(
'nid' => array(
'type' => 'int',
'not null' => TRUE,
'description' => 'Primary Key: Unique {node}.nid.',
),
'lid' => array(
'type' => 'int',
'not null' => TRUE,
'description' => 'Primary Key: Unique {linkchecker_links}.lid.',
),
),
'primary key' => array('nid', 'lid'),
'indexes' => array('lid' => array('lid')),
);
$schema['linkchecker_comments'] = array(
'description' => 'Stores all link references for comments.',
'fields' => array(
'cid' => array(
'type' => 'int',
'not null' => TRUE,
'description' => 'Primary Key: Unique {comments}.cid.',
),
'lid' => array(
'type' => 'int',
'not null' => TRUE,
'description' => 'Primary Key: Unique {linkchecker_links}.lid.',
),
),
'primary key' => array('cid', 'lid'),
'indexes' => array('lid' => array('lid')),
);
return $schema;
}
/**
* Implementation of hook_requirements().
*/
function linkchecker_requirements($phase) {
$requirements = array();
$t = get_t();
switch ($phase) {
case 'install' :
// MySQL version with subselect support is required.
$version = db_version();
if (in_array($GLOBALS['db_type'], array('mysql', 'mysqli')) && version_compare($version, LINKCHECKER_MINIMUM_MYSQL) < 0) {
$requirements['linkchecker_minimum_mysql'] = array(
'title' => $t('MySQL database'),
'value' => $version,
'severity' => REQUIREMENT_ERROR,
'description' => $t('Your MySQL Server is too old. Link Checker requires at least MySQL %version.', array('%version' => LINKCHECKER_MINIMUM_MYSQL)),
);
}
break;
}
return $requirements;
}
/**
* Upgrade module to new D5 schema.
*/
function linkchecker_update_5200() {
$ret = array();
// Module functions are required. Make sure the module is loaded.
drupal_load('module', 'linkchecker');
// Remove obsolete tables no longer required.
db_drop_table($ret, 'linkchecker_tasks');
db_drop_table($ret, 'linkchecker_results');
// Create new tables.
$schema['linkchecker_links'] = array(
'description' => 'Stores all links.',
'fields' => array(
'lid' => array(
'type' => 'int',
'not null' => TRUE,
'description' => 'Primary Key: Unique link ID.',
),
'token' => array(
'type' => 'varchar',
'length' => 32,
'not null' => TRUE,
'description' => 'The indexable md5 hash of the {linkchecker_links}.url.',
),
'url' => array(
'type' => 'text',
'not null' => TRUE,
'description' => 'The full qualified link URL.',
),
'method' => array(
'type' => 'varchar',
'length' => 4,
'default' => 'HEAD',
'not null' => TRUE,
'description' => 'The method for checking links (HEAD, GET, POST).',
),
'code' => array(
'type' => 'int',
'not null' => TRUE,
'default' => 0,
'description' => 'HTTP status code from link checking.',
),
'error' => array(
'type' => 'text',
'not null' => FALSE,
'description' => 'The error message received from the remote server while doing link checking.',
),
'fail_count' => array(
'type' => 'int',
'not null' => TRUE,
'default' => 0,
'description' => 'Fail count of unsuccessful link checks. No flapping detection. (Successful = 0, Unsuccessful = fail_count+1).',
),
'last_checked' => array(
'type' => 'int',
'not null' => TRUE,
'default' => 0,
'description' => 'Timestamp of the last link check.',
),
),
'primary key' => array('lid'),
'unique keys' => array('token' => array('token')),
);
$schema['linkchecker_boxes'] = array(
'description' => 'Stores all link references for boxes.',
'fields' => array(
'bid' => array(
'type' => 'int',
'not null' => TRUE,
'description' => 'Primary Key: Unique {boxes}.bid.',
),
'lid' => array(
'type' => 'int',
'not null' => TRUE,
'description' => 'Primary Key: Unique {linkchecker_links}.lid.',
),
),
'primary key' => array('bid', 'lid'),
);
$schema['linkchecker_nodes'] = array(
'description' => 'Stores all link references for nodes.',
'fields' => array(
'nid' => array(
'type' => 'int',
'not null' => TRUE,
'description' => 'Primary Key: Unique {node}.nid.',
),
'lid' => array(
'type' => 'int',
'not null' => TRUE,
'description' => 'Primary Key: Unique {linkchecker_links}.lid.',
),
),
'primary key' => array('nid', 'lid'),
);
// Create schema.
db_create_table($ret, 'linkchecker_links', $schema['linkchecker_links']);
db_create_table($ret, 'linkchecker_boxes', $schema['linkchecker_boxes']);
db_create_table($ret, 'linkchecker_nodes', $schema['linkchecker_nodes']);
// Upgrade settings. Could be less code, but is easier to follow.
$ignore_response_codes = preg_split('/(\r\n?|\n)/', variable_get('linkchecker_ignore_responses', "200\n304\n401\n403"));
// Filter all invalid responds codes and outdated error messages out.
$ignore_response_codes = array_filter($ignore_response_codes, '_linkchecker_isvalid_response_code');
// Make sure we have status code 200 and 304 in the ignore list.
$ignore_response_codes = array_merge(array('200', '304'), $ignore_response_codes);
$ignore_response_codes = array_unique($ignore_response_codes);
variable_set('linkchecker_ignore_response_codes', implode("\n", $ignore_response_codes));
$ret[] = array('success' => TRUE, 'query' => 'Ignored response codes have been upgraded to '. implode(",", $ignore_response_codes));
// Remove obsolete settings.
variable_del('linkchecker_ignore_responses');
variable_del('linkchecker_rebuild');
variable_del('linkchecker_maxtime');
variable_del('linkchecker_socket_timeout');
variable_del('linkchecker_max_links_per_node');
variable_del('linkchecker_remove_after');
variable_del('linkchecker_give_up');
return $ret;
}
/**
* Upgrade module to new D6 schema.
*/
function linkchecker_update_6200() {
$ret = array();
db_change_field($ret, 'linkchecker_links', 'lid', 'lid', array('type' => 'serial', 'not null' => TRUE));
// Upgrade line break converter from D5 filter/2 to D6 filter/1.
$linkchecker_filter_blacklist = variable_get('linkchecker_filter_blacklist', array());
if (!empty($linkchecker_filter_blacklist) && $linkchecker_filter_blacklist['filter/2']) {
$linkchecker_filter_blacklist['filter/2'] = 0;
$linkchecker_filter_blacklist['filter/1'] = 'filter/1';
variable_set('linkchecker_filter_blacklist', $linkchecker_filter_blacklist);
$ret[] = array('success' => TRUE, 'query' => 'Upgraded the default exclusion of line break converter filter from D5 filter/2 to D6 filter/1.');
}
return $ret;
}
/**
* Install linkchecker_comments table.
*/
function linkchecker_update_6201() {
$ret = array();
// Create new tables.
$schema['linkchecker_comments'] = array(
'description' => 'Stores all link references for comments.',
'fields' => array(
'cid' => array(
'type' => 'int',
'not null' => TRUE,
'description' => 'Primary Key: Unique {comments}.cid.',
),
'lid' => array(
'type' => 'int',
'not null' => TRUE,
'description' => 'Primary Key: Unique {linkchecker_links}.lid.',
),
),
'primary key' => array('cid', 'lid'),
);
// Table may be created in 5201 by 5.x-2.x.
if (!db_table_exists('linkchecker_comments')) {
db_create_table($ret, 'linkchecker_comments', $schema['linkchecker_comments']);
}
return $ret;
}
/**
* Remove unnecessary elements from custom submit buttons.
*/
function linkchecker_update_6202() {
$ret = array();
variable_del('linkchecker_analyze');
variable_del('linkchecker_clear_analyze');
return $ret;
}
/**
* Make fields unsigned.
*/
function linkchecker_update_6204() {
$ret = array();
// Make linkchecker_links.lid unsigned.
db_change_field($ret, 'linkchecker_links', 'lid', 'lid', array('type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE));
if ($GLOBALS['db_type'] == 'pgsql') {
db_add_primary_key($ret, 'linkchecker_links', array('lid'));
}
// Make linkchecker_boxes.bid and linkchecker_boxes.lid unsigned.
db_drop_primary_key($ret, 'linkchecker_boxes');
db_change_field($ret, 'linkchecker_boxes', 'bid', 'bid', array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE));
db_change_field($ret, 'linkchecker_boxes', 'lid', 'lid', array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE));
db_add_primary_key($ret, 'linkchecker_boxes', array('bid', 'lid'));
// Make linkchecker_comments.cid and linkchecker_comments.lid unsigned.
db_drop_primary_key($ret, 'linkchecker_comments');
db_change_field($ret, 'linkchecker_comments', 'cid', 'cid', array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE));
db_change_field($ret, 'linkchecker_comments', 'lid', 'lid', array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE));
db_add_primary_key($ret, 'linkchecker_comments', array('cid', 'lid'));
// Make linkchecker_nodes.nid and linkchecker_nodes.lid unsigned.
db_drop_primary_key($ret, 'linkchecker_nodes');
db_change_field($ret, 'linkchecker_nodes', 'nid', 'nid', array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE));
db_change_field($ret, 'linkchecker_nodes', 'lid', 'lid', array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE));
db_add_primary_key($ret, 'linkchecker_nodes', array('nid', 'lid'));
return $ret;
}
/**
* Remove any references to nodes that are not published and also remove their comments references.
*/
function linkchecker_update_6205() {
$ret = array();
$ret[] = update_sql("DELETE FROM {linkchecker_nodes} WHERE nid IN (SELECT nid FROM {node} WHERE status = 0)");
$ret[] = update_sql("DELETE FROM {linkchecker_comments} WHERE cid IN (SELECT c.cid FROM {node} n INNER JOIN {comments} c ON c.nid = n.nid WHERE n.status = 0)");
return $ret;
}
/**
* Add status column to links table.
*/
function linkchecker_update_6206() {
$ret = array();
// Add the column only if not exists. Column may been added in D5 (5207).
if (!db_column_exists('linkchecker_links', 'status')) {
db_add_field($ret, 'linkchecker_links', 'status', array('type' => 'int', 'not null' => TRUE, 'default' => 1));
}
return $ret;
}
/**
* Remove obsolete variable.
*/
function linkchecker_update_6207() {
$ret = array();
variable_del('linkchecker_cleanup_links_interval');
return $ret;
}
/**
* Change default value for linkchecker_links.code to -1.
*
* fsockopen may return 0 as an indication that the error occurred before
* the connect() call. This is most likely due to a problem initializing the
* socket.
*/
function linkchecker_update_6208() {
$ret = array();
db_change_field($ret, 'linkchecker_links', 'code', 'code', array('type' => 'int', 'not null' => TRUE, 'default' => -1));
return $ret;
}
/**
* Update the permissions table, to reflect changes to hook_perm.
*/
function linkchecker_update_6209() {
$ret = array();
$res = db_query('SELECT rid, perm FROM {permission}');
$perms = array();
while ($p = db_fetch_object($res)) {
$perm = $p->perm;
$perm = preg_replace('/access linkchecker/', 'access broken links report', $perm);
$perms[$p->rid] = $perm;
}
foreach ($perms as $rid => $renamed_permission) {
db_query("UPDATE {permission} SET perm = '%s' WHERE rid = %d", $renamed_permission, $rid);
$ret[] = array('success' => TRUE, 'query' => 'UPDATE {permission} SET perm = ' . check_plain($renamed_permission) . ' WHERE rid = '. $rid);
}
return $ret;
}
/**
* Add status code 302 to the default list of ignored response codes.
*/
function linkchecker_update_6210() {
$ret = array();
$ignore_response_codes = preg_split('/(\r\n?|\n)/', variable_get('linkchecker_ignore_response_codes', "200\n302\n304\n401\n403"));
if (!in_array('302', $ignore_response_codes)) {
$ignore_response_codes[] = '302';
sort($ignore_response_codes);
variable_set('linkchecker_ignore_response_codes', implode("\n", $ignore_response_codes));
$ret[] = array('success' => TRUE, 'query' => 'Added the status code 302 to the list of ignored response codes.');
}
else {
$ret[] = array('success' => TRUE, 'query' => 'No action taken. The status code 302 was already on the list of ignored response codes.');
}
return $ret;
}
/**
* Remove obsolete variable.
*/
function linkchecker_update_6211() {
$ret = array();
variable_del('linkchecker_pathfilter_support');
$ret[] = array('success' => TRUE, 'query' => 'Removed obsolete linkchecker_pathfilter_support variable.');
return $ret;
}
/**
* Change unique key and column name 'token' into 'urlhash'.
*/
function linkchecker_update_6212() {
$ret = array();
db_drop_unique_key($ret, 'linkchecker_links', 'token');
db_change_field($ret, 'linkchecker_links', 'token', 'urlhash', array('type' => 'varchar', 'length' => 32, 'not null' => TRUE));
db_add_unique_key($ret, 'linkchecker_links', 'urlhash', array('urlhash'));
return $ret;
}
/**
* Add RFC documenation domains back if they have been removed.
*/
function linkchecker_update_6213() {
$ret = array();
$linkchecker_disable_link_check_for_urls = array_filter(preg_split('/(\r\n?|\n)/', variable_get('linkchecker_disable_link_check_for_urls', LINKCHECKER_RESERVED_DOCUMENTATION_DOMAINS)));
variable_set('linkchecker_disable_link_check_for_urls', implode("\n", array_unique(array_merge(explode("\n", LINKCHECKER_RESERVED_DOCUMENTATION_DOMAINS), $linkchecker_disable_link_check_for_urls))));
$ret[] = array('success' => TRUE, 'query' => 'Added RFC documenation domains back if they have been removed.');
return $ret;
}
/**
* #1321378: Improve performance of queries.
*/
function linkchecker_update_6214() {
$ret = array();
db_add_index($ret, 'linkchecker_boxes', 'lid', array('lid'));
db_add_index($ret, 'linkchecker_comments', 'lid', array('lid'));
db_add_index($ret, 'linkchecker_nodes', 'lid', array('lid'));
return $ret;
}
/**
* Add status code 206 to the default list of ignored response codes.
*/
function linkchecker_update_6215() {
$ret = array();
$ignore_response_codes = preg_split('/(\r\n?|\n)/', variable_get('linkchecker_ignore_response_codes', "200\n206\n302\n304\n401\n403"));
if (!in_array('206', $ignore_response_codes)) {
$ignore_response_codes[] = '206';
sort($ignore_response_codes);
variable_set('linkchecker_ignore_response_codes', implode("\n", $ignore_response_codes));
$ret[] = array('success' => TRUE, 'query' => 'Added the status code 206 to the list of ignored response codes.');
}
else {
$ret[] = array('success' => TRUE, 'query' => 'No action taken. The status code 206 was already on the list of ignored response codes.');
}
return $ret;
}
/**
* #965720: Add indexes to improve performance of views queries.
*/
function linkchecker_update_6216() {
$ret = array();
db_add_index($ret, 'linkchecker_links', 'method', array('method'));
db_add_index($ret, 'linkchecker_links', 'code', array('code'));
db_add_index($ret, 'linkchecker_links', 'fail_count', array('fail_count'));
db_add_index($ret, 'linkchecker_links', 'last_checked', array('last_checked'));
db_add_index($ret, 'linkchecker_links', 'status', array('status'));
return $ret;
}
/**
* #1450672: Set user 1 as default user to impersonate content updates.
*/
function linkchecker_update_6217() {
$ret = array();
$linkchecker_default_impersonate_user = user_load(1);
variable_set('linkchecker_impersonate_user', $linkchecker_default_impersonate_user->name);
$ret[] = array('success' => TRUE, 'query' => 'Set user 1 as default user to impersonate content updates.');
return $ret;
}
/**
* Removed obsolete linkchecker_check_links_max variable.
*/
function linkchecker_update_6218() {
$ret = array();
variable_del('linkchecker_check_links_max');
$ret[] = array('success' => TRUE, 'query' => 'Removed obsolete linkchecker_check_links_max variable.');
return $ret;
}
/**
* Upgrade outdated HTTP user agents.
*/
function linkchecker_update_6219() {
$ret = array();
$linkchecker_check_useragent = variable_get('linkchecker_check_useragent', 'Drupal (+http://drupal.org/)');
$useragent_upgrade = array(
'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1;)' => 'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)',
'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0;)' => 'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0)',
'Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.9.0.5) Gecko/2008120122 Firefox/3.0.5' => 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:17.0) Gecko/20100101 Firefox/17.0',
'Mozilla/5.0 (Windows; U; Windows NT 6.0; de; rv:1.9.0.5) Gecko/2008120122 Firefox/3.0.5' => 'Mozilla/5.0 (Windows NT 6.2; WOW64; rv:17.0) Gecko/20100101 Firefox/17.0',
);
if (isset($useragent_upgrade[$linkchecker_check_useragent])) {
variable_set('linkchecker_check_useragent', $useragent_upgrade[$linkchecker_check_useragent]);
$ret[] = array('success' => TRUE, 'query' => 'Upgraded outdated HTTP user agent.');
}
else {
$ret[] = array('success' => TRUE, 'query' => 'User agent already up to date.');
}
return $ret;
}
/**
* Upgrade outdated HTTP user agents.
*/
function linkchecker_update_6220() {
$ret = array();
$linkchecker_check_useragent = variable_get('linkchecker_check_useragent', 'Drupal (+http://drupal.org/)');
$useragent_upgrade = array(
'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)' => 'Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; Touch; rv:11.0) like Gecko',
'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0)' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2486.0 Safari/537.36 Edge/13.10586',
'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:17.0) Gecko/20100101 Firefox/17.0' => 'Mozilla/5.0 (Windows NT 6.3; WOW64; rv:47.0) Gecko/20100101 Firefox/47.0',
'Mozilla/5.0 (Windows NT 6.2; WOW64; rv:17.0) Gecko/20100101 Firefox/17.0' => 'Mozilla/5.0 (Windows NT 10.0; WOW64; rv:47.0) Gecko/20100101 Firefox/47.0',
);
if (isset($useragent_upgrade[$linkchecker_check_useragent])) {
variable_set('linkchecker_check_useragent', $useragent_upgrade[$linkchecker_check_useragent]);
$ret[] = array('success' => TRUE, 'query' => 'Upgraded outdated HTTP user agent.');
}
else {
$ret[] = array('success' => TRUE, 'query' => 'User agent already up to date.');
}
return $ret;
}