? allchanges.patch ? duplicate.install.patch ? spam.install.patch Index: spam.info =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/spam/Attic/spam.info,v retrieving revision 1.1.4.4.2.3 diff -u -p -r1.1.4.4.2.3 spam.info --- spam.info 25 Nov 2007 00:01:56 -0000 1.1.4.4.2.3 +++ spam.info 20 Feb 2008 00:04:12 -0000 @@ -2,4 +2,4 @@ name = Spam API description = The core Spam API for autodetecting and managing spam. package = Spam - +core=6.x Index: spam.install =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/spam/Attic/spam.install,v retrieving revision 1.1.2.1.2.9.2.6 diff -u -p -r1.1.2.1.2.9.2.6 spam.install --- spam.install 26 Nov 2007 22:48:26 -0000 1.1.2.1.2.9.2.6 +++ spam.install 20 Feb 2008 00:04:12 -0000 @@ -2,112 +2,298 @@ // $Id: spam.install,v 1.1.2.1.2.9.2.6 2007/11/26 22:48:26 jeremy Exp $ /** + * spam database schema * + * @TODO: descriptions + */ +function spam_schema() { + $schema['spam_filters_errors'] = array( + 'fields' => array( + 'bid' => array( + 'type' => 'serial', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'disp-width' => '11' + ), + 'content_type' => array( + 'type' => 'varchar', + 'length' => '128', + 'not null' => TRUE, + 'default' => '' + ), + 'content_id' => array( + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => FALSE, + 'default' => 0, + 'disp-width' => '11' + ), + 'content_hash' => array( + 'type' => 'char', + 'length' => '32', + 'not null' => TRUE, + 'default' => '' + ), + 'content' => array( + 'type' => 'text', + 'not null' => TRUE + ), + 'hostname' => array( + 'type' => 'varchar', + 'length' => '15', + 'not null' => TRUE, + 'default' => '' + ), + 'timestamp' => array( + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => FALSE, + 'default' => 0, + 'disp-width' => '11' + ), + ), + 'primary key' => array('bid'), + 'unique keys' => array( + 'content_hash' => array('content_hash'), + 'content_id' => array('content_id', 'content_type') + ), + 'indexes' => array( + 'content_hash_2' => array('content_hash'), + 'content_type' => array('content_type'), + 'hostname' => array('hostname'), + 'timestamp' => array('timestamp') + ), + ); + $schema['spam_filters'] = array( + 'description' => t('Provides global configurations for all enabled spam filters.'), + 'fields' => array( + 'fid' => array( + 'description' => t('The primary identifier for a spam filter.'), + 'type' => 'serial', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'disp-width' => '11' + ), + 'gid' => array( + 'description' => t('Foreign key for {spam_filters_groups}.'), + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'default' => 0, + 'disp-width' => '11' + ), + 'name' => array( + 'description' => t('The filter name.'), + 'type' => 'varchar', + 'length' => '128', + 'not null' => TRUE, + 'default' => '' + ), + 'module' => array( + 'description' => t('The module this filter belongs to.'), + 'type' => 'varchar', + 'length' => '128', + 'not null' => TRUE, + 'default' => '' + ), + 'status' => array( + 'description' => t('Allows a filter to be enabled or disabled.'), + 'type' => 'int', + 'unsigned' => TRUE, + 'size' => 'tiny', + 'not null' => TRUE, + 'default' => 0, + 'disp-width' => '3' + ), + 'weight' => array( + 'description' => t('Allows filters to be ordered.'), + 'type' => 'int', + 'size' => 'tiny', + 'not null' => TRUE, + 'default' => 0, + 'disp-width' => '4' + ), + 'gain' => array( + 'description' => t('Allows you to minimize or amplify the effect of a given filter.'), + 'type' => 'int', + 'unsigned' => TRUE, + 'size' => 'tiny', + 'not null' => TRUE, + 'default' => 0, + 'disp-width' => '3' + ) + ), + 'primary key' => array('fid'), + 'indexes' => array( + 'gid' => array('gid'), + 'module' => array('module'), + 'name' => array('name'), + 'status' => array('status'), + 'weight' => array('weight') + ), + ); + $schema['spam_filters_groups'] = array( + 'description' => t('Group of spam filters.'), + 'fields' => array( + 'gid' => array( + 'description' => t('The primary identifier for a group of spam filters.'), + 'type' => 'serial', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'disp-width' => '11' + ), + 'name' => array( + 'description' => t('Name of this group.'), + 'type' => 'varchar', + 'length' => '255', + 'not null' => TRUE, + 'default' => '' + ), + 'weight' => array( + 'description' => t('Allows filter groups to be ordered.'), + 'type' => 'int', + 'size' => 'tiny', + 'not null' => TRUE, + 'default' => 0, + 'disp-width' => '4' + ) + ), + 'primary key' => array('gid'), + 'indexes' => array( + 'weight' => array('weight') + ), + ); + $schema['spam_filters_groups_data'] = array( + 'description' => t('Granular per-content-type configurations for enabled spam filters.'), + 'fields' => array( + 'gid' => array( + 'type' => 'serial', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'disp-width' => '11' + ), + 'content_type' => array( + 'type' => 'varchar', + 'length' => '64', // NOTE: other definitions use 128! + 'not null' => TRUE, + 'default' => '' + ) + ), + 'primary key' => array('gid', 'content_type'), + 'indexes' => array( + 'content_type' => array('content_type') + ), + ); + $schema['spam_tracker'] = array( + 'description' => t('Tracks all filtered site content, included both spam and non-spam.'), + 'fields' => array( + 'sid' => array( + 'type' => 'serial', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'disp-width' => '11' + ), + 'content_type' => array( + 'type' => 'varchar', + 'length' => '128', + 'not null' => TRUE, + 'default' => '' + ), + 'content_id' => array( + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => FALSE, + 'default' => 0, + 'disp-width' => '11' + ), + 'score' => array( + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => FALSE, + 'default' => 0, + 'disp-width' => '4' + ), + 'hostname' => array( + 'type' => 'varchar', + 'length' => '15', + 'not null' => TRUE, + 'default' => '' + ), + 'timestamp' => array( + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => FALSE, + 'default' => 0, + 'disp-width' => '11' + ) + ), + 'primary key' => array('sid'), + 'unique keys' => array( + 'content_id' => array('content_id', 'content_type') + ), + 'indexes' => array( + 'content_type' => array('content_type'), + 'hostname' => array('hostname'), + 'score' => array('score'), + 'timestamp' => array('timestamp') + ), + ); + $schema['spam_log'] = array( + 'description' => t('Logging mechanism similar to watchdog, but provides additional information specific to spam tracking.'), + 'fields' => array( + 'lid' => array( + 'type' => 'serial', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'disp-width' => '11' + ), + 'sid' => array( + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'default' => 0, + 'disp-width' => '11' + ), + 'uid' => array( + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'default' => 0, + 'disp-width' => '10' + ), + 'log' => array( + 'type' => 'varchar', + 'length' => '255', + 'not null' => TRUE, + 'default' => '' + ), + 'timestamp' => array( + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => FALSE, + 'default' => 0, + 'disp-width' => '11' + ) + ), + 'primary key' => array('lid'), + 'indexes' => array( + 'sid' => array('sid'), + 'timestamp' => array('timestamp')), + ); + return $schema; +} +/** + * install spam data tables */ function spam_install() { - switch ($GLOBALS['db_type']) { - case 'mysql': - case 'mysqli': - // TODO: PostgreSQL support -- patches welcome! - default: - /** - * Provides global and granular per-content-type configurations for all - * enabled spam filters. The status allows a filter to be enabled or - * disabled. The weight allows filters to be ordered. The gain allows - * you to minimize or amplify the effect of a given filter. - */ - db_query("CREATE TABLE {spam_filters} ( - fid INT(11) UNSIGNED NOT NULL AUTO_INCREMENT, - gid INT(11) UNSIGNED DEFAULT '0' NOT NULL, - name VARCHAR(128) NOT NULL DEFAULT '', - module VARCHAR(128) NOT NULL DEFAULT '', - status TINYINT UNSIGNED DEFAULT '0' NOT NULL, - weight TINYINT DEFAULT '0' NOT NULL, - gain TINYINT UNSIGNED DEFAULT '0' NOT NULL, - PRIMARY KEY (fid), - KEY (gid), - KEY (name), - KEY (module), - KEY (status), - KEY (weight) - ) TYPE=MyISAM /*!40100 DEFAULT CHARACTER SET utf8 */;"); - db_query("CREATE TABLE {spam_filters_groups} ( - gid INT(11) UNSIGNED NOT NULL AUTO_INCREMENT, - name VARCHAR(255) NOT NULL DEFAULT '', - weight TINYINT DEFAULT '0' NOT NULL, - PRIMARY KEY (gid), - KEY (weight) - ) TYPE=MyISAM /*!40100 DEFAULT CHARACTER SET utf8 */;"); - db_query("CREATE TABLE {spam_filters_groups_data} ( - gid INT(11) UNSIGNED NOT NULL AUTO_INCREMENT, - content_type VARCHAR(64) NOT NULL DEFAULT '', - PRIMARY KEY (gid,content_type), - KEY (content_type) - ) TYPE=MyISAM /*!40100 DEFAULT CHARACTER SET utf8 */;"); - /** - * Tracks all filtered site content, included both spam and non-spam. - */ - db_query("CREATE TABLE {spam_tracker} ( - sid INT(11) UNSIGNED NOT NULL AUTO_INCREMENT, - content_type VARCHAR(128) NOT NULL DEFAULT '', - content_id INT(11) UNSIGNED DEFAULT '0', - score INT(4) UNSIGNED DEFAULT '0', - hostname VARCHAR(15) NOT NULL DEFAULT '', - timestamp INT(11) UNSIGNED DEFAULT '0', - PRIMARY KEY (sid), - UNIQUE KEY (content_id,content_type), - KEY (content_type), - KEY (score), - KEY (hostname), - KEY (timestamp) - ) TYPE=MyISAM /*!40100 DEFAULT CHARACTER SET utf8 */;"); - /** - * - */ - db_query("CREATE TABLE {spam_filters_errors} ( - bid INT(11) UNSIGNED NOT NULL AUTO_INCREMENT, - content_type VARCHAR(128) NOT NULL DEFAULT '', - content_id INT(11) UNSIGNED DEFAULT '0', - content_hash CHAR(32) NOT NULL DEFAULT '', - content TEXT NOT NULL, - hostname VARCHAR(15) NOT NULL DEFAULT '', - timestamp INT(11) UNSIGNED DEFAULT '0', - PRIMARY KEY (bid), - UNIQUE KEY (content_id,content_type), - UNIQUE KEY (content_hash), - KEY (content_type), - KEY (content_hash), - KEY (hostname), - KEY (timestamp) - ) TYPE=MyISAM /*!40100 DEFAULT CHARACTER SET utf8 */;"); - /** - * Logging mechanism similar to watchdog, but provides additional - * information specific to spam tracking. - */ - db_query("CREATE TABLE {spam_log} ( - lid int(11) UNSIGNED NOT NULL AUTO_INCREMENT, - sid INT(11) UNSIGNED NOT NULL DEFAULT '0', - uid int(10) UNSIGNED NOT NULL DEFAULT '0', - log varchar(255) NOT NULL DEFAULT '', - timestamp int(11) UNSIGNED DEFAULT '0', - PRIMARY KEY lid (lid), - KEY sid (sid), - KEY timestamp (timestamp) - ) TYPE=MyISAM /*!40100 DEFAULT CHARACTER SET utf8 */;"); - - } + drupal_install_schema('spam'); drupal_set_message(t('All required spam tables have been created.')); } -/** +/** * Completely uninstall the spam module. */ function spam_uninstall() { - $tables = array('spam_filters', 'spam_tracker', 'spam_log', 'spam_filters_groups', 'spam_filters_groups_data'); - foreach ($tables as $table) { - db_query('DROP TABLE {'. $table .'}'); - } + drupal_uninstall_schema('spam'); drupal_set_message(t('All spam module configuration data and tables have been deleted.')); -} - -?> +} \ No newline at end of file Index: spam.module =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/spam/spam.module,v retrieving revision 1.51.4.1.2.41.2.7 diff -u -p -r1.51.4.1.2.41.2.7 spam.module --- spam.module 2 Dec 2007 22:30:11 -0000 1.51.4.1.2.41.2.7 +++ spam.module 20 Feb 2008 00:04:13 -0000 @@ -19,7 +19,7 @@ define('SPAM_DEFAULT_THRESHOLD', 86); spam_init_api(); -/** +/** * API call for scanning content for spam. If spam is found, the appropriate * action will be taken. */ @@ -50,7 +50,7 @@ function spam_content_is_spam($content, /** * API call to determine the likeliness that a given piece of content is spam, - * returning a rating from 1% likelihood to 99% likelihood. It is unlikely + * returning a rating from 1% likelihood to 99% likelihood. It is unlikely * that you want to call this function directly. * * @param $content @@ -68,7 +68,7 @@ function spam_content_filter($content, $ $fields = spam_invoke_module($type, 'filter_fields', $content, $extra); if (!empty($fields) && is_array($fields['main'])) { // TODO: Once content-type groups are implemented, this query will - // determine which group to filter the given piece of content with. It + // determine which group to filter the given piece of content with. It // will default to a gid of 0 if undefined. //$gid = (int)db_result(db_query("SELECT gid FROM {spam_filters_groups_data} WHERE content_type = '%s'", $type)); $gid = 0; @@ -120,15 +120,15 @@ function spam_content_insert($content, $ $error = FALSE; if ($id = spam_invoke_module($type, 'content_id', $content, $extra)) { $score = spam_content_filter($content, $type, $extra); - db_query("INSERT INTO {spam_tracker} (content_type, content_id, score, hostname, timestamp) VALUES('%s', %d, %d, '%s', %d)", $type, $id, $score, $_SERVER['REMOTE_ADDR'], time()); + db_query("INSERT INTO {spam_tracker} (content_type, content_id, score, hostname, timestamp) VALUES('%s', %d, %d, '%s', %d)", $type, $id, $score, ip_address(), time()); $sid = db_result(db_query("SELECT sid FROM {spam_tracker} WHERE content_type = '%s' AND content_id = %d", $type, $id)); if ($sid) { - watchdog('spam', t('Inserted %type with id %id into spam tracker table.', array('%type' => $type, '%id' => $id)), WATCHDOG_NOTICE); + watchdog('spam', 'Inserted %type with id %id into spam tracker table.', array('%type' => $type, '%id' => $id), WATCHDOG_NOTICE); $extra['sid'] = $sid; if (!isset($extra['host'])) { // Content type modules can set this value, should REMOTE_ADDR not be // the correct IP for their content type. - $extra['host'] = $_SERVER['REMOTE_ADDR']; + $extra['host'] = ip_address(); } $fields = spam_invoke_module($type, 'filter_fields', $content, $extra); if (!empty($fields) && is_array($fields['main'])) { @@ -140,17 +140,17 @@ function spam_content_insert($content, $ } } else { - watchdog('spam', t('Function spam_content_insert failed, no fields are defined for %type content type.', array('%type' => $type)), WATCHDOG_ERROR); + watchdog('spam', 'Function spam_content_insert failed, no fields are defined for %type content type.', array('%type' => $type), WATCHDOG_ERROR); $error = -3; } } else { - watchdog('spam', t('Function spam_content_insert failed, unable to insert %type with id %id into spam_tracker table.', array('%type' => $type, '%id' => $id)), WATCHDOG_ERROR); + watchdog('spam', 'Function spam_content_insert failed, unable to insert %type with id %id into spam_tracker table.', array('%type' => $type, '%id' => $id), WATCHDOG_ERROR); $error = -2; } } else { - watchdog('spam', t('Function spam_content_insert failed, unable to insert %type into spam_tracker table, no id found in the content array.', array('%type' => $type)), WATCHDOG_ERROR); + watchdog('spam', 'Function spam_content_insert failed, unable to insert %type into spam_tracker table, no id found in the content array.', array('%type' => $type), WATCHDOG_ERROR); $error = -1; } @@ -172,12 +172,12 @@ function spam_content_update($content, $ db_query("UPDATE {spam_tracker} SET score = %d, hostname = %d, timestamp = %d WHERE content_type = '%s' AND content_id = '%s'", $score, time(), $type, $id); $sid = db_result(db_query("SELECT sid FROM {spam_tracker} WHERE content_type = '%s' AND content_id = %d", $type, $id)); if ($sid) { - watchdog('spam', t('Updated %type with id %id in spam tracker table.', array('%type' => $type, '%id' => $id)), WATCHDOG_NOTICE); + watchdog('spam', 'Updated %type with id %id in spam tracker table.', array('%type' => $type, '%id' => $id), WATCHDOG_NOTICE); $extra['sid'] = $sid; if (!isset($extra['host'])) { // Content type modules can set this value, should REMOTE_ADDR not be // the correct IP for their content type. - $extra['host'] = $_SERVER['REMOTE_ADDR']; + $extra['host'] = ip_address(); } $fields = spam_invoke_module($type, 'filter_fields', $content, $extra); if (!empty($fields) && is_array($fields['main'])) { @@ -189,19 +189,19 @@ function spam_content_update($content, $ } } else { - watchdog('spam', t('Function spam_content_update failed, no fields are defined for %type content type.', array('%type' => $type)), WATCHDOG_ERROR); + watchdog('spam', 'Function spam_content_update failed, no fields are defined for %type content type.', array('%type' => $type), WATCHDOG_ERROR); $error = -3; } } else { - watchdog('spam', t('Update to %type with id %id not filtered before, inserting.', array('%type' => $type, '%id' => $id)), WATCHDOG_NOTICE); + watchdog('spam', 'Update to %type with id %id not filtered before, inserting.', array('%type' => $type, '%id' => $id), WATCHDOG_NOTICE); // It seems that the content hasn't ever been scanned before, let's try // inserting it. $error = spam_content_insert($content, $type, $extra); } } else { - watchdog('spam', t('Function spam_content_update failed, unable to update %type in spam_tracker table, no id found in the content array.', array('%type' => $type)), WATCHDOG_ERROR); + watchdog('spam', 'Function spam_content_update failed, unable to update %type in spam_tracker table, no id found in the content array.', array('%type' => $type), WATCHDOG_ERROR); $error = -1; } @@ -225,7 +225,7 @@ function spam_content_delete($content, $ if (!isset($extra['host'])) { // Content type modules can set this value, should REMOTE_ADDR not be // the correct IP for their content type. - $extra['host'] = $_SERVER['REMOTE_ADDR']; + $extra['host'] = ip_address(); } $fields = spam_invoke_module($type, 'filter_fields', $content, $extra); if (!empty($fields) && is_array($fields['main'])) { @@ -237,23 +237,23 @@ function spam_content_delete($content, $ } } else { - watchdog('spam', t('Function spam_content_delete failed, no fields are defined for %type content type.', array('%type' => $type)), WATCHDOG_ERROR); + watchdog('spam', 'Function spam_content_delete failed, no fields are defined for %type content type.', array('%type' => $type), WATCHDOG_ERROR); $error = -3; } db_query("DELETE FROM {spam_tracker} WHERE sid = %d", $sid); - watchdog('spam', t('Deleted %type content with id %id.', array('%type' => $type, '%id' => $id)), WATCHDOG_NOTICE); + watchdog('spam', 'Deleted %type content with id %id.', array('%type' => $type, '%id' => $id), WATCHDOG_NOTICE); } else { - watchdog('spam', t('Atempt to delete %type with id %id failed, does not exist in spam_tracker table.', array('%type' => $type, '%id' => $id)), WATCHDOG_WARNING); + watchdog('spam', 'Atempt to delete %type with id %id failed, does not exist in spam_tracker table.', array('%type' => $type, '%id' => $id), WATCHDOG_WARNING); $error = -2; } } else { - watchdog('spam', t('Function spam_content_delete failed, unable to delete %type from spam_tracker table, no id found in the content array.', array('%type' => $type)), WATCHDOG_ERROR); + watchdog('spam', 'Function spam_content_delete failed, unable to delete %type from spam_tracker table, no id found in the content array.', array('%type' => $type), WATCHDOG_ERROR); $error = -1; } - return $error; + return $error; } /*********************/ @@ -261,93 +261,118 @@ function spam_content_delete($content, $ /** * Drupal _menu() hook. */ -function spam_menu($may_cache) { +function spam_menu() { $items = array(); - if ($may_cache) { - $items[] = array( - 'path' => 'admin/settings/spam', - 'title' => t('Spam'), - 'callback' => 'spam_admin_settings', - 'access' => user_access('administer spam'), - 'description' => t('Configure the spam module.'), - ); - $items[] = array( - 'path' => 'admin/settings/spam/general', - 'title' => t('General'), - 'type' => MENU_DEFAULT_LOCAL_TASK, - 'access' => user_access('administer spam'), - 'weight' => -4, - ); - $items[] = array( - 'path' => 'admin/settings/spam/filters', - 'title' => t('Filters'), - 'callback' => 'spam_admin_filter_overview', - 'type' => MENU_LOCAL_TASK, - 'access' => user_access('administer spam'), - 'weight' => -2, - ); + $items['admin/settings/spam'] = array( + 'title' => 'Spam', + 'page callback' => 'spam_admin_settings', + 'access callback' => 'user_access', + 'access arguments' => array('administer spam'), + 'description' => 'Configure the spam module.', + ); + $items['admin/settings/spam/general'] = array( + 'title' => 'General', + 'type' => MENU_DEFAULT_LOCAL_TASK, + 'access callback' => 'user_access', + 'access arguments' => array('administer spam'), + 'weight' => -4, + ); + $items['admin/settings/spam/filters'] = array( + 'title' => 'Filters', + 'page callback' => 'spam_admin_filter_overview', + 'type' => MENU_LOCAL_TASK, + 'access callback' => 'user_access', + 'access arguments' => array('administer spam'), + 'weight' => -2, + ); - $items[] = array( - 'path' => 'admin/settings/spam/filters/overview', - 'title' => t('Overview'), - 'weight' => -2, - 'type' => MENU_DEFAULT_LOCAL_TASK, - 'access' => user_access('administer spam'), - ); - $items[] = array( - 'path' => 'admin/settings/spam/groups', - 'title' => t('Content groups'), - 'weight' => 0, - 'callback' => 'spam_admin_filter_groups', - 'access' => user_access('administer spam'), - 'type' => MENU_LOCAL_TASK, - ); - $items[] = array( - 'path' => 'spam/denied', - 'callback' => 'spam_denied_page', - 'type' => MENU_CALLBACK, - 'access' => TRUE, - ); + $items['admin/settings/spam/filters/overview'] = array( + 'title' => 'Overview', + 'weight' => -2, + 'type' => MENU_DEFAULT_LOCAL_TASK, + 'access callback' => 'user_access', + 'access arguments' => array('administer spam'), + ); + $items['admin/settings/spam/groups'] = array( + 'title' => 'Content groups', + 'weight' => 0, + 'page callback' => 'spam_admin_filter_groups', + 'access callback' => 'user_access', + 'access arguments' => array('administer spam'), + 'type' => MENU_LOCAL_TASK, + ); + $items['spam/denied'] = array( + 'page callback' => 'spam_denied_page', + 'type' => MENU_CALLBACK, + 'access callback' => TRUE, + ); + return $items; +} + +/** + * old !$may_cache stuff from spam_menu + * + * did I understand this correctly? + * see: http://drupal.org/node/103114 + * + * also - how do I add these links? is the + * return enough? + */ +function spam_init() { + $items['spam/denied/error/%spam_content_hash/%spam_signed_hash'] = array( + 'title' => 'Report legitimate content', + 'page callback' => 'spam_denied_in_error_page', + 'type' => MENU_CALLBACK, + 'access callback' => true, + ); + $items['spam/%spam_content_module/%spam_content_id/spam'] = array( + 'page callback' => 'spam_mark_as_spam', + 'page arguments' => array(1, 2, array('redirect' => TRUE)), + 'access callback' => true, + ); + $items['spam/%spam_content_module/%spam_content_id/notspam'] = array( + 'page callback' => 'spam_mark_as_not_spam', + 'page arguments' => array(1, 2, array('redirect' => TRUE)), + 'access callback' => true, + ); + return $items; +} + +/** + * Menu callback; content module + */ +function spam_content_module_load($module) { + if (spam_invoke_module($module, 'content_module') == $module) { + return $module; } else { - if (arg(0) == 'spam') { - if (arg(1) == 'denied' && arg(2) == 'error') { - $hash1 = md5($_SESSION['content']); - $hash2 = _spam_sign($_SESSION['content']); - if (arg(3) == $hash1 && arg(4) == $hash2) { - $items[] = array( - 'path' => "spam/denied/error/$hash1/$hash2", - 'title' => t('Report legitimate content'), - 'callback' => 'spam_denied_in_error_page', - 'type' => MENU_CALLBACK, - 'access' => TRUE, - ); - } - } - if (is_numeric(arg(2)) && (arg(3) == 'spam' || arg(3) == 'notspam')) { - $type = arg(1); - if (spam_invoke_module($type, 'content_module') == $type) { - $id = arg(2); - $action = arg(3); - if ($action == 'spam') { - $callback = 'spam_mark_as_spam'; - } - else { - $callback = 'spam_mark_as_not_spam'; - } - $items[] = array( - 'path' => "spam/$type/$id/$action", - 'callback' => $callback, - 'callback arguments' => array($type, $id, array('redirect' => TRUE)), - 'type' => MENU_CALLBACK, - 'access' => TRUE, - ); - } - } - } + return false; } - return $items; +} + +/** + * Menu callback; content id + */ +function spam_content_id_load($id) { + return is_numeric($id) ? intval($id) : false; +} + +/** + * Menu callback; loads spam hash object + */ +function spam_content_hash_load($arg) { + // could this be made static? + $hash = md5($_SESSION['content']); + return ($arg == $hash) ? $hash : false; +} + +/** + * Menu callback; loads signed spam hash + */ +function spam_signed_hash_load($arg) { + $hash = _spam_sign($_SESSION['content']); + return ($arg == $hash) ? $hash : false; } /** @@ -360,7 +385,7 @@ function spam_perm() { /** * Online help. Drupal _help() hook. */ -function spam_help($path) { +function spam_help($path, $arg) { switch ($path) { case 'admin/settings/spam': return t('Enable and disable individual spam filters for each content type, controlling which order the content is passed through the filters.'); @@ -371,7 +396,7 @@ function spam_help($path) { /** * Drupal form_alter() hook. */ -function spam_form_alter($form_id, &$form) { +function spam_form_alter(&$form, &$form_state, $form_id) { spam_invoke_api('process_form', $form_id, &$form); } @@ -391,8 +416,8 @@ function spam_link($type, $content = 0, */ function spam_admin_filter_overview() { /** - * TODO: For phase one we will only have the default group. A later - * development phase will allow the creation/configuration of custom + * TODO: For phase one we will only have the default group. A later + * development phase will allow the creation/configuration of custom * content-type groups. Content-types are defined through hooks, and * include nodes (book, forum, etc), comments, users, profiles, etc... */ @@ -405,7 +430,7 @@ function spam_admin_filter_overview() { } /** - * Spam filter content-type groups page. Allows creation/deletion of + * Spam filter content-type groups page. Allows creation/deletion of * content-type groups. Each content type can only be in one group. If a * content-type is not specifically added to one of these groups, it is * automatically part of the default group (gid=0). @@ -471,13 +496,24 @@ function spam_admin_filters() { return $form; } -function spam_admin_filters_submit($form_id, $form_values) { - for ($i = 0; $i < $form_values['counter']; $i++) { - db_query('UPDATE {spam_filters} SET status = %d, gain = %d, weight = %d WHERE fid = %d AND gid = %d', $form_values["status-$i"], $form_values["gain-$i"], $form_values["weight-$i"], $form_values["fid-$i"], $form_values["gid-$i"]); +function spam_admin_filters_submit($form, &$form_state) { + for ($i = 0; $i < $form_state['value']['counter']; $i++) { + db_query('UPDATE {spam_filters} SET status = %d, gain = %d, weight = %d WHERE fid = %d AND gid = %d', $form_state['value']["status-$i"], $form_state['value']["gain-$i"], $form_state['value']["weight-$i"], $form_state['value']["fid-$i"], $form_state['value']["gid-$i"]); } } -/** +/** + * register theme functions + */ +function spam_theme() { + return array( + 'spam_admin_filters' => array( + 'arguments' => array('form'), + ), + ); +} + +/** * Display list of filters. */ function theme_spam_admin_filters($form) { @@ -584,27 +620,27 @@ function spam_admin_settings_form() { /** * Store general spam settings in database. */ -function spam_admin_settings_form_submit($form_id, $form_values) { +function spam_admin_settings_form_submit($form, &$form_state) { $modules = spam_invoke_api('content_module'); foreach ($modules as $module) { $content_types = spam_invoke_module($module, 'content_types'); if (is_array($content_types)) { foreach ($content_types as $content_type) { $name = $content_type['name']; - if ($form_values['op'] == t('Reset to defaults')) { + if ($form_state['values']['op'] == t('Reset to defaults')) { variable_del("spam_filter_$name"); } else { - variable_set("spam_filter_$name", $form_values[$name]); + variable_set("spam_filter_$name", $form_state['values'][$name]); } } } } - if ($form_values['op'] == t('Reset to defaults')) { + if ($form_state['values']['op'] == t('Reset to defaults')) { variable_del('spam_threshold'); } else { - variable_set('spam_threshold', $form_values['spam_threshold']); + variable_set('spam_threshold', $form_state['values']['spam_threshold']); } } @@ -618,7 +654,7 @@ function spam_init_filters() { $modules = spam_invoke_api('filter_module'); foreach ($modules as $module) { $filter = spam_invoke_module($module, 'filter_info'); - $fid = db_result(db_query("SELECT fid FROM {spam_filters} WHERE name = '%s' AND module = '%s' LIMIT 1", $filter['name'], $filter['module'])); + $fid = db_result(db_query_range("SELECT fid FROM {spam_filters} WHERE name = '%s' AND module = '%s'", $filter['name'], $filter['module'], 0, 1)); if (!$fid) { spam_install_filter($filter); } @@ -653,9 +689,9 @@ function spam_install_filter($filter) { } /** - * As the spam module isn't a core Drupal module, many important modules won't + * As the spam module isn't a core Drupal module, many important modules won't * utilize its API. We define the appropriate hooks for these modules in the - * modules/ subdirectory. For example, we define the spam api hooks for the + * modules/ subdirectory. For example, we define the spam api hooks for the * node module in modules/spam_node.inc. */ function spam_init_api() { @@ -664,7 +700,7 @@ function spam_init_api() { if (!$initialized) { // We only need to include these files once. $initialized = TRUE; - $path = drupal_get_path('module', 'spam') . '/modules'; + $path = drupal_get_path('module', 'spam') .'/modules'; // These files must be names spam_*.inc, such as spam_node.inc. $files = drupal_system_listing('spam_.*\.inc$', $path, 'name', 0); foreach ($files as $file) { @@ -714,8 +750,8 @@ function spam_sanitize_score($score) { */ function _spam_sign($text) { if (!variable_get('spam_sign_start', '')) { - variable_set('spam_sign_start', rand(0,22)); - variable_set('spam_sign_end', rand(45,115)); + variable_set('spam_sign_start', rand(0, 22)); + variable_set('spam_sign_end', rand(45, 115)); } if (!variable_get('spam_sign_key', '')) { variable_set('spam_sign_key', md5(microtime())); @@ -736,7 +772,7 @@ function _spam_error_link($text) { } } -/** +/** * Generate an error message informing the user that their posting has been * blocked by the spam filter. Provide a dynamic link for reporting if their * posting was blocked in error. @@ -747,7 +783,7 @@ function _spam_error_link($text) { function spam_denied_page($message = NULL, $title = NULL) { drupal_set_header('HTTP/1.1 403 Forbidden'); if (!$message) { - $message = strtr(variable_get('spam_filtered_message', t('

