Index: akismet.admin.inc
===================================================================
RCS file: akismet.admin.inc
diff -N akismet.admin.inc
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ akismet.admin.inc 23 Feb 2008 21:00:43 -0000
@@ -0,0 +1,721 @@
+ t('Enabled'), '0' => t('Disabled'));
+
+ $akismet_wpapikey = variable_get('akismet_wpapikey', '');
+ if (empty($akismet_wpapikey)) {
+ $service_fieldset_collapsed = FALSE;
+ }
+ else {
+ $service_fieldset_collapsed = $is_valid = (akismet_api_cmd_verify_key($akismet_wpapikey) == AKISMET_API_RESULT_SUCCESS ? TRUE : FALSE);
+ }
+ if ($service_fieldset_collapsed) {
+ $service_fieldset_collapsed = variable_get('akismet_connection_enabled', 1);
+ }
+
+ $form['service'] = array(
+ '#type' => 'fieldset', '#title' => t('Akismet Service Options'),
+ '#collapsible' => TRUE, '#collapsed' => $service_fieldset_collapsed
+ );
+ $form['service']['akismet_wpapikey'] = array(
+ '#type' => 'textfield', '#title' => t('WordPress.com API key'),
+ '#size' => 30, '#maxlength' => 60,
+ '#default_value' => $akismet_wpapikey,
+ '#description' => t('Please, enter here your WordPress.com API key . If you don\'t have one already, you can get it by simply signing up for a free account at WordPress.com . Note that this information is required in order to use the Akismet Service . Please, consult the Akismet FAQ for further information.',
+ array(
+ '!wpapikey' => url('http://wordpress.com/api-keys/'),
+ '!wordpress-com' => url('http://wordpress.com'),
+ '!akismet' => url('http://akismet.com'),
+ '!akismet-faq' => url('http://akismet.com/faq/'),
+ ))
+ );
+ if (!empty($akismet_wpapikey) && !$is_valid) {
+ $form['service']['akismet_wpapikey']['#description'] .= '
'. t('WARNING: Your API Key doesn\'t seem to be valid! ') .'
';
+ }
+ $form['service']['akismet_connection_enabled'] = array(
+ '#type' => 'radios', '#title' => t('Akismet connections'),
+ '#options' => $enable_options,
+ '#default_value' => variable_get('akismet_connection_enabled', 1),
+ '#description' => t('This option must be enabled in order to perform real requests to the Akismet Service . You may want to disable this option for testing purposes, however. In this case, the akismet module will operate as normal, except sending real requests to the Akismet Service . ie. no automatic spam detection will be performed and no remote requests will be made when content is manually marked /unmarked as spam. Note: regardless of this option, the akismet module will still connect, from this panel, to validate your WordPress.com API key , if specified.',
+ array(
+ '!akismet' => url('http://akismet.com'),
+ '!wpapikey' => url('http://wordpress.com/api-keys/'),
+ ))
+ );
+ $timeout_options = array();
+ for ($n = 1; $n <= 30; $n++) {
+ $timeout_options[$n] = $n;
+ }
+ $form['service']['akismet_connection_timeout'] = array(
+ '#type' => 'select', '#title' => t('Connection timeout'),
+ '#default_value' => variable_get('akismet_connection_timeout', 10),
+ '#options' => $timeout_options,
+ '#description' => t('This option allows you to specify the connection timeout in seconds that is used for real time Akismet connections.')
+ );
+
+ $form['general'] = array(
+ '#type' => 'fieldset', '#title' => t('General Options'),
+ '#collapsible' => TRUE, '#collapsed' => TRUE
+ );
+ $age_options = drupal_map_assoc(array(0, 3600, 10800, 21600, 32400, 43200, 86400, 172800, 259200, 604800, 1209600, 1814400), 'format_interval');
+ $age_options[0] = t('never');
+ $age_options[2592000] = t('1 month');
+ $age_options[5184000] = t('2 months');
+ $age_options[7776000] = t('3 months');
+ $age_options[10368000] = t('4 months');
+ $age_options[15768000] = t('6 months');
+ $age_options[31536000] = t('1 year');
+ $form['general']['akismet_remove_spam_age'] = array(
+ '#type' => 'select', '#title' => t('Remove spam older than'),
+ '#default_value' => variable_get('akismet_remove_spam_age', 259200),
+ '#options' => $age_options,
+ '#description' => t('Content marked as spam is still saved into database so it can be reviewed by content administrators. This option allows you to specify how long this information will be kept in the database. Spam older than the age specified here will be automatically removed. Requires crontab.')
+ );
+ $form['general']['akismet_records_per_page'] = array(
+ '#type' => 'select', '#title' => t('Records per page'),
+ '#default_value' => variable_get('akismet_records_per_page', 50),
+ '#options' => drupal_map_assoc(array(10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 200)),
+ '#description' => t('The maximum number of records per page on moderation queue.')
+ );
+ $form['general']['akismet_blocks_counter'] = array(
+ '#type' => 'select', '#title' => t('Number of blocks'),
+ '#default_value' => variable_get('akismet_blocks_counter', 1),
+ '#options' => array(0=>t('none'), 1=>1, 2=>2, 3=>3, 4=>4, 5=>5),
+ '#description' => t('The akismet module may generate a number of blocks for you to display the current spam counter anywhere on your site. The number of blocks is variable to help you keep your blocks administration panel as clean as possible. This option allows you to specify how many blocks you wish to use. If you do not plan to show the spam counter to your visitors, set this option to none .',
+ array(
+ '!admin-block' => url('admin/block'),
+ ))
+ );
+ $form['general']['akismet_email_enabled'] = array(
+ '#type' => 'radios', '#title' => t('E-mail notifications'),
+ '#options' => $enable_options,
+ '#default_value' => variable_get('akismet_email_enabled', 1),
+ '#description' => t('Use this option to enable or disable e-mail notifications to content moderators. If enabled, users with proper permissions are allowed to set, from their user profiles, whether they wish to receive e-mail notications for all new (or updated) posts, just for content needing approval or no notifications at all. Users are notified about content types they are allowed to moderate only.')
+ );
+
+ $form['node_options'] = array(
+ '#type' => 'fieldset', '#title' => t('Node Options'),
+ '#collapsible' => TRUE, '#collapsed' => TRUE
+ );
+ $form['node_options']['akismet_check_nodetypes'] = array(
+ '#type' => 'checkboxes', '#title' => t('Check for spam in these node types'),
+ '#options' => node_get_types('names'),
+ '#default_value' => variable_get('akismet_check_nodetypes', NULL),
+ '#description' => t('Use this option to enable or disable spam check for nodes of types specified here. When this option is enabled, a request will be sent to the Akismet Service , in real time. If the Akismet Service was down, nodes would simply be queued for manual moderation. Users with @admin-nodes permission and spam moderators are exempt from this check.',
+ array(
+ '!akismet' => url('http://akismet.com'),
+ '@admin-nodes' => t('administer nodes'),
+ '!admin-access' => url('admin/access'),
+ ))
+ );
+ $form['node_options']['akismet_node_publish_links'] = array(
+ '#type' => 'radios', '#title' => t('Show publish/unpublish links'),
+ '#options' => $enable_options,
+ '#default_value' => variable_get('akismet_node_publish_links', 0),
+ '#description' => t('Use this option to enable or disable links for publish /unpublish operations in nodes. If enabled, these links will only be displayed to spam moderators and users with @admin-nodes permission.',
+ array(
+ '@admin-nodes' => t('administer nodes'),
+ '!admin-access' => url('admin/access'),
+ ))
+ );
+ $form['node_options']['akismet_node_spam_links'] = array(
+ '#type' => 'radios', '#title' => t('Show submit spam/ham links'),
+ '#options' => $enable_options,
+ '#default_value' => variable_get('akismet_node_spam_links', 0),
+ '#description' => t('Use this option to enable or disable links for submit spam /ham operations in nodes. If enabled, these links will only be displayed to spam moderators and users with @admin-nodes permission.',
+ array(
+ '@admin-nodes' => t('administer nodes'),
+ '!admin-access' => url('admin/access'),
+ ))
+ .' '. t('Note: To interact fully with the Akismet Service you really should try putting data back into the system as well as just taking it out. If it is at all possible, please use these links to submit missed spam and false positives (ham), otherwise Akismet will never learn from its mistakes. Thank you.',
+ array(
+ '!akismet' => url('http://akismet.com'),
+ ))
+ );
+
+ if (module_exists('comment')) {
+ $form['comment_options'] = array(
+ '#type' => 'fieldset', '#title' => t('Comment Options'),
+ '#collapsible' => TRUE, '#collapsed' => TRUE
+ );
+ $form['comment_options']['akismet_check_comments'] = array(
+ '#type' => 'radios', '#title' => t('Check for spam in comments'),
+ '#options' => $enable_options,
+ '#default_value' => variable_get('akismet_check_comments', 1),
+ '#description' => t('Use this option to enable or disable spam check for comments. When this option is enabled, a request will be sent to the Akismet Service , in real time. If the Akismet Service was down, comments would simply be queued for manual moderation. Users with @admin-comments permission and spam moderators are exempt from this check.',
+ array(
+ '!akismet' => url('http://akismet.com'),
+ '@admin-comments' => t('administer comments'),
+ '!admin-access' => url('admin/access'),
+ ))
+ );
+ $form['comment_options']['akismet_comment_publish_links'] = array(
+ '#type' => 'radios', '#title' => t('Show publish/unpublish links'),
+ '#options' => $enable_options,
+ '#default_value' => variable_get('akismet_comment_publish_links', 1),
+ '#description' => t('Use this option to enable or disable links for publish /unpublish operations in comments. If enabled, these links will only be displayed to spam moderators and users with @admin-comments permission.',
+ array(
+ '@admin-comments' => t('administer comments'),
+ '!admin-access' => url('admin/access'),
+ ))
+ );
+ $form['comment_options']['akismet_comment_spam_links'] = array(
+ '#type' => 'radios', '#title' => t('Show submit spam/ham links'),
+ '#options' => $enable_options,
+ '#default_value' => variable_get('akismet_comment_spam_links', 1),
+ '#description' => t('Use this option to enable or disable links for submit spam /ham operations in comments. If enabled, these links will only be displayed to spam moderators and users with @admin-comments permission.',
+ array(
+ '@admin-comments' => t('administer comments'),
+ '!admin-access' => url('admin/access'),
+ ))
+ .' '. t('Note: To interact fully with the Akismet Service you really should try putting data back into the system as well as just taking it out. If it is at all possible, please use these links to submit missed spam and false positives (ham), otherwise Akismet will never learn from its mistakes. Thank you.',
+ array(
+ '!akismet' => url('http://akismet.com'),
+ ))
+ );
+ }
+
+ $date_formats = array(
+ 'F j, Y', 'j F, Y', 'Y, F j',
+ 'M j, Y', 'j M, Y', 'Y, M j',
+ 'Y/m/d', 'm/d/Y', 'd/m/Y',
+ 'Y-m-d', 'm-d-Y', 'd-m-Y'
+ );
+ $date_options = array();
+ $now = time();
+ foreach ($date_formats as $format) {
+ $date_options[$format] = format_date($now, 'custom', $format);
+ }
+
+ $form['counter_options'] = array(
+ '#type' => 'fieldset', '#title' => t('Spam Counter Options'),
+ '#collapsible' => TRUE, '#collapsed' => TRUE
+ );
+ $form['counter_options']['akismet_counter_spam'] = array(
+ '#type' => 'textfield', '#title' => t('Spam counter'),
+ '#default_value' => akismet_get_spam_counter(),
+ '#size' => 10, '#maxlength' => 10,
+ '#description' => t('This counter is incremented for every spam caught by Akismet.')
+ );
+ $form['counter_options']['akismet_counter_since'] = array(
+ '#type' => 'date', '#title' => t('Counting since'),
+ '#default_value' => variable_get('akismet_counter_since', array('day' => date('j'), 'month' => date('n'), 'year' => date('Y'))),
+ '#description' => t('This is the date that will tell your visitors when your Akismet spam counter started to increment.')
+ );
+ $form['counter_options']['akismet_counter_date_format'] = array(
+ '#type' => 'select', '#title' => t('Date format'),
+ '#default_value' => variable_get('akismet_counter_date_format', $date_formats[0]),
+ '#options' => $date_options,
+ '#description' => t('Date format used to render the Counting since date.')
+ );
+
+ $form['anti_spambot'] = array(
+ '#type' => 'fieldset', '#title' => t('Anti-Spambot Options'),
+ '#collapsible' => TRUE, '#collapsed' => TRUE,
+ '#description' => t('The goal of this section is not to replace anything that the Akismet Service itself can do a lot better than us, but to provide a set of simple rules aimed to prevent Denial of Service (DoS) situations that could be caused by certain spambots.',
+ array(
+ '!akismet' => url('http://akismet.com'),
+ ))
+ );
+ $delay_options = drupal_map_assoc(array(0, 30, 60, 90, 120, 150, 180), 'format_interval');
+ $delay_options[0] = t('none');
+ $form['anti_spambot']['akismet_antispambot_delay'] = array(
+ '#type' => 'select', '#title' => t('Delay when spam is detected'),
+ '#default_value' => variable_get('akismet_antispambot_delay', 60),
+ '#options' => $delay_options,
+ '#description' => t('Use this option to delay the response when content has been identified as spam or to requests that match the rules defined below.')
+ );
+ $anti_spambot_rules = array(
+ 'ip' => t('IP addresses used by known spammers.'),
+ 'mail' => t('E-mail addresses used by known spammers.'),
+ 'body' => t('Content that has already been identified as spam.'),
+ );
+ $form['anti_spambot']['akismet_antispambot_rules'] = array(
+ '#type' => 'checkboxes', '#title' => t('Identify spambots by'),
+ '#options' => $anti_spambot_rules,
+ '#default_value' => variable_get('akismet_antispambot_rules', NULL),
+ '#description' => t('These rules will be applied before sending any request to the Akismet Service . If a request to send content matches any of these rules, the actions defined below will be triggered. Requests to send content are checked against spam that is stored locally (visible from the moderation queue ).',
+ array(
+ '!akismet' => url('http://akismet.com'),
+ '!moderation-queue' => url('admin/content/akismet'),
+ ))
+ );
+ $anti_spambot_actions = array(
+ 'none' => t('None (only the delay specified above, if any).'),
+ '503' => t('HTTP error 503 (Service Unavailable), showing a simple blank page.'),
+ '403' => t('HTTP error 403 (Forbidden), showing a simple blank page.'),
+ '403d' => t('HTTP error 403 (Forbidden), showing a Drupal generated page.')
+ );
+ $form['anti_spambot']['akismet_antispambot_action'] = array(
+ '#type' => 'radios', '#title' => t('Actions against spambots'),
+ '#options' => $anti_spambot_actions,
+ '#default_value' => variable_get('akismet_antispambot_action', '503'),
+ '#description' => t('Use this option to specify what to do against spambots identified by any of the above rules. When a HTTP error is generated (403 or 503), no request to the Akismet Service will be made, the request to post content will not be stored into database and no further moderator notifications will be sent. In any case, when a rule matches, a record of the event will be logged for further analysis.',
+ array(
+ '!akismet' => url('http://akismet.com'),
+ '!admin-reports' => url('admin/reports'),
+ ))
+ );
+
+ return system_settings_form($form);
+}
+
+/**
+ * Moderation queue operations.
+ */
+function akismet_moderator_operations($mode, $submode) {
+ // Build operations array; based on current mode.
+ if ($mode == 'nodes') {
+ $operations = array(
+ 'submit-spam' => array(
+ 'title' => (variable_get('akismet_connection_enabled', 1) ? t('Submit selected nodes as spam') : t('Mark selected nodes as spam')),
+ 'confirm' => (variable_get('akismet_connection_enabled', 1) ? t('Are you sure you want to submit these nodes as spam?') : t('Are you sure you want to mark these nodes as spam?')),
+ 'button' => (variable_get('akismet_connection_enabled', 1) ? t('Submit nodes as spam') : t('Mark nodes as spam')),
+ ),
+ 'submit-ham' => array(
+ 'title' => (variable_get('akismet_connection_enabled', 1) ? t('Submit selected nodes as ham') : t('Mark selected nodes as ham')),
+ 'confirm' => (variable_get('akismet_connection_enabled', 1) ? t('Are you sure you want to submit these nodes as ham?') : t('Are you sure you want to mark these nodes as ham?')),
+ 'button' => (variable_get('akismet_connection_enabled', 1) ? t('Submit nodes as ham') : t('Mark nodes as ham')),
+ ),
+ 'publish' => array(
+ 'title' => t('Publish selected nodes'),
+ 'confirm' => t('Are you sure you want to publish these nodes?'),
+ 'button' => t('Publish nodes'),
+ ),
+ 'unpublish' => array(
+ 'title' => t('Unpublish selected nodes'),
+ 'confirm' => t('Are you sure you want to unpublish these nodes?'),
+ 'button' => t('Unpublish nodes'),
+ ),
+ 'delete' => array(
+ 'title' => t('Delete selected nodes'),
+ 'confirm' => t('Are you sure you want to delete these nodes and all their comments?'),
+ 'button' => t('Delete nodes'),
+ 'warning' => t('This action cannot be undone.')
+ )
+ );
+ }
+ else if ($mode == 'comments') {
+ $operations = array(
+ 'submit-spam' => array(
+ 'title' => (variable_get('akismet_connection_enabled', 1) ? t('Submit selected comments as spam') : t('Mark selected comments as spam')),
+ 'confirm' => (variable_get('akismet_connection_enabled', 1) ? t('Are you sure you want to submit these comments as spam?') : t('Are you sure you want to mark these comments as spam?')),
+ 'button' => (variable_get('akismet_connection_enabled', 1) ? t('Submit comments as spam') : t('Mark comments as spam')),
+ ),
+ 'submit-ham' => array(
+ 'title' => (variable_get('akismet_connection_enabled', 1) ? t('Submit selected comments as ham') : t('Mark selected comments as ham')),
+ 'confirm' => (variable_get('akismet_connection_enabled', 1) ? t('Are you sure you want to submit these comments as ham?') : t('Are you sure you want to mark these comments as ham?')),
+ 'button' => (variable_get('akismet_connection_enabled', 1) ? t('Submit comments as ham') : t('Mark comments as ham')),
+ ),
+ 'publish' => array(
+ 'title' => t('Publish selected comments'),
+ 'confirm' => t('Are you sure you want to publish these comments?'),
+ 'button' => t('Publish comments'),
+ ),
+ 'unpublish' => array(
+ 'title' => t('Unpublish selected comments'),
+ 'confirm' => t('Are you sure you want to unpublish these comments?'),
+ 'button' => t('Unpublish comments'),
+ ),
+ 'delete' => array(
+ 'title' => t('Delete selected comments'),
+ 'confirm' => t('Are you sure you want to delete these comments and all their replies?'),
+ 'button' => t('Delete comments'),
+ 'warning' => t('This action cannot be undone.')
+ )
+ );
+ }
+ else { // Unknown mode!
+ return array();
+ }
+
+ // Unset redundant operations; based on current submode.
+ if ($submode == 'spam') {
+ unset($operations['submit-spam']);
+ }
+ else if ($submode == 'unpublished') {
+ unset($operations['unpublish']);
+ }
+ else if ($submode == 'published') {
+ unset($operations['publish']);
+ }
+ else { // Unknown submode!
+ return array();
+ }
+
+ return $operations;
+}
+
+/**
+ * Menu callback; Moderation queue.
+ *
+ * @param string Mode: overview (default), nodes, comments.
+ * @param string Submode: spam (default), unpublished, published.
+ */
+function akismet_callback_queue($mode = '', $submode = '') {
+ // Make sure we're dealing with a valid mode and submode.
+ $valid_modes = array('nodes', 'comments');
+ $valid_submodes = array(
+ 'spam' => t('Spam'),
+ 'unpublished' => t('Unpublished'),
+ 'published' => t('Published')
+ );
+ if (empty($mode)) {
+ $mode = 'overview';
+ }
+ else if (!in_array($mode, $valid_modes)) {
+ drupal_not_found();
+ return;
+ }
+ if (empty($submode)) {
+ $submode = 'spam';
+ }
+ else if (!isset($valid_submodes[$submode])) {
+ drupal_not_found();
+ return;
+ }
+ // Compute exactly what the current user is allowed to moderate.
+ $moderator_types = akismet_get_moderator_types();
+ $moderator_types_count = count($moderator_types);
+ $allowed_comments = (isset($moderator_types['comments']) ? TRUE : FALSE);
+ $allowed_nodes = $moderator_types;
+ if ($allowed_comments) {
+ unset($allowed_nodes['comments']);
+ }
+ $allowed_nodes_count = count($allowed_nodes);
+
+ // Make sure the user has some kind of content administration/moderation permission.
+ if ($allowed_nodes_count <= 0 && !$allowed_comments) {
+ drupal_access_denied();
+ return;
+ }
+
+ // Dynamically build the queries using a write once method.
+ if ($allowed_nodes_count > 0) {
+ $sql_nodetypes = array();
+ foreach ($allowed_nodes as $type => $name) {
+ $sql_nodetypes[] = '\''. $type .'\'';
+ }
+ $sql_nodetypes = implode(', ', $sql_nodetypes);
+ $sql_from = 'FROM {node} n LEFT JOIN {akismet_spam_marks} s ON s.content_id = n.nid AND s.content_type = \'node\'';
+ $sql_where = 'WHERE n.type IN ('. $sql_nodetypes .') AND (%cond)';
+ $sql_nodes_cond = array(
+ 'spam' => 's.content_id IS NOT NULL',
+ 'unpublished' => 'n.status = 0',
+ 'published' => 'n.status = 1'
+ );
+
+ $sql_nodes_stmt = 'SELECT n.*, u.name, IFNULL(s.content_id, 0) AS spam_mark '. $sql_from .' INNER JOIN {users} u ON n.uid = u.uid '. $sql_where;
+ $sql_nodes_cnt = 'SELECT COUNT(*) AS cnt '. $sql_from .' '. $sql_where;
+ }
+ if (module_exists('comment') && $allowed_comments) {
+ $sql_from = 'FROM {comments} c LEFT JOIN {akismet_spam_marks} s ON s.content_id = c.cid AND s.content_type = \'comment\'';
+ $sql_where = 'WHERE (%cond)';
+ $sql_comments_cond = array(
+ 'spam' => 's.content_id IS NOT NULL',
+ 'unpublished' => 'c.status = '. COMMENT_NOT_PUBLISHED,
+ 'published' => 'c.status = '. COMMENT_PUBLISHED
+ );
+ $sql_comments_stmt = 'SELECT c.*, u.name AS registered_name, IFNULL(s.content_id, 0) AS spam_mark '. $sql_from .' INNER JOIN {users} u ON c.uid = u.uid '. $sql_where;
+ $sql_comments_cnt = 'SELECT COUNT(*) AS cnt '. $sql_from .' '. $sql_where;
+ }
+
+ $sql = array(
+ 'sql_comments_cnt' => $sql_comments_cnt,
+ 'sql_comments_stmt' => $sql_comments_stmt,
+ 'sql_comments_cond' => $sql_comments_cond,
+ 'sql_nodes_cnt' => $sql_nodes_cnt,
+ 'sql_nodes_stmt' => $sql_nodes_stmt,
+ 'sql_nodes_cond' => $sql_nodes_cond,
+ );
+
+ // Present the overview page (default).
+ if ($mode == 'overview') {
+ $items = array();
+ if ($allowed_nodes_count > 0) {
+ $subitems = array();
+ foreach ($valid_submodes as $key => $title) {
+ $sql_cnt = str_replace('%cond', $sql_nodes_cond[$key], $sql_nodes_cnt);
+ $count = db_result(db_query(db_rewrite_sql($sql_cnt)));
+ $path = 'admin/content/akismet/nodes'. ($key == 'spam' ? '' : '/'. $key);
+ $label = ($count > 0 ? l($title, $path) : $title);
+ $subitems[] = ''. $label .': '. $count .'
';
+ }
+ $items[] = ''. t('Nodes') .' '. theme('item_list', $subitems);
+ }
+ if (module_exists('comment') && $allowed_comments) {
+ $subitems = array();
+ foreach ($valid_submodes as $key => $title) {
+ $sql_cnt = str_replace('%cond', $sql_comments_cond[$key], $sql_comments_cnt);
+ $count = db_result(db_query(db_rewrite_sql($sql_cnt, 'c', 'cid')));
+ $path = 'admin/content/akismet/comments'. ($key == 'spam' ? '' : '/'. $key);
+ $label = ($count > 0 ? l($title, $path) : $title);
+ $subitems[] = ''. $label .': '. $count .'
';
+ }
+ $items[] = ''. t('Comments') .' '. theme('item_list', $subitems);
+ }
+ return ''. t('Summary of content:') .' '. theme('item_list', $items);
+ }
+ if (isset($_POST) && count($_POST['items']) > 0) {
+ return drupal_get_form('akismet_confirm_multiple_operation');
+ }
+ else {
+ return drupal_get_form('akismet_moderation_form', $mode, $submode, $sql);
+ }
+}
+
+function akismet_moderation_form($mode = '', $submode = '', $sql = array()) {
+ // Build the moderation queue form.
+ $form = array();
+ $form['options'] = array(
+ '#type' => 'fieldset', '#title' => t('Moderator actions'),
+ '#prefix' => '', '#suffix' => '
'
+ );
+
+ extract($sql);
+
+ $options = array('' => t(''));
+ foreach (akismet_moderator_operations($mode, $submode) as $key => $operation_info) {
+ $options[$key] = $operation_info['title'];
+ }
+ $form['options']['operation'] = array('#type' => 'select', '#options' => $options, '#default_value' => '');
+ $form['options']['submit'] = array('#type' => 'submit', '#value' => t('Submit'));
+
+ if ($mode == 'nodes') {
+ $sql_stmt = str_replace('%cond', $sql_nodes_cond[$submode], $sql_nodes_stmt);
+ $sql_cnt = str_replace('%cond', $sql_nodes_cond[$submode], $sql_nodes_cnt);
+ $form['header'] = array('#type' => 'value', '#value' => array(
+ theme('table_select_header_cell'),
+ array('data' => t('Title'), 'field' => 'title'),
+ array('data' => t('Type'), 'field' => 'type'),
+ array('data' => t('Author'), 'field' => 'name'),
+ array('data' => t('Status'), 'field' => 'status'),
+ array('data' => t('Last changed'), 'field' => 'changed', 'sort' => 'desc')
+ ));
+ }
+ else { // comments
+ $sql_stmt = str_replace('%cond', $sql_comments_cond[$submode], $sql_comments_stmt);
+ $sql_cnt = str_replace('%cond', $sql_comments_cond[$submode], $sql_comments_cnt);
+ $form['header'] = array('#type' => 'value', '#value' => array(
+ theme('table_select_header_cell'),
+ array('data' => t('Subject'), 'field' => 'subject'),
+ array('data' => t('Author'), 'field' => 'name'),
+ array('data' => t('Status'), 'field' => 'status'),
+ array('data' => t('Last changed'), 'field' => 'timestamp', 'sort' => 'desc')
+ ));
+ }
+
+ $records_per_page = variable_get('akismet_records_per_page', 50);
+ $result = pager_query($sql_stmt . tablesort_sql($form['header']['#value']), $records_per_page, 0, $sql_cnt);
+ $items = array();
+ $now = time();
+ while ($content = db_fetch_object($result)) {
+ if ($mode == 'nodes') {
+ $items[$content->nid] = '';
+ $form['title'][$content->nid] = array('#value' => l($content->title, 'node/'. $content->nid, array('title' => truncate_utf8($content->body, 128))) .' '. theme('mark', node_mark($content->nid, $content->changed)));
+ $form['type'][$content->nid] = array('#value' => node_get_types('name', $content));
+ $form['author'][$content->nid] = array('#value' => theme('username', $content));
+ $form['status'][$content->nid] = array('#value' => ($content->status ? t('published') : t('not published')));
+ if ($content->spam_mark) {
+ $form['status'][$content->nid]['#value'] .= t('/spam');
+ }
+ $form['created'][$content->nid] = array('#value' => t('%time ago', array('%time' => format_interval($now - $content->changed))));
+ }
+ else { // comments
+ $items[$content->cid] = '';
+ $content->name = $content->uid ? $content->registered_name : $content->name;
+ $form['title'][$content->cid] = array('#value' => l($content->subject, 'node/'. $content->nid, array('title' => truncate_utf8($content->comment, 128)), NULL, 'comment-'. $content->cid) .' '. theme('mark', node_mark($content->nid, $content->timestamp)));
+ $form['author'][$content->cid] = array('#value' => theme('username', $content));
+ $form['status'][$content->cid] = array('#value' => ($content->status == COMMENT_PUBLISHED ? t('published') : t('not published')));
+ if ($content->spam_mark) {
+ $form['status'][$content->cid]['#value'] .= t('/spam');
+ }
+ $form['created'][$content->cid] = array('#value' => t('%time ago', array('%time' => format_interval($now - $content->timestamp))));
+ }
+ }
+
+ $form['mode'] = array('#type' => 'hidden', '#value' => $mode);
+ $form['submode'] = array('#type' => 'hidden', '#value' => $submode);
+ $form['items'] = array('#type' => 'checkboxes', '#options' => $items);
+ $form['pager'] = array('#value' => theme('pager', NULL, $records_per_page, 0));
+ return $form;
+}
+
+/**
+ * Theme callback; render the moderation queue form.
+ */
+function theme_akismet_moderation_form($form) {
+ $mode = $form['mode']['#value'];
+ $submode = $form['submode']['#value'];
+ $output = drupal_render($form['options']);
+ $rows = array();
+ if (isset($form['author']) && is_array($form['author'])) {
+ foreach (element_children($form['author']) as $key) {
+ $row = array();
+ $row[] = array('data' => drupal_render($form['items'][$key]));
+ $row[] = drupal_render($form['title'][$key]);
+ if ($mode == 'nodes') {
+ $row[] = drupal_render($form['type'][$key]);
+ }
+ $row[] = drupal_render($form['author'][$key]);
+ $row[] = drupal_render($form['status'][$key]);
+ $row[] = drupal_render($form['created'][$key]);
+ $rows[] = $row;
+ }
+ }
+ else {
+ if ($submode == 'spam') {
+ $message = ($mode == 'nodes' ? t('There is no spam in the nodes moderation queue.') : t('There is no spam in the comments moderation queue.')) .' '. t('It must be your lucky day! ;-)');
+ }
+ else if ($submode == 'unpublished') {
+ $message = ($mode == 'nodes' ? t('There are no unpublished nodes in the moderation queue.') : t('There are no unpublished comments in the moderation queue.'));
+ }
+ else { // published
+ $message = ($mode == 'nodes' ? t('There are no published nodes.') : t('There are no published comments.'));
+ }
+ $rows[] = array(array('data' => $message, 'align' => 'center', 'colspan' => ($mode == 'nodes' ? '6' : '5')));
+ }
+ $output .= theme('table', $form['header']['#value'], $rows);
+ if ($form['pager']['#value']) {
+ $output .= drupal_render($form['pager']);
+ }
+ $output .= drupal_render($form);
+ return $output;
+}
+
+/**
+ * Form API callback; Validate the moderation queue form.
+ */
+function akismet_moderation_form_validate($form, &$form_state) {
+ $mode = $form_state['values']['mode'];
+ $submode = $form_state['values']['submode'];
+ $operation = $form_state['values']['operation'];
+ $valid_operations = akismet_moderator_operations($mode, $submode);
+
+ if (!isset($valid_operations[$operation])) {
+ form_set_error('', t('Please, choose a valid operation.'));
+ }
+ $form_state['values']['items'] = array_diff($form_state['values']['items'], array(0));
+ if (count($form_state['values']['items']) == 0) {
+ if ($operation == 'delete') {
+ form_set_error('', t('Please, select some items to perform the delete operation.'));
+ }
+ else {
+ form_set_error('', t('Please, select some items to perform the action on.'));
+ }
+ }
+}
+
+/**
+ * List the selected items and verify that the admin really wants to delete them.
+ */
+function akismet_confirm_multiple_operation() {
+ $edit = $_POST;
+ $mode = $edit['mode'];
+ $submode = $edit['submode'];
+ $operation = $edit['operation'];
+ $valid_operations = akismet_moderator_operations($mode, $submode);
+
+ // Make sure we deal with a valid combination of mode, submode and operation.
+ if (!isset($valid_operations[$operation])) {
+ return;
+ }
+
+ $confirm_message = ''. $valid_operations[$operation]['confirm'] .' ';
+ $confirm_button = $valid_operations[$operation]['button'];
+ $confirm_warning = ''. (isset($valid_operations[$operation]['warning']) ? $valid_operations[$operation]['warning'] : '') .'
';
+ $content_type = ($mode == 'nodes' ? 'node' : 'comment');
+
+ $form = array();
+ $form['items'] = array('#prefix' => '', '#tree' => TRUE);
+ // array_filter() returns only elements with actual values
+ foreach (array_filter($edit['items']) as $content_id => $value) {
+ if ($content = akismet_content_load($content_type, $content_id)) {
+ $title = '"'. check_plain($content_type == 'node' ? $content->title : $content->subject) .'", '. t('by') .' '. theme('username', $content);
+ $form['items'][$content_id] = array('#type' => 'hidden', '#value' => $content_id, '#prefix' => '', '#suffix' => $title .' ');
+ }
+ }
+ $form['mode'] = array('#type' => 'hidden', '#value' => $mode);
+ $form['submode'] = array('#type' => 'hidden', '#value' => $submode);
+ $form['operation'] = array('#type' => 'hidden', '#value' => $operation);
+
+ // Redirect to a non-existent menu item to make tabs disappear.
+ menu_set_active_item('');
+
+ $path = 'admin/content/akismet/'. $mode;
+ if ($submode != 'spam') {
+ $path .= '/'. $submode;
+ }
+ return confirm_form($form, $confirm_message, $path, $confirm_warning, $confirm_button, t('Cancel'));
+}
+
+/**
+ * confirm_form callback; perform the actual operation against selected content.
+ */
+function akismet_confirm_multiple_operation_submit($form, &$form_state) {
+ $mode = $form_state['values']['mode'];
+ $submode = $form_state['values']['submode'];
+ $operation = $form_state['values']['operation'];
+ $valid_operations = akismet_moderator_operations($mode, $submode);
+
+ // Make sure we deal with a valid combination of mode, submode and operation.
+ if (!isset($valid_operations[$operation])) {
+ return 'admin/content/akismet';
+ }
+
+ if ($form_state['values']['confirm']) {
+ $content_type = ($mode == 'nodes' ? 'node' : 'comment');
+ foreach ($form_state['values']['items'] as $content_id => $value) {
+ if ($operation == 'delete') {
+ akismet_content_delete($content_type, $content_id);
+ $message = ($mode == 'nodes' ? t('The nodes have been deleted.') : t('The comments have been deleted.'));
+ }
+ else if ($content = akismet_content_load($content_type, $content_id)) {
+ if ($content_type == 'node') {
+ $is_published = ($content->status ? TRUE : FALSE);
+ }
+ else { // comment
+ $is_published = ($content->status == COMMENT_PUBLISHED ? TRUE : FALSE);
+ }
+ $is_spam = akismet_content_is_spam($content_type, $content_id);
+
+ if ($operation == 'submit-spam' && !$is_spam) {
+ akismet_content_spam_operation($content_type, $content, 'submit-spam');
+ }
+ else if ($operation == 'submit-ham' && $is_spam) {
+ akismet_content_spam_operation($content_type, $content, 'submit-ham');
+ }
+
+ if (in_array($operation, array('unpublish','submit-spam')) && $is_published) {
+ akismet_content_publish_operation($content_type, $content, 'unpublish');
+ }
+ else if (in_array($operation, array('publish','submit-ham')) && !$is_published) {
+ akismet_content_publish_operation($content_type, $content, 'publish');
+ }
+
+ $message = ($mode == 'nodes' ? t('The nodes have been updated.') : t('The comments have been updated.'));
+ }
+ }
+ drupal_set_message($message);
+ }
+
+ $path = 'admin/content/akismet/'. $mode;
+ if ($submode != 'spam') {
+ $path .= '/'. $submode;
+ }
+ return $path;
+}
Index: akismet.info
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/akismet/akismet.info,v
retrieving revision 1.3
diff -u -p -r1.3 akismet.info
--- akismet.info 18 Jun 2007 23:50:47 -0000 1.3
+++ akismet.info 23 Feb 2008 21:00:43 -0000
@@ -1,3 +1,3 @@
name = Akismet
description = Use the Akismet Service to protect your site from spam.
-
+core = 6.x
Index: akismet.install
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/akismet/akismet.install,v
retrieving revision 1.3
diff -u -p -r1.3 akismet.install
--- akismet.install 1 Jun 2007 21:41:17 -0000 1.3
+++ akismet.install 23 Feb 2008 21:00:43 -0000
@@ -2,80 +2,114 @@
// $Id: akismet.install,v 1.3 2007/06/01 21:41:17 drewish Exp $
/**
+ * Implementation of hook_schema().
+ */
+function akismet_schema() {
+ $schema['akismet_spam_marks'] = array(
+ 'fields' => array(
+ 'content_type' => array(
+ 'type' => 'varchar',
+ 'length' => 20,
+ 'not null' => TRUE,
+ 'default' => '',
+ ),
+ 'content_id' => array(
+ 'type' => 'int',
+ 'unsigned' => TRUE,
+ 'not null' => TRUE,
+ 'default' => 0,
+ ),
+ 'spam_created' => array(
+ 'type' => 'int',
+ 'unsigned' => TRUE,
+ 'not null' => TRUE,
+ 'default' => 0,
+ ),
+ 'hostname' => array(
+ 'type' => 'varchar',
+ 'length' => 128,
+ 'not null' => TRUE,
+ 'default' => '',
+ ),
+ 'mail' => array(
+ 'type' => 'varchar',
+ 'length' => 128,
+ 'not null' => TRUE,
+ 'default' => '',
+ ),
+ ),
+ 'unique key' => array(
+ 'content' => array('content_type', 'content_id'),
+ ),
+ 'indexes' => array(
+ 'spam_created' => array('spam_created'),
+ 'hostname' => array('hostname'),
+ 'mail' => array('mail'),
+ ),
+ );
+ $schema['akismet_moderator'] = array(
+ 'fields' => array(
+ 'uid' => array(
+ 'type' => 'int',
+ 'unsigned' => TRUE,
+ 'not null' => TRUE,
+ 'default' => 0,
+ ),
+ 'email_for' => array(
+ 'type' => 'varchar',
+ 'length' => 20,
+ 'not null' => TRUE,
+ 'default' => '',
+ ),
+ ),
+ 'primary key' => array('uid'),
+ 'indexes' => array(
+ 'email_for' => array('email_for'),
+ ),
+ );
+}
+
+/**
* Implementation of hook_install().
*/
function akismet_install() {
- switch ($GLOBALS['db_type']) {
- case 'mysql':
- case 'mysqli':
- db_query("CREATE TABLE {akismet_spam_marks} (
- content_type varchar(20) NOT NULL default '',
- content_id int(10) unsigned NOT NULL default 0,
- spam_created int(11) unsigned NOT NULL default 0,
- hostname varchar(128) NOT NULL default '',
- mail varchar(128) NOT NULL default '',
- UNIQUE content (content_type, content_id),
- INDEX spam_created (spam_created),
- INDEX hostname (hostname),
- INDEX mail (mail)
- ) /*!40100 DEFAULT CHARACTER SET utf8 */;");
- db_query("CREATE TABLE {akismet_moderator} (
- uid int(10) unsigned NOT NULL default 0,
- email_for varchar(20) NOT NULL default '',
- PRIMARY KEY (uid),
- INDEX email_for (email_for)
- ) /*!40100 DEFAULT CHARACTER SET utf8 */;");
- break;
-
- case 'pgsql':
- db_query("CREATE TABLE {akismet_spam_marks} (
- content_type varchar(20) NOT NULL default '',
- content_id integer NOT NULL default 0 CHECK (content_id >= 0),
- spam_created integer NOT NULL default 0 CHECK (spam_created >= 0),
- hostname varchar(128) NOT NULL default '',
- mail varchar(128) NOT NULL default ''
- )");
- db_query("CREATE UNIQUE INDEX {akismet_spam_marks_content} ON {akismet_spam_marks} (content_type, content_id)");
- db_query("CREATE INDEX {akismet_spam_marks_spamcreated} ON {akismet_spam_marks} (spam_created)");
- db_query("CREATE INDEX {akismet_spam_marks_hostname} ON {akismet_spam_marks} (hostname)");
- db_query("CREATE INDEX {akismet_spam_marks_mail} ON {akismet_spam_marks} (mail)");
- db_query("CREATE TABLE {akismet_moderator} (
- uid INTEGER NOT NULL DEFAULT 0 CHECK (uid >= 0),
- email_for VARCHAR(20) NOT NULL DEFAULT '',
- PRIMARY KEY (uid)
- )");
- db_query("CREATE INDEX {akismet_moderator_email_for} ON {akismet_moderator} (email_for)");
- break;
- }
+ drupal_install_schema('akismet');
+}
+
+/**
+ * Implementation of hook_uninstall().
+ */
+function akismet_uninstall() {
+ drupal_uninstall_schema('akismet');
}
/**
* Update 1: Add table for moderator extensions.
*/
function akismet_update_1() {
- $ret = array();
-
- switch ($GLOBALS['db_type']) {
- case 'mysql':
- case 'mysqli':
- $ret[] = update_sql("CREATE TABLE {akismet_moderator} (
- uid int(10) unsigned NOT NULL default 0,
- email_for varchar(20) NOT NULL default '',
- PRIMARY KEY (uid),
- INDEX email_for (email_for)
- ) /*!40100 DEFAULT CHARACTER SET utf8 */;");
- break;
-
- case 'pgsql':
- $ret[] = update_sql("CREATE TABLE {akismet_moderator} (
- uid INTEGER NOT NULL DEFAULT 0 CHECK (uid >= 0),
- email_for VARCHAR(20) NOT NULL DEFAULT '',
- PRIMARY KEY (uid)
- )");
- $ret[] = update_sql("CREATE INDEX {akismet_moderator_email_for} ON {akismet_moderator} (email_for)");
- break;
- }
+ $schema['akismet_moderator'] = array(
+ 'field' => array(
+ 'uid' => array(
+ 'type' => 'int',
+ 'unsigned' => TRUE,
+ 'not null' => TRUE,
+ 'default' => 0,
+ ),
+ 'email_for' => array(
+ 'type' => 'varchar',
+ 'length' => 20,
+ 'not null' => TRUE,
+ 'default' => '',
+ ),
+ ),
+ 'primary key' => array('uid'),
+ 'indexes' => array(
+ 'email_for' => array('email_for'),
+ ),
+ );
+ $ret = array();
+ db_create_table($ret, 'akismet_moderator', $schema['akismet_moderator']);
return $ret;
}
@@ -85,30 +119,21 @@ function akismet_update_1() {
function akismet_update_2() {
$ret = array();
- switch ($GLOBALS['db_type']) {
- case 'mysql':
- case 'mysqli':
- $ret[] = update_sql("ALTER TABLE {akismet_spam_marks} ADD COLUMN hostname varchar(128) NOT NULL default ''");
- $ret[] = update_sql("ALTER TABLE {akismet_spam_marks} ADD INDEX hostname (hostname)");
-
- $ret[] = update_sql("ALTER TABLE {akismet_spam_marks} ADD COLUMN mail varchar(128) NOT NULL default ''");
- $ret[] = update_sql("ALTER TABLE {akismet_spam_marks} ADD INDEX mail (mail)");
- break;
-
- case 'pgsql':
- $ret[] = update_sql("ALTER TABLE {akismet_spam_marks} ADD COLUMN hostname VARCHAR(128)");
- $ret[] = update_sql("ALTER TABLE {akismet_spam_marks} ALTER COLUMN hostname SET DEFAULT ''");
- $ret[] = update_sql("UPDATE TABLE {akismet_spam_marks} SET hostname = '' WHERE hostname IS NULL");
- $ret[] = update_sql("ALTER TABLE {akismet_spam_marks} ALTER COLUMN hostname SET NOT NULL");
- $ret[] = update_sql("CREATE INDEX {akismet_spam_marks_hostname} ON {akismet_spam_marks} (hostname)");
-
- $ret[] = update_sql("ALTER TABLE {akismet_spam_marks} ADD COLUMN mail VARCHAR(128)");
- $ret[] = update_sql("ALTER TABLE {akismet_spam_marks} ALTER COLUMN mail SET DEFAULT ''");
- $ret[] = update_sql("UPDATE TABLE {akismet_spam_marks} SET mail = '' WHERE mail IS NULL");
- $ret[] = update_sql("ALTER TABLE {akismet_spam_marks} ALTER COLUMN mail SET NOT NULL");
- $ret[] = update_sql("CREATE INDEX {akismet_spam_marks_mail} ON {akismet_spam_marks} (mail)");
- break;
- }
+ db_add_field($ret, 'akismet_spam_marks', 'hostname', array(
+ 'type' => 'varchar',
+ 'length' => 128,
+ 'not null' => TRUE,
+ 'default' => '',
+ ));
+ db_add_index($ret, 'akismet_spam_marks', 'hostname', array('hostname'));
+
+ db_add_field($ret, 'akismet_spam_marks', 'mail', array(
+ 'type' => 'varchar',
+ 'length' => 128,
+ 'not null' => TRUE,
+ 'default' => '',
+ ));
+ db_add_index($ret, 'akismet_spam_marks', 'mail', array('mail'));
return $ret;
}
Index: akismet.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/akismet/akismet.module,v
retrieving revision 1.18
diff -u -p -r1.18 akismet.module
--- akismet.module 1 Jun 2007 22:20:40 -0000 1.18
+++ akismet.module 23 Feb 2008 21:00:44 -0000
@@ -4,8 +4,8 @@
/**
* Akismet Drupal and Module versions.
*/
-define('AKISMET_DRUPAL_VERSION', '5');
-define('AKISMET_MODULE_VERSION', '1.2');
+define('AKISMET_DRUPAL_VERSION', '6');
+define('AKISMET_MODULE_VERSION', '2.0');
define('AKISMET_MODULE_HOMEURL', 'http://www.drupal.org/project/akismet');
define('AKISMET_MODULE_USERAGENT', 'Drupal/'. AKISMET_DRUPAL_VERSION .' | akismet.module/'. AKISMET_MODULE_VERSION);
@@ -26,9 +26,9 @@ define('AKISMET_API_RESULT_IS_HAM', 2);
/**
* Implementation of hook_help().
*/
-function akismet_help($section) {
+function akismet_help($path, $arg) {
$output = '';
- switch ($section) {
+ switch ($path) {
case 'admin/help#akismet':
$output = t('In order to use the Akismet Service , you need a WordPress.com API key . If you don\'t have one already, you can get it by simply signing up for a free account at wordpress.com . Please, consult the Akismet FAQ for further information.
The akismet module may automatically check for spam posted in content (nodes and/or comments) by any user, except node or comment administrators respectively. It is also possible, from the access control panel, to grant %no-check-perm permission to user roles of your choice.
@@ -55,37 +55,33 @@ function akismet_help($section) {
));
$output .= t('Akismet has caught @count spam for you since %since.
', array('@count' => akismet_get_spam_counter(), '%since' => akismet_get_counting_since()));
break;
- default:
- if (arg(0) == 'admin' && arg(1) == 'content '&& arg(2) == 'akismet' && !isset($_POST)) {
- if (arg(3) == 'nodes') {
- if (arg(4) == 'unpublished') {
- $output = t('Below is the list of unpublished nodes awaiting for moderation.');
- }
- else if (arg(4) == 'published') {
- $output = t('Below is the list of published nodes .');
- }
- else { // spam
- $output = t('Below is the list of nodes marked as spam awaiting for moderation.');
- }
- $output .= ' '. t('Click on the titles to see the content of the nodes or the author\'s name to view the author\'s user information. You may also wish to click on the headers to order the nodes upon your needs.');
- }
- else if (arg(3) == 'comments') {
- if (arg(4) == 'unpublished') {
- $output = t('Below is the list of unpublished comments awaiting for moderation.');
- }
- else if (arg(4) == 'published') {
- $output = t('Below is the list of published comments .');
- }
- else { // spam
- $output = t('Below is the list of comments marked as spam awaiting for moderation.');
- }
- $output .= ' '. t('Click on the subjects to see the comments or the author\'s name to view the author\'s user information. You may also wish to click on the headers to order the comments upon your needs.');
- }
- if (!empty($output)) {
- $output .= ' '. t('Note: To interact fully with the Akismet Service you really should try putting data back into the system as well as just taking it out. If it is at all possible, please use the submit ham operation rather than simply publishing content that was identified as spam (false positives). This is necessary in order to let Akismet learn from its mistakes. Thank you.', array('!akismet' => url('http://akismet.com')));
- }
- }
+ case 'admin/content/akismet/nodes/unpublished':
+ $output = t('Below is the list of unpublished nodes awaiting for moderation.');
+ $output .= ' '. t('Click on the titles to see the content of the nodes or the author\'s name to view the author\'s user information. You may also wish to click on the headers to order the nodes upon your needs.');
+ break;
+ case 'admin/content/akismet/nodes/published':
+ $output = t('Below is the list of published nodes .');
+ $output .= ' '. t('Click on the titles to see the content of the nodes or the author\'s name to view the author\'s user information. You may also wish to click on the headers to order the nodes upon your needs.');
break;
+ case 'admin/content/akismet/nodes': // spam
+ $output = t('Below is the list of nodes marked as spam awaiting for moderation.');
+ $output .= ' '. t('Click on the titles to see the content of the nodes or the author\'s name to view the author\'s user information. You may also wish to click on the headers to order the nodes upon your needs.');
+ break;
+ case 'admin/content/akismet/comments/unpublished':
+ $output = t('Below is the list of unpublished comments awaiting for moderation.');
+ $output .= ' '. t('Click on the subjects to see the comments or the author\'s name to view the author\'s user information. You may also wish to click on the headers to order the comments upon your needs.');
+ break;
+ case 'admin/content/akismet/comments/published':
+ $output = t('Below is the list of published comments .');
+ $output .= ' '. t('Click on the subjects to see the comments or the author\'s name to view the author\'s user information. You may also wish to click on the headers to order the comments upon your needs.');
+ break;
+ case 'admin/content/akismet/comments': // spam
+ $output = t('Below is the list of comments marked as spam awaiting for moderation.');
+ $output .= ' '. t('Click on the subjects to see the comments or the author\'s name to view the author\'s user information. You may also wish to click on the headers to order the comments upon your needs.');
+ break;
+ }
+ if (arg(0) == 'admin' && arg(1) == 'content '&& arg(2) == 'akismet' && !isset($_POST) && !empty($output)) {
+ $output .= ' '. t('Note: To interact fully with the Akismet Service you really should try putting data back into the system as well as just taking it out. If it is at all possible, please use the submit ham operation rather than simply publishing content that was identified as spam (false positives). This is necessary in order to let Akismet learn from its mistakes. Thank you.', array('!akismet' => url('http://akismet.com')));
}
return $output;
}
@@ -135,111 +131,204 @@ function akismet_cron() {
register_shutdown_function('akismet_cron_shutdown');
}
-/**
- * Implementation of hook_settings().
- */
-function akismet_settings() {
- require_once('./'. drupal_get_path('module', 'akismet') . '/akismet_admin.inc');
- return _akismet_settings_form();
+function _akismet_moderator_types_count($types = array()) {
+ if (empty($types)) {
+ $types = akismet_get_moderator_types();
+ }
+ return count($types);
+}
+
+function _akismet_is_moderator($moderator_types = array(), $type = '') {
+ if (empty($moderator_types)) {
+ $moderator_types = akismet_get_moderator_types();
+ }
+ if (_akismet_moderator_types_count($moderator_types) > 0 && (empty($type) || isset($moderator_types[$type]))) {
+ return TRUE;
+ }
+ else {
+ return FALSE;
+ }
+}
+
+function _akismet_is_node_moderator($moderator_types = array()) {
+ if (empty($moderator_types)) {
+ $moderator_types = akismet_get_moderator_types();
+ }
+ if (_akismet_is_moderator($moderator_types) && (!_akismet_is_moderator($moderator_types, $type = 'comments') || _akismet_moderator_types_count($moderator_types) > 1)) {
+ return TRUE;
+ }
+ else {
+ return FALSE;
+ }
+}
+
+function _akismet_is_moderator_type($type, $types = array()) {
+ if (empty($types)) {
+ $types = akismet_get_moderator_types();
+ }
+ if (_akismet_moderator_types_count($types) > 0 && isset($types[$type])) {
+ return TRUE;
+ }
+ else {
+ return FALSE;
+ }
}
/**
* Implementation of hook_menu().
*/
-function akismet_menu($may_cache) {
+function akismet_menu() {
$items = array();
- if ($may_cache) {
- // Changes in content types force the menu to be rebuilt,
- // so it should be safe to cache this menu items here.
- // Users will only see this menu if they actually can
- // moderate, at least, one content type.
- $items[] = array('path' => 'admin/settings/akismet',
- 'title' => t('Akismet'), 'description' => t('Use the Akismet Service to protect your site from spam.'),
- 'callback' => 'drupal_get_form', 'callback arguments' => array('akismet_settings'),
- 'access' => user_access('administer akismet settings'));
+ $items['admin/settings/akismet'] = array(
+ 'title' => t('Akismet'),
+ 'description' => t('Use the Akismet Service to protect your site from spam.'),
+ 'page callback' => 'drupal_get_form',
+ 'page arguments' => array('akismet_settings'),
+ 'access arguments' => array('administer akismet settings'),
+ 'file' => 'akismet.admin.inc',
+ );
- $moderator_types = akismet_get_moderator_types();
- $moderator_types_count = count($moderator_types);
- if ($moderator_types_count > 0) {
- $items[] = array('path' => 'admin/content/akismet', 'title' => t('Akismet moderation queue'),
- 'description' => t('Manage the Akismet spam queue, appropving or deleting content in need of moderation.'),
- 'callback' => 'akismet_callback_queue',
- 'access' => ($moderator_types_count > 0 ? TRUE : FALSE));
- $items[] = array('path' => 'admin/content/akismet/overview', 'title' => t('Overview'),
- 'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => 0);
- if (!isset($moderator_types['comments']) || $moderator_types_count > 1) {
- $items[] = array('path' => 'admin/content/akismet/nodes', 'title' => t('Nodes'),
- 'callback' => 'akismet_callback_queue',
- 'callback arguments' => array('nodes'),
- 'type' => MENU_LOCAL_TASK, 'weight' => 1);
- $items[] = array('path' => 'admin/content/akismet/nodes/spam', 'title' => t('Spam'),
- 'callback' => 'akismet_callback_queue',
- 'callback arguments' => array('nodes'),
- 'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => 0);
- $items[] = array('path' => 'admin/content/akismet/nodes/unpublished', 'title' => t('Unpublished nodes'),
- 'callback' => 'akismet_callback_queue',
- 'callback arguments' => array('nodes', 'unpublished'),
- 'type' => MENU_LOCAL_TASK, 'weight' => 1);
- $items[] = array('path' => 'admin/content/akismet/nodes/published', 'title' => t('Published nodes'),
- 'callback' => 'akismet_callback_queue',
- 'callback arguments' => array('nodes', 'published'),
- 'type' => MENU_LOCAL_TASK, 'weight' => 2);
- }
- if (isset($moderator_types['comments'])) {
- $items[] = array('path' => 'admin/content/akismet/comments', 'title' => t('Comments'),
- 'callback' => 'akismet_callback_queue',
- 'callback arguments' => array('comments'),
- 'type' => MENU_LOCAL_TASK, 'weight' => 2);
- $items[] = array('path' => 'admin/content/akismet/comments/spam', 'title' => t('Spam'),
- 'callback' => 'akismet_callback_queue',
- 'callback arguments' => array('comments'),
- 'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => 0);
- $items[] = array('path' => 'admin/content/akismet/comments/unpublished', 'title' => t('Unpublished comments'),
- 'callback' => 'akismet_callback_queue',
- 'callback arguments' => array('comments', 'unpublished'),
- 'type' => MENU_LOCAL_TASK, 'weight' => 1);
- $items[] = array('path' => 'admin/content/akismet/comments/published', 'title' => t('Published comments'),
- 'callback' => 'akismet_callback_queue',
- 'callback arguments' => array('comments', 'published'),
- 'type' => MENU_LOCAL_TASK, 'weight' => 2);
- }
+ $moderator_types = akismet_get_moderator_types();
+ if (_akismet_is_moderator($moderator_types)) {
+ $items['admin/content/akismet'] = array(
+ 'title' => t('Akismet moderation queue'),
+ 'description' => t('Manage the Akismet spam queue, appropving or deleting content in need of moderation.'),
+ 'page callback' => 'akismet_callback_queue',
+ 'access callback' => array('_akismet_is_moderator'),
+ 'access arguments' => array($moderator_types),
+ 'file' => 'akismet.admin.inc',
+ );
+ $items['admin/content/akismet/overview'] = array(
+ 'title' => t('Overview'),
+ 'type' => MENU_DEFAULT_LOCAL_TASK,
+ 'weight' => 0,
+ 'file' => 'akismet.admin.inc',
+ );
+ if (_akismet_is_node_moderator($moderator_types)) {
+ $items['admin/content/akismet/nodes'] = array(
+ 'title' => t('Nodes'),
+ 'page callback' => 'akismet_callback_queue',
+ 'page arguments' => array('nodes'),
+ 'access callback' => array('_akismet_is_node_moderator'),
+ 'access arguments' => array($moderator_types),
+ 'type' => MENU_LOCAL_TASK,
+ 'weight' => 1,
+ 'file' => 'akismet.admin.inc',
+ );
+ $items['admin/content/akismet/nodes/spam'] = array(
+ 'title' => t('Spam'),
+ 'page arguments' => array('nodes'),
+ 'type' => MENU_DEFAULT_LOCAL_TASK,
+ 'weight' => 0,
+ 'file' => 'akismet.admin.inc',
+ );
+ $items['admin/content/akismet/nodes/unpublished'] = array(
+ 'title' => t('Unpublished nodes'),
+ 'page arguments' => array('nodes', 'unpublished'),
+ 'type' => MENU_LOCAL_TASK,
+ 'weight' => 1,
+ 'file' => 'akismet.admin.inc',
+ );
+ $items['admin/content/akismet/nodes/published'] = array(
+ 'title' => t('Published nodes'),
+ 'callback arguments' => array('nodes', 'published'),
+ 'type' => MENU_LOCAL_TASK,
+ 'weight' => 2,
+ 'file' => 'akismet.admin.inc',
+ );
+ }
+ if (_akismet_is_moderator($moderator_types, 'comments')) {
+ $items['admin/content/akismet/comments'] = array(
+ 'title' => t('Comments'),
+ 'page callback' => 'akismet_callback_queue',
+ 'page arguments' => array('comments'),
+ 'access callback' => array('_akismet_is_moderator'),
+ 'access arguments' => array($moderator_types, 'comments'),
+ 'type' => MENU_LOCAL_TASK,
+ 'weight' => 2,
+ 'file' => 'akismet.admin.inc',
+ );
+ $items['admin/content/akismet/comments/spam'] = array(
+ 'title' => t('Spam'),
+ 'page arguments' => array('comments'),
+ 'type' => MENU_DEFAULT_LOCAL_TASK,
+ 'weight' => 0,
+ 'file' => 'akismet.admin.inc',
+ );
+ $items['admin/content/akismet/comments/unpublished'] = array(
+ 'title' => t('Unpublished comments'),
+ 'page arguments' => array('comments', 'unpublished'),
+ 'type' => MENU_LOCAL_TASK,
+ 'weight' => 1,
+ 'file' => 'akismet.admin.inc',
+ );
+ $items['admin/content/akismet/comments/published'] = array(
+ 'title' => t('Published comments'),
+ 'page arguments' => array('comments', 'published'),
+ 'type' => MENU_LOCAL_TASK,
+ 'weight' => 2,
+ 'file' => 'akismet.admin.inc',
+ );
}
}
else {
- // Paths may look like 'akismet/content_type/content_id/operation'
- if (arg(0) == 'akismet' && is_numeric(arg(2))) {
- $content_type = arg(1);
- if ($content_type == 'node' || ($content_type == 'comment' && module_exists('comment'))) {
- $op = arg(3);
- if ($op == 'publish' || $op == 'unpublish') {
- $callback = 'akismet_callback_set_published_status';
- }
- else if ($op == 'submit-spam' || $op == 'submit-ham') {
- $callback = 'akismet_callback_set_spam_status';
- }
- if (isset($callback)) {
- $moderator_type = akismet_content_get_moderator_type($content_type, arg(2));
- if (!empty($moderator_type)) {
- $items[] = array('path' => 'akismet', 'title' => t('switch content status'),
- 'callback' => $callback,
- 'access' => akismet_is_spam_moderator($moderator_type),
- 'type' => MENU_CALLBACK);
- }
- }
- }
- }
- else {
- // Load the administration specific code?
- if (arg(0) == 'admin' && arg(1) == 'content' && arg(2) == 'akismet') {
- require_once('./'. drupal_get_path('module', 'akismet') . '/akismet_admin.inc');
- }
+ $item = array(
+ 'title' => 'switch content status',
+ 'page callback' => 'akismet_page',
+ 'page arguments' => array(0, 1, 2, 3),
+ 'load arguments' => array('%map', '%index'),
+ 'access callback' => array('akismet_access_callback'),
+ 'access argument' => array(0, 1, 2, 3),
+ );
+ foreach (array('publish', 'unpublish', 'submit-spam', 'submit-ham') as $op) {
+ $items['akismet/%akismet/%/'. $op] = $item;
}
}
return $items;
}
+function akismet_load($arg, &$map, $index) {
+ $content_type = $map[1];
+ if ($content_type == 'node') {
+ if (!$map[2] = node_load($map[2])) {
+ return FALSE;
+ }
+ }
+ if ($content_type == 'comment' && module_exists('comment')) {
+ if (!$map[2] = comment_load($map[2])) {
+ return FALSE;
+ }
+ }
+ $op == $map[3];
+ if ($op == 'publish' || $op == 'unpublish') {
+ $map[0] = 'akismet_callback_set_published_status';
+ }
+ else if ($op == 'submit-spam' || $op == 'submit-ham') {
+ $map[0] = 'akismet_callback_set_spam_status';
+ }
+ return $map[$index];
+}
+
+function akismet_access_callback($callback, $content_type, $object, $op) {
+ if ($content_type == 'node' && !node_access($map[2])) {
+ return FALSE;
+ }
+ if (function_exists($callback && !akismet_is_spam_moderator(akismet_content_get_moderator_type($content_type, $object)))) {
+ return FALSE;
+ }
+ // Is there a comment access check we need to run? If yes, then do the same as above.
+ return TRUE;
+}
+
+function akismet_page($callback, $content_type, $object, $op) {
+ if (function_exists($callback)) {
+ return $callback($content_type, $object, $op);
+ }
+ drupal_not_found();
+}
+
/**
* Implementation of hook_link().
*/
@@ -291,9 +380,9 @@ function akismet_link($type, $content =
* @param integer Content ID; can be either a nid or a cid.
* @param string Operation; it can be 'publish' or 'unpublish'.
*/
-function akismet_callback_set_published_status($content_type, $content_id, $op) {
+function akismet_callback_set_published_status($content_type, $object, $op) {
// Load the content (existence has been checked in hook_menu).
- $content = akismet_content_load($content_type, $content_id);
+ $content = akismet_content_load($content_type, $object);
if ($content_type == 'node') {
$is_published = ($content->status ? TRUE : FALSE);
@@ -326,11 +415,11 @@ function akismet_callback_set_published_
* @param integer Content ID; can be either a nid or a cid.
* @param string Operation; it can be 'submit-spam' or 'submit-ham'.
*/
-function akismet_callback_set_spam_status($content_type, $content_id, $op) {
- $is_spam = akismet_content_is_spam($content_type, $content_id);
+function akismet_callback_set_spam_status($content_type, $object, $op) {
+ $is_spam = akismet_content_is_spam($content_type, $object);
// Load the content (existence has been checked in hook_menu).
- $content = akismet_content_load($content_type, $content_id);
+ $content = akismet_content_load($content_type, $object);
if ($content_type == 'node') {
$is_published = ($content->status ? TRUE : FALSE);
@@ -420,10 +509,10 @@ function akismet_nodeapi(&$node, $op, $t
// Record the event to watchdog.
if ($akismet_api_result == AKISMET_API_RESULT_ERROR) {
- watchdog('content', t('Akismet service seems to be down, %content-type-name queued for manual approval: %title', array('%content-type-name' => $content_type_name, '%title' => $node->title)), WATCHDOG_WARNING, l(t('view'), 'node/'. $node->nid));
+ watchdog('content', 'Akismet service seems to be down, %content-type-name queued for manual approval: %title', array('%content-type-name' => $content_type_name, '%title' => $node->title), WATCHDOG_WARNING, l(t('view'), 'node/'. $node->nid));
}
else {
- watchdog('content', t('Spam detected by Akismet in %content-type-name: %title', array('%content-type-name' => $content_type_name, '%title' => $node->title)), WATCHDOG_WARNING, l(t('view'), 'node/'. $node->nid));
+ watchdog('content', 'Spam detected by Akismet in %content-type-name: %title', array('%content-type-name' => $content_type_name, '%title' => $node->title), WATCHDOG_WARNING, l(t('view'), 'node/'. $node->nid));
// If requested to, generate a delay so the spammer has to wait for a while.
if (($seconds = variable_get('akismet_antispambot_delay', 60)) > 0) {
sleep($seconds);
@@ -457,26 +546,25 @@ function akismet_comment(&$comment, $op)
/**
* Implementation of hook_form_alter().
*/
-function akismet_form_alter($form_id, &$form) {
+function akismet_form_alter(&$form, &$form_state, $form_id) {
// Hook into comment edit/reply form.
if ($form_id == 'comment_form' && variable_get('akismet_check_comments', 1)) {
// ...only if current user is not moderator.
if (!akismet_is_spam_moderator('comments')) {
// ...also check if Akismet connections are enabled.
if (variable_get('akismet_connection_enabled', 1)) {
- if (isset($form['cid']) && isset($form['cid']['#value']) && is_numeric($form['cid']['#value'])) {
- // This is the simple hook method, we already have the $cid.
- $form['#submit']['_akismet_comment_form_submit'] = array();
- }
- else {
+ // This is the simple hook method, *if* we already have the $cid.
+ $form['#submit'][] = '_akismet_comment_form_submit';
+ if (!isset($form['cid']) || !isset($form['cid']['#value']) || !is_numeric($form['cid']['#value'])) {
// This is a bit more complex, because the user is creating a new comment, so
// how can we get the $cid? See comments below, within our own submit callback.
- $form['#submit'] = array('_akismet_comment_form_submit' => array($form['#submit']));
+ $form['#comment_form_param1'] = $form['#submit'];
+// $form['#submit'] = array('_akismet_comment_form_submit' => array($form['#submit']));
}
}
// Inject anti-spambot code, if requested to.
if (akismet_is_anti_spambot_enabled()) {
- $form['#validate']['_akismet_comment_form_validate'] = array();
+ $form['#validate'][] = '_akismet_comment_form_validate';
}
}
}
@@ -490,7 +578,7 @@ function akismet_form_alter($form_id, &$
if (is_array($check_nodetypes) && isset($check_nodetypes[$node_type]) && $check_nodetypes[$node_type]) {
// Inject anti-spambot code, if requested to.
if (akismet_is_anti_spambot_enabled()) {
- $form['#validate']['_akismet_node_form_validate'] = array();
+ $form['#validate'][] = '_akismet_node_form_validate';
}
}
}
@@ -500,7 +588,7 @@ function akismet_form_alter($form_id, &$
/**
* Node form validate callback; check for spambots.
*/
-function _akismet_node_form_validate($form_id, $form_values) {
+function _akismet_node_form_validate($form, &$form_state) {
// Quit if there have already been errors in the form.
if (form_get_errors()) {
return;
@@ -513,11 +601,11 @@ function _akismet_node_form_validate($fo
$sql_args = array();
if ($antispambot_rules['ip']) {
$sql_where[] = 's.hostname = \'%s\'';
- $sql_args[] = $_SERVER['REMOTE_ADDR'];
+ $sql_args[] = ip_address();
}
- if ($antispambot_rules['body'] && !empty($form_values['body'])) {
+ if ($antispambot_rules['body'] && !empty($form_state['values']['body'])) {
$sql_where[] = 'r.body = \'%s\'';
- $sql_args[] = $form_values['body'];
+ $sql_args[] = $form_state['values']['body'];
}
if ($antispambot_rules['mail'] && !empty($user->mail)) {
$sql_where[] = 's.mail = \'%s\'';
@@ -536,7 +624,7 @@ function _akismet_node_form_validate($fo
akismet_anti_spambot_action(array(
t('SQL') => _akismet_translate_query($sql_stmt, $sql_args),
t('E-mail') => (isset($user->mail) ? $user->mail : ''),
- t('Body') => $form_values['body']
+ t('Body') => $form_state['values']['body']
));
}
}
@@ -545,7 +633,7 @@ function _akismet_node_form_validate($fo
/**
* Comment form validate callback; check for spambots.
*/
-function _akismet_comment_form_validate($form_id, $form_values) {
+function _akismet_comment_form_validate($form, &$form_state) {
// Quit if there have already been errors in the form.
if (form_get_errors()) {
return;
@@ -557,15 +645,15 @@ function _akismet_comment_form_validate(
$sql_args = array();
if ($antispambot_rules['ip']) {
$sql_where[] = 's.hostname = \'%s\'';
- $sql_args[] = $_SERVER['REMOTE_ADDR'];
+ $sql_args[] = ip_address();
}
- if ($antispambot_rules['body'] && !empty($form_values['comment'])) {
+ if ($antispambot_rules['body'] && !empty($form_state['values']['comment'])) {
$sql_where[] = 'c.comment = \'%s\'';
- $sql_args[] = $form_values['comment'];
+ $sql_args[] = $form_state['values']['comment'];
}
- if ($antispambot_rules['mail'] && !empty($form_values['mail'])) {
+ if ($antispambot_rules['mail'] && !empty($form_state['values']['mail'])) {
$sql_where[] = 's.mail = \'%s\'';
- $sql_args[] = $form_values['mail'];
+ $sql_args[] = $$form_state['values']['mail'];
}
if (count($sql_where) > 0) {
@@ -579,8 +667,8 @@ function _akismet_comment_form_validate(
if (db_result(db_query($sql_stmt, $sql_args, 0, 1))) {
akismet_anti_spambot_action(array(
t('SQL') => _akismet_translate_query($sql_stmt, $sql_args),
- t('E-mail') => $form_values['mail'],
- t('Comment') => $form_values['comment']
+ t('E-mail') => $form_state['values']['mail'],
+ t('Comment') => $form_state['values']['comment']
));
}
}
@@ -589,14 +677,14 @@ function _akismet_comment_form_validate(
/**
* Comment form submit callback; check for spam.
*/
-function _akismet_comment_form_submit($form_id, $form_values, $original_submit_callback = NULL) {
+function _akismet_comment_form_submit($form, &$form_state, $original_submit_callback = NULL) {
// Our default destination. It doesn't need to override the original.
$goto = NULL;
// If the comment is being edited, then there's no problem to get the $cid.
// In this case, the original #submit callback has already been called.
- if (isset($form_values['cid'])) {
- $cid = $form_values['cid'];
+ if (isset($form_state['values']['cid'])) {
+ $cid = $form_state['values']['cid'];
}
// However, if the comment is being created, we'll try to get the $cid from the
// return value of the original #submit callback. It's an array that customizes
@@ -654,10 +742,10 @@ function _akismet_comment_form_submit($f
// Record the event to watchdog.
if ($akismet_api_result == AKISMET_API_RESULT_ERROR) {
- watchdog('content', t('Akismet service seems to be down, comment queued for manual approval: %subject', array('%subject' => $comment->subject)), WATCHDOG_WARNING, l(t('view'), 'node/'. $comment->nid, NULL, NULL, 'comment-'. $comment->cid));
+ watchdog('content', 'Akismet service seems to be down, comment queued for manual approval: %subject', array('%subject' => $comment->subject), WATCHDOG_WARNING, l(t('view'), 'node/'. $comment->nid, NULL, NULL, 'comment-'. $comment->cid));
}
else {
- watchdog('content', t('Spam detected by Akismet in comment: %subject', array('%subject' => $comment->subject)), WATCHDOG_WARNING, l(t('view'), 'node/'. $comment->nid, NULL, NULL, 'comment-'. $comment->cid));
+ watchdog('content', 'Spam detected by Akismet in comment: %subject', array('%subject' => $comment->subject), WATCHDOG_WARNING, l(t('view'), 'node/'. $comment->nid, NULL, NULL, 'comment-'. $comment->cid));
// If requested to, generate a delay so the spammer has to wait for a while.
if (($seconds = variable_get('akismet_antispambot_delay', 60)) > 0) {
sleep($seconds);
@@ -741,7 +829,7 @@ function akismet_anti_spambot_action($de
$message = t('Spambot detected (action: 503 Service unavailable).');
}
- watchdog('akismet', $message .''. t('Additional information:') .'
'. theme('item_list', $items));
+ watchdog('akismet', '%messageAdditional information:
%items', array('%message' => $message, '%items' => theme('item_list', $items)));
module_invoke_all('exit');
exit;
@@ -927,7 +1015,7 @@ function akismet_notify_moderators($cont
$site_name = variable_get('site_name', t('Drupal'));
if ($content_type == 'comment') {
if (!($node = akismet_content_load('node', $content->nid))) {
- watchdog('akismet', t('An error has ocurred while trying to notify moderators about a comment. The associated node could not be loaded.'), WATCHDOG_NOTICE, l(t('view'), 'node/'. $content->nid, NULL, NULL, 'comment-'. $content->cid));
+ watchdog('akismet', 'An error has ocurred while trying to notify moderators about a comment. The associated node could not be loaded.', array(), WATCHDOG_NOTICE, l(t('view'), 'node/'. $content->nid, NULL, NULL, 'comment-'. $content->cid));
return;
}
$message_args = array(
@@ -970,7 +1058,7 @@ EOT
, $message_args);
// Log the notification to watchdog.
- watchdog('akismet', t('Trying to notify the following recipients: %emails', array('%emails' => implode(', ', array_keys($unique_emails)))));
+ watchdog('akismet', 'Trying to notify the following recipients: %emails', array('%emails' => implode(', ', array_keys($unique_emails))));
// Send e-mails.
foreach ($unique_emails as $email_to => $uid) {
@@ -1200,6 +1288,29 @@ function akismet_block($op = 'list', $de
}
/**
+ * Implementation of hook_theme().
+ */
+function akismet_theme() {
+ return array(
+ 'akismet_counter_block' => array(
+ 'arguments' => array(
+ 'args' => array(
+ 'content',
+ 'counter',
+ 'since',
+ 'text' => array(
+ 'plain' => array('short', 'long'),
+ 'html' => array('short', 'long'),
+ ),
+ 'image',
+ 'block',
+ ),
+ ),
+ ),
+ );
+}
+
+/**
* Allow themes customize the content of the akismet spam counter block.
*
* @param array arguments where each element is:
@@ -1277,7 +1388,7 @@ function akismet_content_delete($content
}
// Record the event to watchdog.
- watchdog('content', t('%type: deleted @title.', array('%type' => t($node->type), '@title' => $node->title)));
+ watchdog('content', '%type: deleted @title.', array('%type' => t($node->type), '@title' => $node->title));
return TRUE;
}
}
@@ -1330,7 +1441,7 @@ function akismet_content_spam_operation(
}
if ($op == 'submit-spam') {
- $hostname = (!empty($content->hostname) ? $content->hostname : $_SERVER['REMOTE_ADDR']);
+ $hostname = (!empty($content->hostname) ? $content->hostname : ip_address());
db_query('INSERT INTO {akismet_spam_marks} (content_type, content_id, spam_created, hostname, mail) VALUES (\'%s\', %d, %d, \'%s\', \'%s\')', $content_type, $content_id, time(), $hostname, $user_mail);
if (variable_get('akismet_connection_enabled', 1)) {
@@ -1354,7 +1465,7 @@ function akismet_content_spam_operation(
}
if ($log_action) {
- watchdog('content', t('@action: @title', array('@action' => $action, '@title' => $content_title)), WATCHDOG_NOTICE, $content_link);
+ watchdog('content', '@action: @title', array('@action' => $action, '@title' => $content_title), WATCHDOG_NOTICE, $content_link);
}
akismet_clear_cache();
}
@@ -1377,7 +1488,7 @@ function akismet_content_publish_operati
if ($log_action) {
$action = ($op == 'publish' ? t('Content published') : t('Content unpublished'));
- watchdog('content', t('@action: @title', array('@action' => $action, '@title' => $content->title)), WATCHDOG_NOTICE, l(t('view'), 'node/'. $content->nid));
+ watchdog('content', '@action: @title', array('@action' => $action, '@title' => $content->title), WATCHDOG_NOTICE, l(t('view'), 'node/'. $content->nid));
}
}
else { // comment
@@ -1401,7 +1512,7 @@ function akismet_content_publish_operati
if ($log_action) {
$action = ($op == 'publish' ? t('Comment published') : t('Comment unpublished'));
- watchdog('content', t('@action: %subject', array('@action' => $action, '%subject' => $content->subject)), WATCHDOG_NOTICE, l(t('view'), 'node/'. $content->nid, NULL, NULL, 'comment-'. $content->cid));
+ watchdog('content', '@action: %subject', array('@action' => $action, '%subject' => $content->subject), WATCHDOG_NOTICE, l(t('view'), 'node/'. $content->nid, NULL, NULL, 'comment-'. $content->cid));
}
}
@@ -1419,7 +1530,7 @@ function akismet_prepare_comment_data($c
// Prepare data that is common to nodes/comments.
$comment_data = array(
// IP address of the comment submitter.
- 'user_ip' => (!empty($content->hostname) ? $content->hostname : $_SERVER['REMOTE_ADDR']),
+ 'user_ip' => (!empty($content->hostname) ? $content->hostname : ip_address()),
// User agent information of the comment submitter.
'user_agent' => $_SERVER['HTTP_USER_AGENT'],
// The content of the HTTP_REFERER header should be sent here.
Index: akismet_admin.inc
===================================================================
RCS file: akismet_admin.inc
diff -N akismet_admin.inc
--- akismet_admin.inc 1 Jun 2007 22:40:59 -0000 1.8
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,714 +0,0 @@
- t('Enabled'), '0' => t('Disabled'));
-
- $akismet_wpapikey = variable_get('akismet_wpapikey', '');
- if (empty($akismet_wpapikey)) {
- $service_fieldset_collapsed = FALSE;
- }
- else {
- $service_fieldset_collapsed = $is_valid = (akismet_api_cmd_verify_key($akismet_wpapikey) == AKISMET_API_RESULT_SUCCESS ? TRUE : FALSE);
- }
- if ($service_fieldset_collapsed) {
- $service_fieldset_collapsed = variable_get('akismet_connection_enabled', 1);
- }
-
- $form['service'] = array(
- '#type' => 'fieldset', '#title' => t('Akismet Service Options'),
- '#collapsible' => TRUE, '#collapsed' => $service_fieldset_collapsed
- );
- $form['service']['akismet_wpapikey'] = array(
- '#type' => 'textfield', '#title' => t('WordPress.com API key'),
- '#size' => 30, '#maxlength' => 60,
- '#default_value' => $akismet_wpapikey,
- '#description' => t('Please, enter here your WordPress.com API key . If you don\'t have one already, you can get it by simply signing up for a free account at WordPress.com . Note that this information is required in order to use the Akismet Service . Please, consult the Akismet FAQ for further information.',
- array(
- '!wpapikey' => url('http://wordpress.com/api-keys/'),
- '!wordpress-com' => url('http://wordpress.com'),
- '!akismet' => url('http://akismet.com'),
- '!akismet-faq' => url('http://akismet.com/faq/'),
- ))
- );
- if (!empty($akismet_wpapikey) && !$is_valid) {
- $form['service']['akismet_wpapikey']['#description'] .= ''. t('WARNING: Your API Key doesn\'t seem to be valid! ') .'
';
- }
- $form['service']['akismet_connection_enabled'] = array(
- '#type' => 'radios', '#title' => t('Akismet connections'),
- '#options' => $enable_options,
- '#default_value' => variable_get('akismet_connection_enabled', 1),
- '#description' => t('This option must be enabled in order to perform real requests to the Akismet Service . You may want to disable this option for testing purposes, however. In this case, the akismet module will operate as normal, except sending real requests to the Akismet Service . ie. no automatic spam detection will be performed and no remote requests will be made when content is manually marked /unmarked as spam. Note: regardless of this option, the akismet module will still connect, from this panel, to validate your WordPress.com API key , if specified.',
- array(
- '!akismet' => url('http://akismet.com'),
- '!wpapikey' => url('http://wordpress.com/api-keys/'),
- ))
- );
- $timeout_options = array();
- for ($n = 1; $n <= 30; $n++) {
- $timeout_options[$n] = $n;
- }
- $form['service']['akismet_connection_timeout'] = array(
- '#type' => 'select', '#title' => t('Connection timeout'),
- '#default_value' => variable_get('akismet_connection_timeout', 10),
- '#options' => $timeout_options,
- '#description' => t('This option allows you to specify the connection timeout in seconds that is used for real time Akismet connections.')
- );
-
- $form['general'] = array(
- '#type' => 'fieldset', '#title' => t('General Options'),
- '#collapsible' => TRUE, '#collapsed' => TRUE
- );
- $age_options = drupal_map_assoc(array(0, 3600, 10800, 21600, 32400, 43200, 86400, 172800, 259200, 604800, 1209600, 1814400), 'format_interval');
- $age_options[0] = t('never');
- $age_options[2592000] = t('1 month');
- $age_options[5184000] = t('2 months');
- $age_options[7776000] = t('3 months');
- $age_options[10368000] = t('4 months');
- $age_options[15768000] = t('6 months');
- $age_options[31536000] = t('1 year');
- $form['general']['akismet_remove_spam_age'] = array(
- '#type' => 'select', '#title' => t('Remove spam older than'),
- '#default_value' => variable_get('akismet_remove_spam_age', 259200),
- '#options' => $age_options,
- '#description' => t('Content marked as spam is still saved into database so it can be reviewed by content administrators. This option allows you to specify how long this information will be kept in the database. Spam older than the age specified here will be automatically removed. Requires crontab.')
- );
- $form['general']['akismet_records_per_page'] = array(
- '#type' => 'select', '#title' => t('Records per page'),
- '#default_value' => variable_get('akismet_records_per_page', 50),
- '#options' => drupal_map_assoc(array(10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 200)),
- '#description' => t('The maximum number of records per page on moderation queue.')
- );
- $form['general']['akismet_blocks_counter'] = array(
- '#type' => 'select', '#title' => t('Number of blocks'),
- '#default_value' => variable_get('akismet_blocks_counter', 1),
- '#options' => array(0=>t('none'), 1=>1, 2=>2, 3=>3, 4=>4, 5=>5),
- '#description' => t('The akismet module may generate a number of blocks for you to display the current spam counter anywhere on your site. The number of blocks is variable to help you keep your blocks administration panel as clean as possible. This option allows you to specify how many blocks you wish to use. If you do not plan to show the spam counter to your visitors, set this option to none .',
- array(
- '!admin-block' => url('admin/block'),
- ))
- );
- $form['general']['akismet_email_enabled'] = array(
- '#type' => 'radios', '#title' => t('E-mail notifications'),
- '#options' => $enable_options,
- '#default_value' => variable_get('akismet_email_enabled', 1),
- '#description' => t('Use this option to enable or disable e-mail notifications to content moderators. If enabled, users with proper permissions are allowed to set, from their user profiles, whether they wish to receive e-mail notications for all new (or updated) posts, just for content needing approval or no notifications at all. Users are notified about content types they are allowed to moderate only.')
- );
-
- $form['node_options'] = array(
- '#type' => 'fieldset', '#title' => t('Node Options'),
- '#collapsible' => TRUE, '#collapsed' => TRUE
- );
- $form['node_options']['akismet_check_nodetypes'] = array(
- '#type' => 'checkboxes', '#title' => t('Check for spam in these node types'),
- '#options' => node_get_types('names'),
- '#default_value' => variable_get('akismet_check_nodetypes', NULL),
- '#description' => t('Use this option to enable or disable spam check for nodes of types specified here. When this option is enabled, a request will be sent to the Akismet Service , in real time. If the Akismet Service was down, nodes would simply be queued for manual moderation. Users with @admin-nodes permission and spam moderators are exempt from this check.',
- array(
- '!akismet' => url('http://akismet.com'),
- '@admin-nodes' => t('administer nodes'),
- '!admin-access' => url('admin/access'),
- ))
- );
- $form['node_options']['akismet_node_publish_links'] = array(
- '#type' => 'radios', '#title' => t('Show publish/unpublish links'),
- '#options' => $enable_options,
- '#default_value' => variable_get('akismet_node_publish_links', 0),
- '#description' => t('Use this option to enable or disable links for publish /unpublish operations in nodes. If enabled, these links will only be displayed to spam moderators and users with @admin-nodes permission.',
- array(
- '@admin-nodes' => t('administer nodes'),
- '!admin-access' => url('admin/access'),
- ))
- );
- $form['node_options']['akismet_node_spam_links'] = array(
- '#type' => 'radios', '#title' => t('Show submit spam/ham links'),
- '#options' => $enable_options,
- '#default_value' => variable_get('akismet_node_spam_links', 0),
- '#description' => t('Use this option to enable or disable links for submit spam /ham operations in nodes. If enabled, these links will only be displayed to spam moderators and users with @admin-nodes permission.',
- array(
- '@admin-nodes' => t('administer nodes'),
- '!admin-access' => url('admin/access'),
- ))
- .' '. t('Note: To interact fully with the Akismet Service you really should try putting data back into the system as well as just taking it out. If it is at all possible, please use these links to submit missed spam and false positives (ham), otherwise Akismet will never learn from its mistakes. Thank you.',
- array(
- '!akismet' => url('http://akismet.com'),
- ))
- );
-
- if (module_exists('comment')) {
- $form['comment_options'] = array(
- '#type' => 'fieldset', '#title' => t('Comment Options'),
- '#collapsible' => TRUE, '#collapsed' => TRUE
- );
- $form['comment_options']['akismet_check_comments'] = array(
- '#type' => 'radios', '#title' => t('Check for spam in comments'),
- '#options' => $enable_options,
- '#default_value' => variable_get('akismet_check_comments', 1),
- '#description' => t('Use this option to enable or disable spam check for comments. When this option is enabled, a request will be sent to the Akismet Service , in real time. If the Akismet Service was down, comments would simply be queued for manual moderation. Users with @admin-comments permission and spam moderators are exempt from this check.',
- array(
- '!akismet' => url('http://akismet.com'),
- '@admin-comments' => t('administer comments'),
- '!admin-access' => url('admin/access'),
- ))
- );
- $form['comment_options']['akismet_comment_publish_links'] = array(
- '#type' => 'radios', '#title' => t('Show publish/unpublish links'),
- '#options' => $enable_options,
- '#default_value' => variable_get('akismet_comment_publish_links', 1),
- '#description' => t('Use this option to enable or disable links for publish /unpublish operations in comments. If enabled, these links will only be displayed to spam moderators and users with @admin-comments permission.',
- array(
- '@admin-comments' => t('administer comments'),
- '!admin-access' => url('admin/access'),
- ))
- );
- $form['comment_options']['akismet_comment_spam_links'] = array(
- '#type' => 'radios', '#title' => t('Show submit spam/ham links'),
- '#options' => $enable_options,
- '#default_value' => variable_get('akismet_comment_spam_links', 1),
- '#description' => t('Use this option to enable or disable links for submit spam /ham operations in comments. If enabled, these links will only be displayed to spam moderators and users with @admin-comments permission.',
- array(
- '@admin-comments' => t('administer comments'),
- '!admin-access' => url('admin/access'),
- ))
- .' '. t('Note: To interact fully with the Akismet Service you really should try putting data back into the system as well as just taking it out. If it is at all possible, please use these links to submit missed spam and false positives (ham), otherwise Akismet will never learn from its mistakes. Thank you.',
- array(
- '!akismet' => url('http://akismet.com'),
- ))
- );
- }
-
- $date_formats = array(
- 'F j, Y', 'j F, Y', 'Y, F j',
- 'M j, Y', 'j M, Y', 'Y, M j',
- 'Y/m/d', 'm/d/Y', 'd/m/Y',
- 'Y-m-d', 'm-d-Y', 'd-m-Y'
- );
- $date_options = array();
- $now = time();
- foreach ($date_formats as $format) {
- $date_options[$format] = format_date($now, 'custom', $format);
- }
-
- $form['counter_options'] = array(
- '#type' => 'fieldset', '#title' => t('Spam Counter Options'),
- '#collapsible' => TRUE, '#collapsed' => TRUE
- );
- $form['counter_options']['akismet_counter_spam'] = array(
- '#type' => 'textfield', '#title' => t('Spam counter'),
- '#default_value' => akismet_get_spam_counter(),
- '#size' => 10, '#maxlength' => 10,
- '#description' => t('This counter is incremented for every spam caught by Akismet.')
- );
- $form['counter_options']['akismet_counter_since'] = array(
- '#type' => 'date', '#title' => t('Counting since'),
- '#default_value' => variable_get('akismet_counter_since', array('day' => date('j'), 'month' => date('n'), 'year' => date('Y'))),
- '#description' => t('This is the date that will tell your visitors when your Akismet spam counter started to increment.')
- );
- $form['counter_options']['akismet_counter_date_format'] = array(
- '#type' => 'select', '#title' => t('Date format'),
- '#default_value' => variable_get('akismet_counter_date_format', $date_formats[0]),
- '#options' => $date_options,
- '#description' => t('Date format used to render the Counting since date.')
- );
-
- $form['anti_spambot'] = array(
- '#type' => 'fieldset', '#title' => t('Anti-Spambot Options'),
- '#collapsible' => TRUE, '#collapsed' => TRUE,
- '#description' => t('The goal of this section is not to replace anything that the Akismet Service itself can do a lot better than us, but to provide a set of simple rules aimed to prevent Denial of Service (DoS) situations that could be caused by certain spambots.',
- array(
- '!akismet' => url('http://akismet.com'),
- ))
- );
- $delay_options = drupal_map_assoc(array(0, 30, 60, 90, 120, 150, 180), 'format_interval');
- $delay_options[0] = t('none');
- $form['anti_spambot']['akismet_antispambot_delay'] = array(
- '#type' => 'select', '#title' => t('Delay when spam is detected'),
- '#default_value' => variable_get('akismet_antispambot_delay', 60),
- '#options' => $delay_options,
- '#description' => t('Use this option to delay the response when content has been identified as spam or to requests that match the rules defined below.')
- );
- $anti_spambot_rules = array(
- 'ip' => t('IP addresses used by known spammers.'),
- 'mail' => t('E-mail addresses used by known spammers.'),
- 'body' => t('Content that has already been identified as spam.'),
- );
- $form['anti_spambot']['akismet_antispambot_rules'] = array(
- '#type' => 'checkboxes', '#title' => t('Identify spambots by'),
- '#options' => $anti_spambot_rules,
- '#default_value' => variable_get('akismet_antispambot_rules', NULL),
- '#description' => t('These rules will be applied before sending any request to the Akismet Service . If a request to send content matches any of these rules, the actions defined below will be triggered. Requests to send content are checked against spam that is stored locally (visible from the moderation queue ).',
- array(
- '!akismet' => url('http://akismet.com'),
- '!moderation-queue' => url('admin/content/akismet'),
- ))
- );
- $anti_spambot_actions = array(
- 'none' => t('None (only the delay specified above, if any).'),
- '503' => t('HTTP error 503 (Service Unavailable), showing a simple blank page.'),
- '403' => t('HTTP error 403 (Forbidden), showing a simple blank page.'),
- '403d' => t('HTTP error 403 (Forbidden), showing a Drupal generated page.')
- );
- $form['anti_spambot']['akismet_antispambot_action'] = array(
- '#type' => 'radios', '#title' => t('Actions against spambots'),
- '#options' => $anti_spambot_actions,
- '#default_value' => variable_get('akismet_antispambot_action', '503'),
- '#description' => t('Use this option to specify what to do against spambots identified by any of the above rules. When a HTTP error is generated (403 or 503), no request to the Akismet Service will be made, the request to post content will not be stored into database and no further moderator notifications will be sent. In any case, when a rule matches, a record of the event will be logged for further analysis.',
- array(
- '!akismet' => url('http://akismet.com'),
- '!admin-logs' => url('admin/logs'),
- ))
- );
-
- return system_settings_form($form);
-}
-
-/**
- * Moderation queue operations.
- */
-function akismet_moderator_operations($mode, $submode) {
- // Build operations array; based on current mode.
- if ($mode == 'nodes') {
- $operations = array(
- 'submit-spam' => array(
- 'title' => (variable_get('akismet_connection_enabled', 1) ? t('Submit selected nodes as spam') : t('Mark selected nodes as spam')),
- 'confirm' => (variable_get('akismet_connection_enabled', 1) ? t('Are you sure you want to submit these nodes as spam?') : t('Are you sure you want to mark these nodes as spam?')),
- 'button' => (variable_get('akismet_connection_enabled', 1) ? t('Submit nodes as spam') : t('Mark nodes as spam')),
- ),
- 'submit-ham' => array(
- 'title' => (variable_get('akismet_connection_enabled', 1) ? t('Submit selected nodes as ham') : t('Mark selected nodes as ham')),
- 'confirm' => (variable_get('akismet_connection_enabled', 1) ? t('Are you sure you want to submit these nodes as ham?') : t('Are you sure you want to mark these nodes as ham?')),
- 'button' => (variable_get('akismet_connection_enabled', 1) ? t('Submit nodes as ham') : t('Mark nodes as ham')),
- ),
- 'publish' => array(
- 'title' => t('Publish selected nodes'),
- 'confirm' => t('Are you sure you want to publish these nodes?'),
- 'button' => t('Publish nodes'),
- ),
- 'unpublish' => array(
- 'title' => t('Unpublish selected nodes'),
- 'confirm' => t('Are you sure you want to unpublish these nodes?'),
- 'button' => t('Unpublish nodes'),
- ),
- 'delete' => array(
- 'title' => t('Delete selected nodes'),
- 'confirm' => t('Are you sure you want to delete these nodes and all their comments?'),
- 'button' => t('Delete nodes'),
- 'warning' => t('This action cannot be undone.')
- )
- );
- }
- else if ($mode == 'comments') {
- $operations = array(
- 'submit-spam' => array(
- 'title' => (variable_get('akismet_connection_enabled', 1) ? t('Submit selected comments as spam') : t('Mark selected comments as spam')),
- 'confirm' => (variable_get('akismet_connection_enabled', 1) ? t('Are you sure you want to submit these comments as spam?') : t('Are you sure you want to mark these comments as spam?')),
- 'button' => (variable_get('akismet_connection_enabled', 1) ? t('Submit comments as spam') : t('Mark comments as spam')),
- ),
- 'submit-ham' => array(
- 'title' => (variable_get('akismet_connection_enabled', 1) ? t('Submit selected comments as ham') : t('Mark selected comments as ham')),
- 'confirm' => (variable_get('akismet_connection_enabled', 1) ? t('Are you sure you want to submit these comments as ham?') : t('Are you sure you want to mark these comments as ham?')),
- 'button' => (variable_get('akismet_connection_enabled', 1) ? t('Submit comments as ham') : t('Mark comments as ham')),
- ),
- 'publish' => array(
- 'title' => t('Publish selected comments'),
- 'confirm' => t('Are you sure you want to publish these comments?'),
- 'button' => t('Publish comments'),
- ),
- 'unpublish' => array(
- 'title' => t('Unpublish selected comments'),
- 'confirm' => t('Are you sure you want to unpublish these comments?'),
- 'button' => t('Unpublish comments'),
- ),
- 'delete' => array(
- 'title' => t('Delete selected comments'),
- 'confirm' => t('Are you sure you want to delete these comments and all their replies?'),
- 'button' => t('Delete comments'),
- 'warning' => t('This action cannot be undone.')
- )
- );
- }
- else { // Unknown mode!
- return array();
- }
-
- // Unset redundant operations; based on current submode.
- if ($submode == 'spam') {
- unset($operations['submit-spam']);
- }
- else if ($submode == 'unpublished') {
- unset($operations['unpublish']);
- }
- else if ($submode == 'published') {
- unset($operations['publish']);
- }
- else { // Unknown submode!
- return array();
- }
-
- return $operations;
-}
-
-/**
- * Menu callback; Moderation queue.
- *
- * @param string Mode: overview (default), nodes, comments.
- * @param string Submode: spam (default), unpublished, published.
- */
-function akismet_callback_queue($mode = '', $submode = '') {
- // Make sure we're dealing with a valid mode and submode.
- $valid_modes = array('nodes', 'comments');
- $valid_submodes = array(
- 'spam' => t('Spam'),
- 'unpublished' => t('Unpublished'),
- 'published' => t('Published')
- );
- if (empty($mode)) {
- $mode = 'overview';
- }
- else if (!in_array($mode, $valid_modes)) {
- drupal_not_found();
- return;
- }
- if (empty($submode)) {
- $submode = 'spam';
- }
- else if (!isset($valid_submodes[$submode])) {
- drupal_not_found();
- return;
- }
- // Compute exactly what the current user is allowed to moderate.
- $moderator_types = akismet_get_moderator_types();
- $moderator_types_count = count($moderator_types);
- $allowed_comments = (isset($moderator_types['comments']) ? TRUE : FALSE);
- $allowed_nodes = $moderator_types;
- if ($allowed_comments) {
- unset($allowed_nodes['comments']);
- }
- $allowed_nodes_count = count($allowed_nodes);
-
- // Make sure the user has some kind of content administration/moderation permission.
- if ($allowed_nodes_count <= 0 && !$allowed_comments) {
- drupal_access_denied();
- return;
- }
-
- // Dynamically build the queries using a write once method.
- if ($allowed_nodes_count > 0) {
- $sql_nodetypes = array();
- foreach ($allowed_nodes as $type => $name) {
- $sql_nodetypes[] = '\''. $type .'\'';
- }
- $sql_nodetypes = implode(', ', $sql_nodetypes);
- $sql_from = 'FROM {node} n LEFT JOIN {akismet_spam_marks} s ON s.content_id = n.nid AND s.content_type = \'node\'';
- $sql_where = 'WHERE n.type IN ('. $sql_nodetypes .') AND (%cond)';
- $sql_nodes_cond = array(
- 'spam' => 's.content_id IS NOT NULL',
- 'unpublished' => 'n.status = 0',
- 'published' => 'n.status = 1'
- );
-
- $sql_nodes_stmt = 'SELECT n.*, u.name, IFNULL(s.content_id, 0) AS spam_mark '. $sql_from .' INNER JOIN {users} u ON n.uid = u.uid '. $sql_where;
- $sql_nodes_cnt = 'SELECT COUNT(*) AS cnt '. $sql_from .' '. $sql_where;
- }
- if (module_exists('comment') && $allowed_comments) {
- $sql_from = 'FROM {comments} c LEFT JOIN {akismet_spam_marks} s ON s.content_id = c.cid AND s.content_type = \'comment\'';
- $sql_where = 'WHERE (%cond)';
- $sql_comments_cond = array(
- 'spam' => 's.content_id IS NOT NULL',
- 'unpublished' => 'c.status = '. COMMENT_NOT_PUBLISHED,
- 'published' => 'c.status = '. COMMENT_PUBLISHED
- );
- $sql_comments_stmt = 'SELECT c.*, u.name AS registered_name, IFNULL(s.content_id, 0) AS spam_mark '. $sql_from .' INNER JOIN {users} u ON c.uid = u.uid '. $sql_where;
- $sql_comments_cnt = 'SELECT COUNT(*) AS cnt '. $sql_from .' '. $sql_where;
- }
-
- $sql = array(
- 'sql_comments_cnt' => $sql_comments_cnt,
- 'sql_comments_stmt' => $sql_comments_stmt,
- 'sql_comments_cond' => $sql_comments_cond,
- 'sql_nodes_cnt' => $sql_nodes_cnt,
- 'sql_nodes_stmt' => $sql_nodes_stmt,
- 'sql_nodes_cond' => $sql_nodes_cond,
- );
-
- // Present the overview page (default).
- if ($mode == 'overview') {
- $items = array();
- if ($allowed_nodes_count > 0) {
- $subitems = array();
- foreach ($valid_submodes as $key => $title) {
- $sql_cnt = str_replace('%cond', $sql_nodes_cond[$key], $sql_nodes_cnt);
- $count = db_result(db_query(db_rewrite_sql($sql_cnt)));
- $path = 'admin/content/akismet/nodes'. ($key == 'spam' ? '' : '/'. $key);
- $label = ($count > 0 ? l($title, $path) : $title);
- $subitems[] = ''. $label .': '. $count .'
';
- }
- $items[] = ''. t('Nodes') .' '. theme('item_list', $subitems);
- }
- if (module_exists('comment') && $allowed_comments) {
- $subitems = array();
- foreach ($valid_submodes as $key => $title) {
- $sql_cnt = str_replace('%cond', $sql_comments_cond[$key], $sql_comments_cnt);
- $count = db_result(db_query(db_rewrite_sql($sql_cnt, 'c', 'cid')));
- $path = 'admin/content/akismet/comments'. ($key == 'spam' ? '' : '/'. $key);
- $label = ($count > 0 ? l($title, $path) : $title);
- $subitems[] = ''. $label .': '. $count .'
';
- }
- $items[] = ''. t('Comments') .' '. theme('item_list', $subitems);
- }
- return ''. t('Summary of content:') .' '. theme('item_list', $items);
- }
- if (isset($_POST) && count($_POST['items']) > 0) {
- return drupal_get_form('akismet_confirm_multiple_operation');
- }
- else {
- return drupal_get_form('akismet_moderation_form', $mode, $submode, $sql);
- }
-}
-
-function akismet_moderation_form($mode = '', $submode = '', $sql = array()) {
- // Build the moderation queue form.
- $form = array();
- $form['options'] = array(
- '#type' => 'fieldset', '#title' => t('Moderator actions'),
- '#prefix' => '', '#suffix' => '
'
- );
-
- extract($sql);
-
- $options = array('' => t(''));
- foreach (akismet_moderator_operations($mode, $submode) as $key => $operation_info) {
- $options[$key] = $operation_info['title'];
- }
- $form['options']['operation'] = array('#type' => 'select', '#options' => $options, '#default_value' => '');
- $form['options']['submit'] = array('#type' => 'submit', '#value' => t('Submit'));
-
- if ($mode == 'nodes') {
- $sql_stmt = str_replace('%cond', $sql_nodes_cond[$submode], $sql_nodes_stmt);
- $sql_cnt = str_replace('%cond', $sql_nodes_cond[$submode], $sql_nodes_cnt);
- $form['header'] = array('#type' => 'value', '#value' => array(
- theme('table_select_header_cell'),
- array('data' => t('Title'), 'field' => 'title'),
- array('data' => t('Type'), 'field' => 'type'),
- array('data' => t('Author'), 'field' => 'name'),
- array('data' => t('Status'), 'field' => 'status'),
- array('data' => t('Last changed'), 'field' => 'changed', 'sort' => 'desc')
- ));
- }
- else { // comments
- $sql_stmt = str_replace('%cond', $sql_comments_cond[$submode], $sql_comments_stmt);
- $sql_cnt = str_replace('%cond', $sql_comments_cond[$submode], $sql_comments_cnt);
- $form['header'] = array('#type' => 'value', '#value' => array(
- theme('table_select_header_cell'),
- array('data' => t('Subject'), 'field' => 'subject'),
- array('data' => t('Author'), 'field' => 'name'),
- array('data' => t('Status'), 'field' => 'status'),
- array('data' => t('Last changed'), 'field' => 'timestamp', 'sort' => 'desc')
- ));
- }
-
- $records_per_page = variable_get('akismet_records_per_page', 50);
- $result = pager_query($sql_stmt . tablesort_sql($form['header']['#value']), $records_per_page, 0, $sql_cnt);
- $items = array();
- $now = time();
- while ($content = db_fetch_object($result)) {
- if ($mode == 'nodes') {
- $items[$content->nid] = '';
- $form['title'][$content->nid] = array('#value' => l($content->title, 'node/'. $content->nid, array('title' => truncate_utf8($content->body, 128))) .' '. theme('mark', node_mark($content->nid, $content->changed)));
- $form['type'][$content->nid] = array('#value' => node_get_types('name', $content));
- $form['author'][$content->nid] = array('#value' => theme('username', $content));
- $form['status'][$content->nid] = array('#value' => ($content->status ? t('published') : t('not published')));
- if ($content->spam_mark) {
- $form['status'][$content->nid]['#value'] .= t('/spam');
- }
- $form['created'][$content->nid] = array('#value' => t('%time ago', array('%time' => format_interval($now - $content->changed))));
- }
- else { // comments
- $items[$content->cid] = '';
- $content->name = $content->uid ? $content->registered_name : $content->name;
- $form['title'][$content->cid] = array('#value' => l($content->subject, 'node/'. $content->nid, array('title' => truncate_utf8($content->comment, 128)), NULL, 'comment-'. $content->cid) .' '. theme('mark', node_mark($content->nid, $content->timestamp)));
- $form['author'][$content->cid] = array('#value' => theme('username', $content));
- $form['status'][$content->cid] = array('#value' => ($content->status == COMMENT_PUBLISHED ? t('published') : t('not published')));
- if ($content->spam_mark) {
- $form['status'][$content->cid]['#value'] .= t('/spam');
- }
- $form['created'][$content->cid] = array('#value' => t('%time ago', array('%time' => format_interval($now - $content->timestamp))));
- }
- }
-
- $form['mode'] = array('#type' => 'hidden', '#value' => $mode);
- $form['submode'] = array('#type' => 'hidden', '#value' => $submode);
- $form['items'] = array('#type' => 'checkboxes', '#options' => $items);
- $form['pager'] = array('#value' => theme('pager', NULL, $records_per_page, 0));
- return $form;
-}
-
-/**
- * Theme callback; render the moderation queue form.
- */
-function theme_akismet_moderation_form($form) {
- $mode = $form['mode']['#value'];
- $submode = $form['submode']['#value'];
- $output = drupal_render($form['options']);
- $rows = array();
- if (isset($form['author']) && is_array($form['author'])) {
- foreach (element_children($form['author']) as $key) {
- $row = array();
- $row[] = array('data' => drupal_render($form['items'][$key]));
- $row[] = drupal_render($form['title'][$key]);
- if ($mode == 'nodes') {
- $row[] = drupal_render($form['type'][$key]);
- }
- $row[] = drupal_render($form['author'][$key]);
- $row[] = drupal_render($form['status'][$key]);
- $row[] = drupal_render($form['created'][$key]);
- $rows[] = $row;
- }
- }
- else {
- if ($submode == 'spam') {
- $message = ($mode == 'nodes' ? t('There is no spam in the nodes moderation queue.') : t('There is no spam in the comments moderation queue.')) .' '. t('It must be your lucky day! ;-)');
- }
- else if ($submode == 'unpublished') {
- $message = ($mode == 'nodes' ? t('There are no unpublished nodes in the moderation queue.') : t('There are no unpublished comments in the moderation queue.'));
- }
- else { // published
- $message = ($mode == 'nodes' ? t('There are no published nodes.') : t('There are no published comments.'));
- }
- $rows[] = array(array('data' => $message, 'align' => 'center', 'colspan' => ($mode == 'nodes' ? '6' : '5')));
- }
- $output .= theme('table', $form['header']['#value'], $rows);
- if ($form['pager']['#value']) {
- $output .= drupal_render($form['pager']);
- }
- $output .= drupal_render($form);
- return $output;
-}
-
-/**
- * Form API callback; Validate the moderation queue form.
- */
-function akismet_moderation_form_validate($form_id, $edit) {
- $mode = $edit['mode'];
- $submode = $edit['submode'];
- $operation = $edit['operation'];
- $valid_operations = akismet_moderator_operations($mode, $submode);
-
- if (!isset($valid_operations[$operation])) {
- form_set_error('', t('Please, choose a valid operation.'));
- }
- $edit['items'] = array_diff($edit['items'], array(0));
- if (count($edit['items']) == 0) {
- if ($operation == 'delete') {
- form_set_error('', t('Please, select some items to perform the delete operation.'));
- }
- else {
- form_set_error('', t('Please, select some items to perform the action on.'));
- }
- }
-}
-
-/**
- * List the selected items and verify that the admin really wants to delete them.
- */
-function akismet_confirm_multiple_operation() {
- $edit = $_POST;
- $mode = $edit['mode'];
- $submode = $edit['submode'];
- $operation = $edit['operation'];
- $valid_operations = akismet_moderator_operations($mode, $submode);
-
- // Make sure we deal with a valid combination of mode, submode and operation.
- if (!isset($valid_operations[$operation])) {
- return;
- }
-
- $confirm_message = ''. $valid_operations[$operation]['confirm'] .' ';
- $confirm_button = $valid_operations[$operation]['button'];
- $confirm_warning = ''. (isset($valid_operations[$operation]['warning']) ? $valid_operations[$operation]['warning'] : '') .'
';
- $content_type = ($mode == 'nodes' ? 'node' : 'comment');
-
- $form = array();
- $form['items'] = array('#prefix' => '', '#tree' => TRUE);
- // array_filter() returns only elements with actual values
- foreach (array_filter($edit['items']) as $content_id => $value) {
- if ($content = akismet_content_load($content_type, $content_id)) {
- $title = '"'. check_plain($content_type == 'node' ? $content->title : $content->subject) .'", '. t('by') .' '. theme('username', $content);
- $form['items'][$content_id] = array('#type' => 'hidden', '#value' => $content_id, '#prefix' => '', '#suffix' => $title .' ');
- }
- }
- $form['mode'] = array('#type' => 'hidden', '#value' => $mode);
- $form['submode'] = array('#type' => 'hidden', '#value' => $submode);
- $form['operation'] = array('#type' => 'hidden', '#value' => $operation);
-
- // Redirect to a non-existent menu item to make tabs disappear.
- menu_set_active_item('');
-
- $path = 'admin/content/akismet/'. $mode;
- if ($submode != 'spam') {
- $path .= '/'. $submode;
- }
- return confirm_form($form, $confirm_message, $path, $confirm_warning, $confirm_button, t('Cancel'));
-}
-
-/**
- * confirm_form callback; perform the actual operation against selected content.
- */
-function akismet_confirm_multiple_operation_submit($form_id, $edit) {
- $mode = $edit['mode'];
- $submode = $edit['submode'];
- $operation = $edit['operation'];
- $valid_operations = akismet_moderator_operations($mode, $submode);
-
- // Make sure we deal with a valid combination of mode, submode and operation.
- if (!isset($valid_operations[$operation])) {
- return 'admin/content/akismet';
- }
-
- if ($edit['confirm']) {
- $content_type = ($mode == 'nodes' ? 'node' : 'comment');
- foreach ($edit['items'] as $content_id => $value) {
- if ($operation == 'delete') {
- akismet_content_delete($content_type, $content_id);
- $message = ($mode == 'nodes' ? t('The nodes have been deleted.') : t('The comments have been deleted.'));
- }
- else if ($content = akismet_content_load($content_type, $content_id)) {
- if ($content_type == 'node') {
- $is_published = ($content->status ? TRUE : FALSE);
- }
- else { // comment
- $is_published = ($content->status == COMMENT_PUBLISHED ? TRUE : FALSE);
- }
- $is_spam = akismet_content_is_spam($content_type, $content_id);
-
- if ($operation == 'submit-spam' && !$is_spam) {
- akismet_content_spam_operation($content_type, $content, 'submit-spam');
- }
- else if ($operation == 'submit-ham' && $is_spam) {
- akismet_content_spam_operation($content_type, $content, 'submit-ham');
- }
-
- if (in_array($operation, array('unpublish','submit-spam')) && $is_published) {
- akismet_content_publish_operation($content_type, $content, 'unpublish');
- }
- else if (in_array($operation, array('publish','submit-ham')) && !$is_published) {
- akismet_content_publish_operation($content_type, $content, 'publish');
- }
-
- $message = ($mode == 'nodes' ? t('The nodes have been updated.') : t('The comments have been updated.'));
- }
- }
- drupal_set_message($message);
- }
-
- $path = 'admin/content/akismet/'. $mode;
- if ($submode != 'spam') {
- $path .= '/'. $submode;
- }
- return $path;
-}
Index: akismet_cron.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/akismet/akismet_cron.inc,v
retrieving revision 1.4
diff -u -p -r1.4 akismet_cron.inc
--- akismet_cron.inc 1 Jun 2007 21:41:17 -0000 1.4
+++ akismet_cron.inc 23 Feb 2008 21:00:44 -0000
@@ -5,7 +5,7 @@
* Shutdown function executed at cron time.
*/
function akismet_cron_shutdown() {
- watchdog('cron', t('Akismet cron started at %time.', array('%time' => format_date(time(), 'custom', 'H:i:s'))));
+ watchdog('cron', 'Akismet cron started at %time.', array('%time' => format_date(time(), 'custom', 'H:i:s')));
// Expired content spam that we have to remove from each content repository.
$expired_content_spam = array('nids'=>array(), 'cids'=>array());
@@ -16,13 +16,13 @@ function akismet_cron_shutdown() {
$expire_spam_age = variable_get('akismet_remove_spam_age', 259200);
if ($expire_spam_age > 0) {
$result = db_query('SELECT content_type, content_id FROM {akismet_spam_marks} WHERE spam_created < %d', time() - $expire_spam_age);
- if (db_num_rows($result)) {
+// if (db_num_rows($result)) {
while ($s = db_fetch_object($result)) {
$key = ($s->content_type == 'node' ? 'nids' : 'cids');
$expired_content_spam[$key][] = $s->content_id;
$obsolete_spam_marks[$key][] = $s->content_id;
}
- }
+// }
}
// Deal with possible spam marks for content that have already been removed from database.
@@ -31,21 +31,21 @@ function akismet_cron_shutdown() {
// This is why this cron task is being more complex that it could really be. Anyway, these
// queries shouldn't be too heavy.
$result = db_query('SELECT s.content_id FROM {akismet_spam_marks} s LEFT JOIN {node} n ON s.content_id = n.nid WHERE s.content_type = \'node\' AND n.nid IS NULL');
- if (db_num_rows($result)) {
+//if (db_num_rows($result)) {
while ($s = db_fetch_object($result)) {
if (!in_array($s->content_id, $obsolete_spam_marks['nids'])) {
$obsolete_spam_marks['nids'][] = $s->content_id;
}
}
- }
+//}
$result = db_query('SELECT s.content_id FROM {akismet_spam_marks} s LEFT JOIN {comments} c ON s.content_id = c.cid WHERE s.content_type = \'comment\' AND c.cid IS NULL');
- if (db_num_rows($result)) {
+//if (db_num_rows($result)) {
while ($s = db_fetch_object($result)) {
if (!in_array($s->content_id, $obsolete_spam_marks['cids'])) {
$obsolete_spam_marks['cids'][] = $s->content_id;
}
}
- }
+//}
// From this point on is where we really will delete stuff from database.
// Drupal cache will need to be cleared so anonymous users get updated views.
@@ -115,5 +115,5 @@ function akismet_cron_shutdown() {
if ($clear_cache) {
akismet_clear_cache();
}
- watchdog('cron', t('Akismet cron completed at %time.', array('%time' => format_date(time(), 'custom', 'H:i:s'))));
+ watchdog('cron', 'Akismet cron completed at %time.', array('%time' => format_date(time(), 'custom', 'H:i:s')));
}