Index: includes/linkchecker.admin.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/linkchecker/includes/Attic/linkchecker.admin.inc,v retrieving revision 1.1.2.24 diff -u -r1.1.2.24 linkchecker.admin.inc --- includes/linkchecker.admin.inc 22 Nov 2009 14:09:45 -0000 1.1.2.24 +++ includes/linkchecker.admin.inc 24 May 2010 14:40:47 -0000 @@ -6,6 +6,8 @@ * Administrative page callbacks for the linkchecker module. */ +require_once (drupal_get_path('module', 'linkchecker') . '/includes/linkchecker.mail.inc'); + function linkchecker_admin_settings_form(&$form_state) { $form['settings'] = array( @@ -197,6 +199,36 @@ '#wysiwyg' => FALSE, ); + $email_token_help = t('Available variables are: !site, !user_link, !uri, !uri_brief, !username, !mailto, !date.'); + $form['mail'] = array( + '#type' => 'fieldset', + '#title' => t('Email settings'), + '#description' => t('Customize e-mail message sent when to Users when Broken links in their created content are found.') . ' ' . $email_token_help, + '#collapsible' => FALSE, + ); + $form['mail']['linkchecker_mail_broken'] = array( + '#type' => 'checkbox', + '#default_value' => variable_get('linkchecker_mail_broken', TRUE), + '#title' => t('Email user on finding broken links'), + '#description' => t('Email the Creator of the Content when Broken Links are found in the content.'), + ); + $form['mail']['linkchecker_mail_broken_subject'] = array( + '#type' => 'textfield', + '#title' => t('Broken link email subject'), + '#description' => t('Subject template for the e-mail sent when broken links are found.'), + '#required' => TRUE, + '#maxlength' => 180, + '#default_value' => linkchecker_mail_text('broken_subject'), + ); + $form['mail']['linkchecker_mail_broken_body'] = array( + '#type' => 'textarea', + '#title' => t('Broken link email body'), + '#description' => t('Body template for the e-mail sent when broken links are found.'), + '#required' => TRUE, + '#rows' => 15, + '#default_value' => linkchecker_mail_text('broken_body'), + ); + // Buttons are only required for testing and debugging reasons. $description = '

' . t('These actions will either clear all link checker tables in the database and/or analyze all selected node types, blocks and cck fields (see settings above) for new/updated/removed links. Normally there is no need to press one of these buttons. Use this only for immediate cleanup tasks and to force a full re-build of the links to be checked in the linkchecker tables. Keep in mind that all custom link settings will be lost!') . '

'; $description .= '

' . t('Note: These functions ONLY collect the links, they do not evaluate the HTTP response codes, this will be done during normal cron runs.') . '

'; Index: linkchecker.install =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/linkchecker/linkchecker.install,v retrieving revision 1.2.2.37 diff -u -r1.2.2.37 linkchecker.install --- linkchecker.install 26 Dec 2009 13:50:53 -0000 1.2.2.37 +++ linkchecker.install 24 May 2010 14:40:45 -0000 @@ -167,6 +167,42 @@ 'primary key' => array('cid', 'lid'), ); + $schema['linkchecker_users'] = array( + 'description' => 'Stores user preferences for receiving mails when broken links are found in content created by them.', + 'fields' => array( + 'uid' => array( + 'type' => 'int', + 'not null' => TRUE, + 'description' => 'Primary Key: Unique {users}.uid.', + ), + 'receive_mail' => array( + 'type' => 'int', + 'not null' => TRUE, + 'description' => 'True if the user wants to receive mail for broken links in content created by him/her, false otherwise.', + ), + 'min_days' => array( + 'type' => 'int', + 'not null' => TRUE, + 'description' => 'Minimum duration (in days) before which new emails should not been sent by the module.', + ), + 'days' => array( + 'type' => 'varchar', + 'length' => 25, + 'not null' => TRUE, + 'description' => 'Comma separated list of days on which the user wants to receive emails.', + ), + 'last_mailed' => array( + 'type' => 'int', + 'default' => 0, + 'description' => 'Last time a mail was dispatched to the user by this module.', + ), + ), + 'primary key' => array('uid'), + 'foreign keys' => array( + 'uid' => array('users' => 'uid'), + ), + ); + return $schema; } @@ -559,3 +595,50 @@ return $ret; } + +/** + * Add linkchecker_users table to existing installations. + */ +function linkchecker_update_6213() { + $ret = array(); + + $schema['linkchecker_users'] = array( + 'description' => 'Stores user preferences for receiving mails when broken links are found in content created by them.', + 'fields' => array( + 'uid' => array( + 'type' => 'int', + 'not null' => TRUE, + 'description' => 'Primary Key: Unique {users}.uid.', + ), + 'receive_mail' => array( + 'type' => 'int', + 'not null' => TRUE, + 'description' => 'True if the user wants to receive mail for broken links in content created by him/her, false otherwise.', + ), + 'min_days' => array( + 'type' => 'int', + 'not null' => TRUE, + 'description' => 'Minimum duration (in days) before which new emails should not been sent by the module.', + ), + 'days' => array( + 'type' => 'varchar', + 'length' => 25, + 'not null' => TRUE, + 'description' => 'Comma separated list of days on which the user wants to receive emails.', + ), + 'last_mailed' => array( + 'type' => 'int', + 'default' => 0, + 'description' => 'Last time a mail was dispatched to the user by this module.', + ), + ), + 'primary key' => array('uid'), + 'foreign keys' => array( + 'uid' => array('users' => 'uid'), + ), + ); + + db_create_table($ret, 'linkchecker_users', $schema['linkchecker_users']); + + return $ret; +} Index: linkchecker.module =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/linkchecker/linkchecker.module,v retrieving revision 1.7.2.138 diff -u -r1.7.2.138 linkchecker.module --- linkchecker.module 16 Jan 2010 13:18:55 -0000 1.7.2.138 +++ linkchecker.module 24 May 2010 14:40:47 -0000 @@ -8,6 +8,8 @@ * Developed by Alexander Hass, http://www.yaml-for-drupal.com/. */ +require_once (drupal_get_path('module', 'linkchecker') . '/includes/linkchecker.mail.inc'); + /** * Defines the maximum limit of links collected in one chunk if content is * scanned for links. A value that is too high may overload the database server. @@ -137,6 +139,9 @@ $check_links_interval = variable_get('linkchecker_check_links_interval', 2419200); $useragent = variable_get('linkchecker_check_useragent', 'Drupal (+http://drupal.org/)'); + // Register the start time for the cron run. + _linkchecker_cron_start_time(); + // Get URLs for checking. $result = db_query_range("SELECT * FROM {linkchecker_links} WHERE last_checked < %d AND status = %d ORDER BY last_checked, lid ASC", time() - $check_links_interval, 1, 0, $check_links_max_per_cron_run); while ($link = db_fetch_object($result)) { @@ -148,6 +153,122 @@ break; // Stop once we have used over half of the maximum execution time. } } + + //Send broken link emails. + _linkchecker_notify_broken_links(); +} + +/** + * Implementation of hook_user(). + */ +function linkchecker_user($type, &$edit, &$user, $category = NULL) { + switch ($type) { + case 'form': + if ($category == 'account') { + $results = db_query("SELECT * FROM {linkchecker_users} WHERE uid = %d", $user->uid); + if (!($settings = db_fetch_array($results))) { + $settings = _linkchecker_default_user_settings(); + } + + $form['linkchecker'] = array( + '#type' => 'fieldset', + '#title' => t('Linkchecker settings'), + '#description' => t('Customize settings for e-mails sent when broken links are found in the content created by you on the site.'), + '#tree' => TRUE, + '#weight' => 4, + '#collapsible' => TRUE, + '#collapsed' => TRUE, + ); + $form['linkchecker']['receive_mail'] = array( + '#type' => 'checkbox', + '#default_value' => $settings['receive_mail'], + '#title' => t('Receive e-mail for broken links'), + '#description' => t('Receive e-mail when broken links are found in content created by you.'), + ); + + $form['linkchecker']['min_days'] = array( + '#type' => 'textfield', + '#title' => t('Minimum duration between e-mails'), + '#description' => t('Minimum number of days after which the system should send you e-mails for broken links. Please note that the actual duration between the e-mails can be greater than what you specify here, but would never be less than this value.'), + '#required' => TRUE, + '#default_value' => $settings['min_days'], + ); + + $days = array( + 1 => t('Monday'), + 2 => t('Tuesday'), + 3 => t('Wednesday'), + 4 => t('Thursday'), + 5 => t('Friday'), + 6 => t('Saturday'), + 7 => t('Sunday'), + ); + + $form['linkchecker']['days'] = array( + '#type' => 'checkboxes', + '#title' => t('Days on which e-mail can be sent'), + '#description' => t('Select the days in the week on which you wish to receive e-mail for broken links.'), + '#options' => $days, + '#default_value' => explode(',', $settings['days']), + ); + + return $form; + } + break; + + case 'validate': + if (!$user->uid) { + return; + } + $min_days = $edit['linkchecker']['min_days']; + if (!is_numeric($min_days)) { + form_set_error('linkchecker][min_days', t('Value should be an integer.')); + } + else { + $min_days = (int) $min_days; + if ($min_days < 1) { + form_set_error('linkchecker][min_days', t('Minimum duration between e-mails should be 1.')); + } + } + $days = array(); + foreach ($edit['linkchecker']['days'] as $key => $val) { + if ($val) { + $days[$key] = $val; + } + } + + if ($edit['linkchecker']['receive_mail']) { + if (count($days) == 0) { + form_set_error('linkchecker][receive_mail', t('Please select at least one day on which to receive e-mail.')); + } + } + break; + + case 'submit': + $receive_mail = $edit['linkchecker']['receive_mail']; + $min_days = $edit['linkchecker']['min_days']; + $days = array(); + foreach ($edit['linkchecker']['days'] as $key => $val) { + if ($val) { + $days[$key] = $val; + } + } + $days = implode(',', $days); + + if (db_result(db_query("SELECT uid FROM {linkchecker_users} WHERE uid = %d", $user->uid))) { + db_query("UPDATE {linkchecker_users} SET receive_mail = %d, min_days = %d, days = '%s' WHERE uid = %d", $receive_mail, $min_days, $days, $user->uid); + } + else { + db_query("INSERT INTO {linkchecker_users} (uid, receive_mail, min_days, days) VALUES (%d, %d, %d, '%s')", $user->uid, $receive_mail, $min_days, $days); + } + break; + + case 'delete': + db_query("DELETE FROM {linkchecker_users} WHERE uid = %d", $user->uid); + break; + + break; + } } /** Index: includes/linkchecker.mail.inc =================================================================== RCS file: includes/linkchecker.mail.inc diff -N includes/linkchecker.mail.inc --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ includes/linkchecker.mail.inc 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,130 @@ +language : NULL; + + if ($admin_setting = variable_get('linkchecker_mail_' . $key, FALSE)) { + // An admin setting overrides the default string. + return strtr($admin_setting, $variables); + } + else { + // No override, return default string. + switch ($key) { + case 'broken_subject': + return t('Content created by you has broken links at !site', $variables, $langcode); + case 'broken_body': + return t("!username,\n\nThank you for your participation at !site. Content created by you at !site has been found to contain broken links. Please consider visiting your User Page and checking for broken links at: !user_link.\n\nYou can change the broken link notification settings by logging in to your account and going to your account page.\n\n\n-- !site team", $variables, $langcode); + } + } +} + +function linkchecker_mail_tokens($account, $language) { + global $base_url; + + $tokens = array( + '!username' => $account->name, + '!user_link' => url('user/' . $account->uid . '/linkchecker'), + '!site' => variable_get('site_name', 'Drupal'), + '!uri' => $base_url, + '!uri_brief' => preg_replace('!^https?://!', '', $base_url), + '!mailto' => $account->mail, + '!date' => format_date(time(), 'medium', '', NULL, $language->language), + ); + + return $tokens; +} + +function _linkchecker_cron_start_time() { + static $time = NULL; + if (!isset($time)) { + $time = time(); + } + return ($time); +} + +function _linkchecker_notify_broken_links() { + if (!variable_get('linkchecker_mail_broken', TRUE)) { + return; + } + + $time = _linkchecker_cron_start_time(); + $status = 1; + $day = date('N'); + $mail_time = time(); + $default = _linkchecker_default_user_settings(); + + $ignore_response_codes = preg_split('/(\r\n?|\n)/', variable_get('linkchecker_ignore_response_codes', "200\n302\n304\n401\n403")); + + // Search for broken links in nodes and comments and blocks of all users. + $sql = "SELECT u.*, lu.receive_mail, lu.min_days, lu.days, lu.last_mailed + FROM {users} u LEFT JOIN {linkchecker_users} lu ON u.uid = lu.uid INNER JOIN ( + SELECT DISTINCT c.uid + FROM {linkchecker_links} ll + INNER JOIN {linkchecker_comments} lc + ON ll.last_checked >= %d AND ll.status = %d AND ll.code NOT IN (" . db_placeholders($ignore_response_codes, 'int') . ") AND ll.lid = lc.lid + INNER JOIN {comments} c ON lc.cid = c.cid + UNION + SELECT DISTINCT n.uid + FROM {linkchecker_links} ll + INNER JOIN {linkchecker_nodes} ln + ON ll.last_checked >= %d AND ll.status = %d AND ll.code NOT IN (" . db_placeholders($ignore_response_codes, 'int') . ") AND ll.lid = ln.lid + INNER JOIN {node} n ON ln.nid = n.nid) q1 ON u.uid = q1.uid"; + + $results = db_query($sql, $time, 1, $codes, $time, 1, $codes); + + while ($user = db_fetch_object($results)) { + $receive_mail = $user->receive_mail == NULL ? 1 : $user->receive_mail + if ($receive_mail == 1) { + $last_mailed = $user->last_mailed == NULL ? 0 : $user->last_mailed; + $days = $user->days == NULL ? 0 : $user->days; + if ((($mail_time - $last_mailed) / 86400) > $days) { + $days = $user->days == NULL ? NULL : explode(',', $user->days); + if ($days == NULL || in_array($day, $days)) { + try { + drupal_mail('linkchecker', 'broken', $user->mail, user_preferred_language($user), array('account' => $user)); + } + catch (Exception $ex) { + watchdog('mail', $ex->getMessage()); + } + if ($user->receive_mail == NULL) { + db_query("INSERT INTO {linkchecker_users} (uid, receive_mail, min_days, days, last_mailed) VALUES (%d, %d, %d, '%s', %d)", $user->uid, $default['receive_mail'], $default['min_days'], $default['days'], $mail_time); + } + else { + db_query("UPDATE {linkchecker_users} SET last_mailed = %d WHERE uid = %d", $mail_time, $user->uid); + } + } + } + } + } +} + +function _linkchecker_default_user_settings() { + $settings = array(); + $settings['receive_mail'] = 1; + $settings['min_days'] = 7; + $settings['days'] = '1,2,3,4,5,6,7'; + return ($settings); +}