Your posting on @site from %IP has been automatically flagged by our spam filters as being inappropriate for this website.

At @site we work very hard to keep our web pages free of spam. Unfortunately, sometimes we accidentally block legitimate content. If you are attempting to post legitimate content to this website, you can help us to improve our spam filters and insure that your post appears on our website by clicking this link:

%LINK
', array('@site' => variable_get('site_name', 'Drupal'), ))), array('%IP' => $_SERVER['REMOTE_ADDR'], '%LINK' => _spam_error_link($_SESSION['content']))); + $message = strtr(variable_get('spam_filtered_message', t('

Your posting on @site from %IP has been automatically flagged by our spam filters as being inappropriate for this website.

At @site we work very hard to keep our web pages free of spam. Unfortunately, sometimes we accidentally block legitimate content. If you are attempting to post legitimate content to this website, you can help us to improve our spam filters and insure that your post appears on our website by clicking this link:

%LINK
', array('@site' => variable_get('site_name', 'Drupal'), ))), array('%IP' => ip_address(), '%LINK' => _spam_error_link($_SESSION['content']))); } if (!$title) { $title = t('Your posting was blocked by our spam filter.'); @@ -854,6 +890,4 @@ function spam_unpublish($type, $id, $ext */ function spam_publish($type, $id, $extra = array()) { spam_invoke_module($type, 'publish', $id, $extra); -} - -?> +} \ No newline at end of file Index: filters/bayesian/bayesian.info =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/spam/filters/bayesian/Attic/bayesian.info,v retrieving revision 1.1.2.1 diff -u -p -r1.1.2.1 bayesian.info --- filters/bayesian/bayesian.info 25 Nov 2007 00:01:57 -0000 1.1.2.1 +++ filters/bayesian/bayesian.info 20 Feb 2008 00:04:13 -0000 @@ -2,5 +2,6 @@ name = Bayesian filter description = A bayesian filter. package = Spam -dependencies = spam +dependencies[] = spam +core = 6.x Index: filters/bayesian/bayesian.module =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/spam/filters/bayesian/Attic/bayesian.module,v retrieving revision 1.1.2.1 diff -u -p -r1.1.2.1 bayesian.module --- filters/bayesian/bayesian.module 25 Nov 2007 00:01:57 -0000 1.1.2.1 +++ filters/bayesian/bayesian.module 20 Feb 2008 00:04:13 -0000 @@ -34,6 +34,4 @@ function bayesian_spamapi($op) { 'status' => SPAM_FILTER_ENABLED, ); } -} - -?> +} \ No newline at end of file Index: filters/duplicate/duplicate.info =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/spam/filters/duplicate/Attic/duplicate.info,v retrieving revision 1.1.2.1 diff -u -p -r1.1.2.1 duplicate.info --- filters/duplicate/duplicate.info 25 Nov 2007 03:56:51 -0000 1.1.2.1 +++ filters/duplicate/duplicate.info 20 Feb 2008 00:04:13 -0000 @@ -2,5 +2,6 @@ name = Duplicate filter description = A duplication detecting spam filter. package = Spam -dependencies = spam +dependencies[] = spam +core = 6.x Index: filters/duplicate/duplicate.install =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/spam/filters/duplicate/Attic/duplicate.install,v retrieving revision 1.1.2.3 diff -u -p -r1.1.2.3 duplicate.install --- filters/duplicate/duplicate.install 2 Dec 2007 22:30:12 -0000 1.1.2.3 +++ filters/duplicate/duplicate.install 20 Feb 2008 00:04:13 -0000 @@ -1,35 +1,84 @@ array( + 'iid' => array( + 'type' => 'serial', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'disp-width' => '11' + ), + 'sid' => array( + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'default' => 0, + 'disp-width' => '11' + ), + 'content_hash' => array( + 'type' => 'char', + 'length' => '32', + 'not null' => TRUE, + 'default' => '' + ), + 'hostname' => array( + 'type' => 'varchar', + 'length' => '15', + 'not null' => TRUE, + 'default' => '' + ), + 'duplicate_hash' => array( + 'type' => 'int', + 'not null' => TRUE, + 'default' => 0, + 'disp-width' => '11' + ), + 'duplicate_ip' => array( + 'type' => 'int', + 'not null' => TRUE, + 'default' => 0, + 'disp-width' => '11' + ), + 'spam' => array( + 'type' => 'int', + 'size' => 'tiny', + 'not null' => TRUE, + 'default' => 0, + 'disp-width' => '4' + ), + 'expired' => array( + 'type' => 'int', + 'size' => 'tiny', + 'not null' => TRUE, + 'default' => 0, + 'disp-width' => '4' + ), + 'timestamp' => array( + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => FALSE, + 'default' => 0, + 'disp-width' => '11' + ) + ), + 'primary key' => array('iid'), + 'indexes' => array( + 'content_hash' => array('content_hash'), + 'hostname' => array('hostname'), + 'sid' => array('sid'), + 'spam' => array('spam'), + 'timestamp' => array('timestamp') + ), + ); + return $schema; +} + function duplicate_install() { - switch ($GLOBALS['db_type']) { - case 'mysql': - case 'mysqli': - // TODO: PostgreSQL support -- patches welcome! - default: - /** - * Tracks a 32-bit hash and the IP for each piece of content. - */ - db_query("CREATE TABLE {spam_duplicate} ( - iid INT(11) UNSIGNED NOT NULL AUTO_INCREMENT, - sid INT(11) UNSIGNED NOT NULL DEFAULT '0', - content_hash CHAR(32) NOT NULL DEFAULT '', - hostname VARCHAR(15) NOT NULL DEFAULT '', - duplicate_hash INT(11) NOT NULL DEFAULT '0', - duplicate_ip INT(11) NOT NULL DEFAULT '0', - spam TINYINT NOT NULL DEFAULT '0', - expired TINYINT NOT NULL DEFAULT '0', - timestamp INT(11) UNSIGNED DEFAULT '0', - PRIMARY KEY (iid), - KEY (sid), - KEY (content_hash), - KEY (hostname), - KEY (spam), - KEY (timestamp) - ) TYPE=MyISAM /*!40100 DEFAULT CHARACTER SET utf8 */;"); - } + drupal_install_schema('duplicate'); } function duplicate_uninstall() { - db_query('DROP TABLE {spam_duplicate}'); + drupal_uninstall_schema('duplicate'); } Index: filters/duplicate/duplicate.module =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/spam/filters/duplicate/Attic/duplicate.module,v retrieving revision 1.1.2.5 diff -u -p -r1.1.2.5 duplicate.module --- filters/duplicate/duplicate.module 2 Dec 2007 22:30:12 -0000 1.1.2.5 +++ filters/duplicate/duplicate.module 20 Feb 2008 00:04:14 -0000 @@ -22,31 +22,25 @@ define('DUPLICATE_SPAM', 1); /** * Drupal _menu() hook. */ -function duplicate_menu($may_cache) { +function duplicate_menu() { $items = array(); - - if ($may_cache) { - $items[] = array( - 'path' => 'admin/settings/spam/filters/duplicate', - 'title' => t('Duplicate'), - 'callback' => 'drupal_get_form', - 'callback arguments' => array('duplicate_admin_settings'), - 'description' => t('Configure the spam duplicate filter.'), - 'type' => MENU_LOCAL_TASK, - ); - $items[] = array( - 'path' => 'duplicate/denied/ip', - 'callback' => 'duplicate_denied_ip', - 'type' => MENU_CALLBACK, - 'access' => TRUE, - ); - $items[] = array( - 'path' => 'duplicate/denied/post', - 'callback' => 'duplicate_denied_post', - 'type' => MENU_CALLBACK, - 'access' => TRUE, - ); - } + $items['admin/settings/spam/filters/duplicate'] = array( + 'title' => 'Duplicate', + 'page callback' => 'drupal_get_form', + 'page arguments' => array('duplicate_admin_settings'), + 'description' => 'Configure the spam duplicate filter.', + 'type' => MENU_LOCAL_TASK, + ); + $items['duplicate/denied/ip'] = array( + 'page callback' => 'duplicate_denied_ip', + 'type' => MENU_CALLBACK, + 'access callback' => TRUE, + ); + $items['duplicate/denied/post'] = array( + 'page callback' => 'duplicate_denied_post', + 'type' => MENU_CALLBACK, + 'access callback' => TRUE, + ); return $items; } @@ -57,11 +51,10 @@ function duplicate_menu($may_cache) { */ function duplicate_init() { if (arg(0) == 'duplicate' && arg(1) == 'denied' && arg(2) == 'ip') return; - if ((variable_get('duplicate_blacklist_action', DUPLICATE_BLACKLIST_NOTIFY) - == DUPLICATE_BLACKLIST_BLOCK) + if ((variable_get('duplicate_blacklist_action', DUPLICATE_BLACKLIST_NOTIFY) == DUPLICATE_BLACKLIST_BLOCK) && (variable_get('duplicate_blacklist', DUPLICATE_DEFAULT_BLACKLIST) > -1)) { // Blacklisting and IP blocking enabled. - $duplicate_ip = (int)db_query("SELECT COUNT(iid) FROM {spam_duplicate} WHERE hostname = '%s' AND spam = %d", $_SERVER['REMOTE_ADDR'], DUPLICATE_SPAM); + $duplicate_ip = (int)db_query("SELECT COUNT(iid) FROM {spam_duplicate} WHERE hostname = '%s' AND spam = %d", ip_address(), DUPLICATE_SPAM); if ($duplicate_ip >= variable_get('duplicate_blacklist', DUPLICATE_DEFAULT_BLACKLIST)) { drupal_goto("duplicate/denied/ip"); } @@ -97,8 +90,7 @@ function duplicate_spamapi($op, $content break; case 'delete': - if (is_array($extra) && $extra['sid'] && !empty($content) && - !empty($fields)) { + if (is_array($extra) && $extra['sid'] && !empty($content) && !empty($fields)) { db_query("DELETE FROM {spam_duplicate} WHERE sid = %d", $extra['sid']); } break; @@ -130,7 +122,7 @@ function duplicate_spamapi($op, $content } /** - * + * */ function duplicate_admin_settings() { $form['content'] = array( @@ -185,11 +177,11 @@ function duplicate_admin_settings() { return system_settings_form($form); } -/** +/** * Save the configuration. */ -function duplicate_admin_settings_submit($form_id, $form_values) { - if ($form_values['op'] == t('Reset to defaults')) { +function duplicate_admin_settings_submit($form, $form_state) { + if ($form_state['values']['op'] == t('Reset to defaults')) { variable_del('duplicate_threshold'); variable_del('duplicate_post_message'); variable_del('duplicate_blacklist'); @@ -198,11 +190,11 @@ function duplicate_admin_settings_submit drupal_set_message('Configuration reset to defaults.'); } else { - variable_set('duplicate_threshold', $form_values['duplicate_threshold']); - variable_set('duplicate_post_message', $form_values['duplicate_post_message']); - variable_set('duplicate_blacklist', $form_values['duplicate_blacklist']); - variable_set('duplicate_blacklist_action', $form_values['duplicate_blacklist_action']); - variable_set('duplicate_blacklist_message', $form_values['duplicate_blacklist_message']); + variable_set('duplicate_threshold', $form_state['values']['duplicate_threshold']); + variable_set('duplicate_post_message', $form_state['values']['duplicate_post_message']); + variable_set('duplicate_blacklist', $form_state['values']['duplicate_blacklist']); + variable_set('duplicate_blacklist_action', $form_state['values']['duplicate_blacklist_action']); + variable_set('duplicate_blacklist_message', $form_state['values']['duplicate_blacklist_message']); drupal_set_message('Configuration saved.'); } } @@ -230,14 +222,14 @@ function duplicate_spam_filter($content, $hash = _duplicate_content_hash($content, $fields); $duplicate_hash = db_result(db_query("SELECT COUNT(iid) FROM {spam_duplicate} WHERE content_hash = '%s'", $hash)) + 1; if ($duplicate_hash >= variable_get('duplicate_threshold', DUPLICATE_DEFAULT_THRESHOLD)) { - $sids = db_query("SELECT sid FROM spam_duplicate WHERE content_hash = '%s'", $hash); + $sids = db_query("SELECT sid FROM {spam_duplicate} WHERE content_hash = '%s'", $hash); if (!$filter_test) { while ($sid = db_result($sids)) { $unpublish = db_fetch_object(db_query('SELECT content_type, content_id, score FROM {spam_tracker} WHERE sid = %d', $sid)); spam_mark_as_spam($unpublish->content_type, $unpublish->content_id, array('score' => 99)); } // Update counter tracking that we've blocked a duplicate posting of this - // content. (It will actually increment the counter on + // content. (It will actually increment the counter on // "duplicate_threshold" rows.) db_query("UPDATE {spam_duplicate} SET duplicate_hash = duplicate_hash + 1 WHERE content_hash = '%s'", $hash); } @@ -250,7 +242,7 @@ function duplicate_spam_filter($content, return $action; } - $duplicate_ip = db_result(db_query("SELECT COUNT(iid) FROM {spam_duplicate} WHERE hostname = '%s' AND spam = %d", $_SERVER['REMOTE_ADDR'], DUPLICATE_SPAM)); + $duplicate_ip = db_result(db_query("SELECT COUNT(iid) FROM {spam_duplicate} WHERE hostname = '%s' AND spam = %d", ip_address(), DUPLICATE_SPAM)); if ($duplicate_ip >= variable_get('duplicate_blacklist', DUPLICATE_DEFAULT_BLACKLIST)) { $action['ip'] = array( 'score' => 99, @@ -263,21 +255,18 @@ function duplicate_spam_filter($content, return $action; } -/** +/** * */ function duplicate_denied_ip() { - $message = strtr(variable_get('duplicate_blacklist_message', t('

