function _linkchecker_status_handling in Link checker 5.2
Same name and namespace in other branches
- 6.2 linkchecker.module \_linkchecker_status_handling()
- 7 linkchecker.module \_linkchecker_status_handling()
Status code handling.
Parameters
$link: An object containing the url, lid and fail_count.
$response: An object containing the HTTP request headers, response code, headers, data and redirect status.
1 call to _linkchecker_status_handling()
- linkchecker_cron in ./
linkchecker.module - Implementation of hook_cron().
File
- ./
linkchecker.module, line 725 - This module periodically check links in given node types, blocks, cck fields, etc.
Code
function _linkchecker_status_handling($link, $response) {
$useragent = variable_get('linkchecker_check_useragent', 'Drupal (+http://drupal.org/)');
$ignore_response_codes = preg_split('/(\\r\\n?|\\n)/', variable_get('linkchecker_ignore_response_codes', "200\n302\n304\n401\n403"));
// FIXME: drupal_http_request() may not provide an UTF8 encoded error message
// what results in a database UPDATE failure. See http://drupal.org/node/371495
// for more information. ISO-8859-1 as source encoding may be wrong, but WFM.
if (!empty($response->error) && !drupal_validate_utf8($response->error)) {
$response->error = drupal_convert_to_utf8($response->error, 'ISO-8859-1');
}
// Prevent E_ALL warnings for non-existing $response->error.
if (!isset($response->error)) {
$response->error = '';
}
switch ($response->code) {
case 200:
case 304:
db_query("UPDATE {linkchecker_links} SET code = %d, error = '%s', fail_count = %d, last_checked = %d WHERE lid = %d", $response->code, $response->error, 0, time(), $link->lid);
//watchdog('linkchecker', t('Checked %link successfully.', array('%link' => $link->url)));
break;
case 301:
db_query("UPDATE {linkchecker_links} SET code = %d, error = '%s', fail_count = fail_count+1, last_checked = %d WHERE lid = %d", $response->code, $response->error, time(), $link->lid);
// A HTTP status code of 301 tells us an existing link have changed to
// a new link. The remote site owner was so kind to provide us the new
// link and if we trust this change we are able to replace the old link
// with the new one without any hand work.
$auto_repair_301 = variable_get('linkchecker_action_status_code_301', 0);
if ($auto_repair_301 && $auto_repair_301 <= $link->fail_count + 1 && $response->redirect_code == 200 && valid_url($response->redirect_url, TRUE)) {
// NODES: Autorepair all nodes having this outdated link.
$res = db_query("SELECT * FROM {linkchecker_nodes} WHERE lid = %d", $link->lid);
while ($row = db_fetch_object($res)) {
$node = node_load(array(
'nid' => $row->nid,
));
// Create array of node fields to scan (for e.g. $node->title, $node->links_weblink_url).
$text_items = array();
$text_items[] = 'title';
$text_items[] = 'body';
$text_items[] = 'teaser';
// Update 'weblink' nodes from 'links' module package.
if (module_exists('links_weblink') && $node->type == 'weblink' && isset($node->links_weblink_url)) {
$text_items[] = 'links_weblink_url';
}
// Update 'weblinks' nodes from 'weblinks' module.
if (module_exists('weblinks') && $node->type == 'weblinks' && isset($node->url)) {
$text_items[] = 'url';
}
// Now replace the outdated link with the permanently moved one in all node fields.
foreach ($text_items as $text_item) {
_linkchecker_link_replace($node->{$text_item}, $link->url, $response->redirect_url);
}
// Search for CCK-fields of types 'link' and 'text'.
if (module_exists('content')) {
$fields = content_fields(NULL, $node->type);
foreach ($fields as $field) {
if (isset($node->{$field['field_name']})) {
if (module_exists('link') && $field['type'] == 'link') {
foreach ($node->{$field}['field_name'] as $delta => $item) {
_linkchecker_link_replace($node->{$field['field_name']}[$delta]['url'], $link->url, $response->redirect_url);
}
}
elseif (module_exists('text') && $field['type'] == 'text') {
foreach ($node->{$field}['field_name'] as $delta => $item) {
_linkchecker_link_replace($node->{$field['field_name']}[$delta]['value'], $link->url, $response->redirect_url);
}
}
}
}
}
// Always use the default revision setting. See node_form().
$node_options = variable_get('node_options_' . $node->type, array(
'status',
'promote',
));
$node->revision = in_array('revision', $node_options);
// Generate a log message for the node_revisions table, visible on the node's revisions tab.
$log_message = t('Changed permanently moved link in %node from %src to %dst.', array(
'%node' => url('node/' . $row->nid),
'%src' => $link->url,
'%dst' => $response->redirect_url,
));
$node->log = $log_message;
// Save changed node and update the node link list.
node_save($node);
watchdog('linkchecker', $log_message);
}
// COMMENTS: Autorepair all comments having this outdated link.
if (module_exists('comment')) {
$res = db_query("SELECT * FROM {linkchecker_comments} WHERE lid = %d", $link->lid);
while ($row = db_fetch_object($res)) {
$comment = _linkchecker_comment_load($row->cid);
// Create array of comment fields to scan (for e.g. $comment->subject, $comment->comment).
$text_items = array();
$text_items[] = 'subject';
$text_items[] = 'comment';
// Now replace the outdated link with the permanently moved one in all comment fields.
foreach ($text_items as $text_item) {
_linkchecker_link_replace($comment[$text_item], $link->url, $response->redirect_url);
}
// Save changed comment and update the comment link list.
comment_save($comment);
watchdog('linkchecker', t('Changed permanently moved link in comment %comment from %src to %dst.', array(
'%comment' => $comment['cid'],
'%src' => $link->url,
'%dst' => $response->redirect_url,
)));
}
}
// BOXES: Autorepair all boxes having this outdated link.
$res = db_query("SELECT * FROM {linkchecker_boxes} WHERE lid = %d", $link->lid);
while ($row = db_fetch_object($res)) {
$box = block_box_get($row->bid);
// Create array of box fields to scan.
$text_items = array();
$text_items[] = 'info';
$text_items[] = 'title';
$text_items[] = 'body';
// Now replace the outdated link with the permanently moved one in all box fields.
foreach ($text_items as $text_item) {
_linkchecker_link_replace($box[$text_item], $link->url, $response->redirect_url);
}
// Save changed node and update the node link list.
block_box_save($box, $row->bid);
// There is no hook that fires on block_box_save(), therefore do it programmatically.
_linkchecker_add_box_links($box, $row->bid);
watchdog('linkchecker', t('Changed permanently moved link in box %bid from %src to %dst.', array(
'%bid' => $row->bid,
'%src' => $link->url,
'%dst' => $response->redirect_url,
)));
}
}
else {
watchdog('linkchecker', t('Link %link has changed and needs to be updated.', array(
'%link' => $link->url,
)), WATCHDOG_NOTICE, l(t('Broken links'), 'admin/logs/linkchecker'));
}
break;
case 404:
db_query("UPDATE {linkchecker_links} SET code = %d, error = '%s', fail_count = fail_count+1, last_checked = %d WHERE lid = %d", $response->code, $response->error, time(), $link->lid);
watchdog('linkchecker', t('Broken link %link has been found.', array(
'%link' => $link->url,
)), WATCHDOG_NOTICE, l(t('Broken links'), 'admin/logs/linkchecker'));
// If unpublishing limit is reached, unpublish all nodes having this link.
$linkchecker_action_status_code_404 = variable_get('linkchecker_action_status_code_404', 0);
if ($linkchecker_action_status_code_404 && $linkchecker_action_status_code_404 <= $link->fail_count + 1) {
_linkchecker_unpublish_nodes($link->lid);
}
break;
case 405:
// Special error handling if method is not allowed. Switch link checking to GET method and try again.
$response = drupal_http_request($link->url, array(
'User-Agent' => 'User-Agent: ' . $useragent,
), 'GET', NULL, 0);
if ($response->code == 200) {
db_query("UPDATE {linkchecker_links} SET code = %d, error = '%s', fail_count = %d, last_checked = %d, method = '%s' WHERE lid = %d", $response->code, $response->error, 0, time(), 'GET', $link->lid);
}
else {
db_query("UPDATE {linkchecker_links} SET code = %d, error = '%s', fail_count = fail_count+1, last_checked = %d, method = '%s' WHERE lid = %d", $response->code, $response->error, time(), 'GET', $link->lid);
}
watchdog('linkchecker', t('Method HEAD is not allowed for link %link. Method has been changed to GET.', array(
'%link' => $link->url,
)), WATCHDOG_NOTICE, l(t('Broken links'), 'admin/logs/linkchecker'));
break;
default:
// Don't treat ignored response codes as errors.
if (in_array($response->code, $ignore_response_codes)) {
db_query("UPDATE {linkchecker_links} SET code = %d, error = '%s', fail_count = %d, last_checked = %d WHERE lid = %d", $response->code, $response->error, 0, time(), $link->lid);
//watchdog('linkchecker', t('Unhandled link error %link has been found.', array('%link' => $link->url)), WATCHDOG_ERROR, l(t('Broken links'), 'admin/logs/linkchecker'));
}
else {
db_query("UPDATE {linkchecker_links} SET code = %d, error = '%s', fail_count = fail_count+1, last_checked = %d WHERE lid = %d", $response->code, $response->error, time(), $link->lid);
//watchdog('linkchecker', t('Unhandled link error %link has been found.', array('%link' => $link->url)), WATCHDOG_ERROR, l(t('Broken links'), 'admin/logs/linkchecker'));
}
}
}