You are currently not allowed to post content to @site, as previous content posted by your IP address (%IP) has been flagged as potential spam.

If you have not posted spam to @site, please report this error along with your IP address to a site administrator. We apologize for any inconvenience.

')), array('@site' => variable_get('site_name', 'Drupal'), '%IP' => $_SERVER['REMOTE_ADDR'])); + $message = strtr(variable_get('duplicate_blacklist_message', t('

You are currently not allowed to post content to @site, as previous content posted by your IP address (%IP) has been flagged as potential spam.

If you have not posted spam to @site, please report this error along with your IP address to a site administrator. We apologize for any inconvenience.

')), array('@site' => variable_get('site_name', 'Drupal'), '%IP' => ip_address())); spam_denied_page($message, t('Your IP address has been blocked by our spam filter.')); } -/** +/** * */ function duplicate_denied_post() { - $message = strtr(variable_get('duplicate_post_message', t('

You have attempted to post the same identical content multiple times, causing your posts to be flagged as potential spam. If this has happened in error, please report this error along with your IP address (%IP) to a @site site administrator. We apologize for any inconvenience.

')), array('@site' => variable_get('site_name', 'Drupal'), '%IP' => $_SERVER['REMOTE_ADDR'])); + $message = strtr(variable_get('duplicate_post_message', t('

You have attempted to post the same identical content multiple times, causing your posts to be flagged as potential spam. If this has happened in error, please report this error along with your IP address (%IP) to a @site site administrator. We apologize for any inconvenience.

')), array('@site' => variable_get('site_name', 'Drupal'), '%IP' => ip_address())); spam_denied_page($message, t('You have attempted to post the same content multiple times.')); -} - - -?> +} \ No newline at end of file Index: modules/spam_comment.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/spam/modules/Attic/spam_comment.inc,v retrieving revision 1.1.2.1.2.3 diff -u -p -r1.1.2.1.2.3 spam_comment.inc --- modules/spam_comment.inc 2 Dec 2007 22:30:12 -0000 1.1.2.1.2.3 +++ modules/spam_comment.inc 20 Feb 2008 00:04:14 -0000 @@ -1,4 +1,5 @@