Merge lp:~yoboy-leguesh/ubuntu-party/upgrade-wp3.0.4 into lp:ubuntu-party

Proposed by YoBoY
Status: Merged
Approved by: YoBoY
Approved revision: 3
Merged at revision: 2
Proposed branch: lp:~yoboy-leguesh/ubuntu-party/upgrade-wp3.0.4
Merge into: lp:ubuntu-party
Diff against target: 3609 lines (+1875/-1231)
22 files modified
wp-admin/includes/file.php (+1/-1)
wp-admin/includes/plugin.php (+1/-1)
wp-admin/includes/update-core.php (+1/-1)
wp-admin/plugins.php (+3/-3)
wp-config-sample.php (+99/-90)
wp-content/plugins/akismet/admin.php (+746/-0)
wp-content/plugins/akismet/akismet.css (+7/-0)
wp-content/plugins/akismet/akismet.js (+10/-0)
wp-content/plugins/akismet/akismet.php (+370/-1050)
wp-content/plugins/akismet/legacy.php (+396/-0)
wp-content/plugins/akismet/readme.txt (+67/-9)
wp-content/plugins/akismet/widget.php (+90/-0)
wp-includes/canonical.php (+7/-5)
wp-includes/capabilities.php (+5/-8)
wp-includes/comment.php (+4/-14)
wp-includes/formatting.php (+2/-1)
wp-includes/functions.php (+1/-1)
wp-includes/kses.php (+12/-27)
wp-includes/load.php (+1/-1)
wp-includes/ms-files.php (+2/-2)
wp-includes/version.php (+1/-1)
xmlrpc.php (+49/-16)
To merge this branch: bzr merge lp:~yoboy-leguesh/ubuntu-party/upgrade-wp3.0.4
Reviewer Review Type Date Requested Status
Ubuntu Party WebApps Developpers Pending
Review via email: mp+47409@code.launchpad.net

Description of the change

Mise à jour vers wordpress 3.0.4
Mise à jour du plugin akismet

To post a comment you must log in.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'wp-admin/includes/file.php'
2--- wp-admin/includes/file.php 2011-01-25 15:27:25 +0000
3+++ wp-admin/includes/file.php 2011-01-25 16:02:14 +0000
4@@ -937,7 +937,7 @@
5 $error_string = __('<strong>Error:</strong> There was an error connecting to the server, Please verify the settings are correct.');
6 if ( is_wp_error($error) )
7 $error_string = $error->get_error_message();
8- echo '<div id="message" class="error"><p>' . $error_string . '</p></div>';
9+ echo '<div id="message" class="error"><p>' . esc_html( $error_string ) . '</p></div>';
10 }
11
12 $types = array();
13
14=== modified file 'wp-admin/includes/plugin.php'
15--- wp-admin/includes/plugin.php 2011-01-25 15:27:25 +0000
16+++ wp-admin/includes/plugin.php 2011-01-25 16:02:14 +0000
17@@ -483,6 +483,7 @@
18 ob_start();
19 include(WP_PLUGIN_DIR . '/' . $plugin);
20 do_action( 'activate_plugin', trim( $plugin) );
21+ do_action( 'activate_' . trim( $plugin ) );
22 if ( $network_wide ) {
23 $current[$plugin] = time();
24 update_site_option( 'active_sitewide_plugins', $current );
25@@ -491,7 +492,6 @@
26 sort($current);
27 update_option('active_plugins', $current);
28 }
29- do_action( 'activate_' . trim( $plugin ) );
30 do_action( 'activated_plugin', trim( $plugin) );
31 if ( ob_get_length() > 0 ) {
32 $output = ob_get_clean();
33
34=== modified file 'wp-admin/includes/update-core.php'
35--- wp-admin/includes/update-core.php 2011-01-25 15:27:25 +0000
36+++ wp-admin/includes/update-core.php 2011-01-25 16:02:14 +0000
37@@ -274,7 +274,7 @@
38 $mysql_version = $wpdb->db_version();
39 $required_php_version = '4.3';
40 $required_mysql_version = '4.1.2';
41- $wp_version = '3.0.1';
42+ $wp_version = '3.0.4';
43 $php_compat = version_compare( $php_version, $required_php_version, '>=' );
44 $mysql_compat = version_compare( $mysql_version, $required_mysql_version, '>=' ) || file_exists( WP_CONTENT_DIR . '/db.php' );
45
46
47=== modified file 'wp-admin/plugins.php'
48--- wp-admin/plugins.php 2011-01-25 15:27:25 +0000
49+++ wp-admin/plugins.php 2011-01-25 16:02:14 +0000
50@@ -255,11 +255,11 @@
51 foreach ( $plugin_info as $plugin ) {
52 if ( $plugin['is_uninstallable'] ) {
53 /* translators: 1: plugin name, 2: plugin author */
54- echo '<li>', sprintf( __( '<strong>%1$s</strong> by <em>%2$s</em> (will also <strong>delete its data</strong>)' ), $plugin['Name'], $plugin['Author'] ), '</li>';
55+ echo '<li>', sprintf( __( '<strong>%1$s</strong> by <em>%2$s</em> (will also <strong>delete its data</strong>)' ), esc_html($plugin['Name']), esc_html($plugin['Author']) ), '</li>';
56 $data_to_delete = true;
57 } else {
58 /* translators: 1: plugin name, 2: plugin author */
59- echo '<li>', sprintf( __('<strong>%1$s</strong> by <em>%2$s</em>' ), $plugin['Name'], $plugin['Author'] ), '</li>';
60+ echo '<li>', sprintf( __('<strong>%1$s</strong> by <em>%2$s</em>' ), esc_html($plugin['Name']), esc_html($plugin['Author']) ), '</li>';
61 }
62 }
63 ?>
64@@ -289,7 +289,7 @@
65 <ul class="code">
66 <?php
67 foreach ( (array)$files_to_delete as $file )
68- echo '<li>' . str_replace(WP_PLUGIN_DIR, '', $file) . '</li>';
69+ echo '<li>' . esc_html(str_replace(WP_PLUGIN_DIR, '', $file)) . '</li>';
70 ?>
71 </ul>
72 </div>
73
74=== modified file 'wp-config-sample.php'
75--- wp-config-sample.php 2011-01-25 15:27:25 +0000
76+++ wp-config-sample.php 2011-01-25 16:02:14 +0000
77@@ -1,90 +1,99 @@
78-<?php
79-/**
80- * The base configurations of the WordPress.
81- *
82- * This file has the following configurations: MySQL settings, Table Prefix,
83- * Secret Keys, WordPress Language, and ABSPATH. You can find more information
84- * by visiting {@link http://codex.wordpress.org/Editing_wp-config.php Editing
85- * wp-config.php} Codex page. You can get the MySQL settings from your web host.
86- *
87- * This file is used by the wp-config.php creation script during the
88- * installation. You don't have to use the web site, you can just copy this file
89- * to "wp-config.php" and fill in the values.
90- *
91- * @package WordPress
92- */
93-
94-// ** MySQL settings - You can get this info from your web host ** //
95-/** The name of the database for WordPress */
96-define('DB_NAME', 'database_name_here');
97-
98-/** MySQL database username */
99-define('DB_USER', 'username_here');
100-
101-/** MySQL database password */
102-define('DB_PASSWORD', 'password_here');
103-
104-/** MySQL hostname */
105-define('DB_HOST', 'localhost');
106-
107-/** Database Charset to use in creating database tables. */
108-define('DB_CHARSET', 'utf8');
109-
110-/** The Database Collate type. Don't change this if in doubt. */
111-define('DB_COLLATE', '');
112-
113-/**#@+
114- * Authentication Unique Keys and Salts.
115- *
116- * Change these to different unique phrases!
117- * You can generate these using the {@link https://api.wordpress.org/secret-key/1.1/salt/ WordPress.org secret-key service}
118- * You can change these at any point in time to invalidate all existing cookies. This will force all users to have to log in again.
119- *
120- * @since 2.6.0
121- */
122-define('AUTH_KEY', 'put your unique phrase here');
123-define('SECURE_AUTH_KEY', 'put your unique phrase here');
124-define('LOGGED_IN_KEY', 'put your unique phrase here');
125-define('NONCE_KEY', 'put your unique phrase here');
126-define('AUTH_SALT', 'put your unique phrase here');
127-define('SECURE_AUTH_SALT', 'put your unique phrase here');
128-define('LOGGED_IN_SALT', 'put your unique phrase here');
129-define('NONCE_SALT', 'put your unique phrase here');
130-
131-/**#@-*/
132-
133-/**
134- * WordPress Database Table prefix.
135- *
136- * You can have multiple installations in one database if you give each a unique
137- * prefix. Only numbers, letters, and underscores please!
138- */
139-$table_prefix = 'wp_';
140-
141-/**
142- * WordPress Localized Language, defaults to English.
143- *
144- * Change this to localize WordPress. A corresponding MO file for the chosen
145- * language must be installed to wp-content/languages. For example, install
146- * de.mo to wp-content/languages and set WPLANG to 'de' to enable German
147- * language support.
148- */
149-define ('WPLANG', 'fr_FR');
150-
151-/**
152- * For developers: WordPress debugging mode.
153- *
154- * Change this to true to enable the display of notices during development.
155- * It is strongly recommended that plugin and theme developers use WP_DEBUG
156- * in their development environments.
157- */
158-define('WP_DEBUG', false);
159-
160-/* That's all, stop editing! Happy blogging. */
161-
162-/** Absolute path to the WordPress directory. */
163-if ( !defined('ABSPATH') )
164- define('ABSPATH', dirname(__FILE__) . '/');
165-
166-/** Sets up WordPress vars and included files. */
167-require_once(ABSPATH . 'wp-settings.php');
168+<?php
169+/**
170+ * La configuration de base de votre installation WordPress.
171+ *
172+ * Ce fichier contient les réglages de configuration suivants : réglages MySQL,
173+ * préfixe de table, clefs secrètes, langue utilisée, et ABSPATH.
174+ * Vous pouvez en savoir plus à leur sujet en allant sur
175+ * {@link http://codex.wordpress.org/Editing_wp-config.php Modifier
176+ * wp-config.php} (en anglais). C'est votre hébergeur qui doit vous donner vos
177+ * codes MySQL.
178+ *
179+ * Ce fichier est utilisé par le script de création de wp-config.php pendant
180+ * le processus d'installation. Vous n'avez pas à utiliser le site web, vous
181+ * pouvez simplement renommer ce fichier en "wp-config.php" et remplir les
182+ * valeurs.
183+ *
184+ * @package WordPress
185+ */
186+
187+// ** Réglages MySQL - Votre hébergeur doit vous fournir ces informations. ** //
188+/** Nom de la base de données de WordPress. */
189+define('DB_NAME', 'votre_nom_de_bdd');
190+
191+/** Utilisateur de la base de données MySQL. */
192+define('DB_USER', 'votre_utilisateur_de_bdd');
193+
194+/** Mot de passe de la base de données MySQL. */
195+define('DB_PASSWORD', 'votre_mdp_de_bdd');
196+
197+/** Adresse de l'hébergement MySQL. */
198+define('DB_HOST', 'localhost');
199+
200+/** Jeu de caractères à utiliser par la base de données lors de la création des tables. */
201+define('DB_CHARSET', 'utf8');
202+
203+/** Type de collation de la base de données.
204+ * N'y touchez que si vous savez ce que vous faites.
205+ */
206+define('DB_COLLATE', '');
207+
208+/**#@+
209+ * Clefs uniques d'authentification et salage.
210+ *
211+ * Remplacez les valeurs par défaut par des phrases uniques !
212+ * Vous pouvez générer des phrases aléatoires en utilisant
213+ * {@link https://api.wordpress.org/secret-key/1.1/salt/ le service de clefs secrètes de WordPress.org}.
214+ * Vous pouvez modifier ces phrases à n'importe quel moment, afin d'invalider tous les cookies existants.
215+ * Cela forcera également tous les utilisateurs à se reconnecter.
216+ *
217+ * @since 2.6.0
218+ */
219+define('AUTH_KEY', 'put your unique phrase here');
220+define('SECURE_AUTH_KEY', 'put your unique phrase here');
221+define('LOGGED_IN_KEY', 'put your unique phrase here');
222+define('NONCE_KEY', 'put your unique phrase here');
223+define('AUTH_SALT', 'put your unique phrase here');
224+define('SECURE_AUTH_SALT', 'put your unique phrase here');
225+define('LOGGED_IN_SALT', 'put your unique phrase here');
226+define('NONCE_SALT', 'put your unique phrase here');
227+/**#@-*/
228+
229+/**
230+ * Préfixe de base de données pour les tables de WordPress.
231+ *
232+ * Vous pouvez installer plusieurs WordPress sur une seule base de données
233+ * si vous leur donnez chacune un préfixe unique.
234+ * N'utilisez que des chiffres, des lettres non-accentuées, et des caractères soulignés!
235+ */
236+$table_prefix = 'wp_';
237+
238+/**
239+ * Langue de localisation de WordPress, par défaut en Anglais.
240+ *
241+ * Modifiez cette valeur pour localiser WordPress. Un fichier MO correspondant
242+ * au langage choisi doit être installé dans le dossier wp-content/languages.
243+ * Par exemple, pour mettre en place une traduction française, mettez le fichier
244+ * fr_FR.mo dans wp-content/languages, et réglez l'option ci-dessous à "fr_FR".
245+ */
246+define ('WPLANG', 'fr_FR');
247+
248+/**
249+ * Pour les développeurs : le mode deboguage de WordPress.
250+ *
251+ * En passant la valeur suivante à "true", vous activez l'affichage des
252+ * notifications d'erreurs pendant votre essais.
253+ * Il est fortemment recommandé que les développeurs d'extensions et
254+ * de thèmes se servent de WP_DEBUG dans leur environnement de
255+ * développement.
256+ */
257+define('WP_DEBUG', false);
258+
259+/* C'est tout, ne touchez pas à ce qui suit ! Bon blogging ! */
260+
261+/** Chemin absolu vers le dossier de WordPress. */
262+if ( !defined('ABSPATH') )
263+ define('ABSPATH', dirname(__FILE__) . '/');
264+
265+/** Réglage des variables de WordPress et de ses fichiers inclus. */
266+require_once(ABSPATH . 'wp-settings.php');
267\ No newline at end of file
268
269=== added file 'wp-content/plugins/akismet/admin.php'
270--- wp-content/plugins/akismet/admin.php 1970-01-01 00:00:00 +0000
271+++ wp-content/plugins/akismet/admin.php 2011-01-25 16:02:14 +0000
272@@ -0,0 +1,746 @@
273+<?php
274+add_action( 'admin_menu', 'akismet_config_page' );
275+add_action( 'admin_menu', 'akismet_stats_page' );
276+akismet_admin_warnings();
277+
278+function akismet_admin_init() {
279+ global $wp_version;
280+
281+ // all admin functions are disabled in old versions
282+ if ( !function_exists('is_multisite') && version_compare( $wp_version, '3.0', '<' ) ) {
283+
284+ function akismet_version_warning() {
285+ echo "
286+ <div id='akismet-warning' class='updated fade'><p><strong>".sprintf(__('Akismet %s requires WordPress 3.0 or higher.'), AKISMET_VERSION) ."</strong> ".sprintf(__('Please <a href="%s">upgrade WordPress</a> to a current version, or <a href="%s">downgrade to version 2.4 of the Akismet plugin</a>.'), 'http://codex.wordpress.org/Upgrading_WordPress', 'http://wordpress.org/extend/plugins/akismet/download/'). "</p></div>
287+ ";
288+ }
289+ add_action('admin_notices', 'akismet_version_warning');
290+
291+ return;
292+ }
293+
294+ if ( function_exists( 'get_plugin_page_hook' ) )
295+ $hook = get_plugin_page_hook( 'akismet-stats-display', 'index.php' );
296+ else
297+ $hook = 'dashboard_page_akismet-stats-display';
298+ add_action('admin_head-'.$hook, 'akismet_stats_script');
299+ add_meta_box('akismet-status', __('Comment History'), 'akismet_comment_status_meta_box', 'comment', 'normal');
300+ wp_register_style('akismet.css', AKISMET_PLUGIN_URL . 'akismet.css');
301+ wp_enqueue_style('akismet.css');
302+ wp_register_script('akismet.js', AKISMET_PLUGIN_URL . 'akismet.js', array('jquery'));
303+ wp_enqueue_script('akismet.js');
304+}
305+add_action('admin_init', 'akismet_admin_init');
306+
307+function akismet_nonce_field($action = -1) { return wp_nonce_field($action); }
308+$akismet_nonce = 'akismet-update-key';
309+
310+function akismet_config_page() {
311+ if ( function_exists('add_submenu_page') )
312+ add_submenu_page('plugins.php', __('Akismet Configuration'), __('Akismet Configuration'), 'manage_options', 'akismet-key-config', 'akismet_conf');
313+}
314+
315+function akismet_plugin_action_links( $links, $file ) {
316+ if ( $file == plugin_basename( dirname(__FILE__).'/akismet.php' ) ) {
317+ $links[] = '<a href="plugins.php?page=akismet-key-config">'.__('Settings').'</a>';
318+ }
319+
320+ return $links;
321+}
322+
323+add_filter( 'plugin_action_links', 'akismet_plugin_action_links', 10, 2 );
324+
325+function akismet_conf() {
326+ global $akismet_nonce, $wpcom_api_key;
327+
328+ if ( isset($_POST['submit']) ) {
329+ if ( function_exists('current_user_can') && !current_user_can('manage_options') )
330+ die(__('Cheatin&#8217; uh?'));
331+
332+ check_admin_referer( $akismet_nonce );
333+ $key = preg_replace( '/[^a-h0-9]/i', '', $_POST['key'] );
334+ $home_url = parse_url( get_bloginfo('url') );
335+
336+ if ( empty($key) ) {
337+ $key_status = 'empty';
338+ $ms[] = 'new_key_empty';
339+ delete_option('wordpress_api_key');
340+ } elseif ( empty($home_url['host']) ) {
341+ $key_status = 'empty';
342+ $ms[] = 'bad_home_url';
343+ } else {
344+ $key_status = akismet_verify_key( $key );
345+ }
346+
347+ if ( $key_status == 'valid' ) {
348+ update_option('wordpress_api_key', $key);
349+ $ms[] = 'new_key_valid';
350+ } else if ( $key_status == 'invalid' ) {
351+ $ms[] = 'new_key_invalid';
352+ } else if ( $key_status == 'failed' ) {
353+ $ms[] = 'new_key_failed';
354+ }
355+
356+ if ( isset( $_POST['akismet_discard_month'] ) )
357+ update_option( 'akismet_discard_month', 'true' );
358+ else
359+ update_option( 'akismet_discard_month', 'false' );
360+
361+ if ( isset( $_POST['akismet_show_user_comments_approved'] ) )
362+ update_option( 'akismet_show_user_comments_approved', 'true' );
363+ else
364+ update_option( 'akismet_show_user_comments_approved', 'false' );
365+
366+ } elseif ( isset($_POST['check']) ) {
367+ akismet_get_server_connectivity(0);
368+ }
369+
370+ if ( empty( $key_status) || $key_status != 'valid' ) {
371+ $key = get_option('wordpress_api_key');
372+ if ( empty( $key ) ) {
373+ if ( empty( $key_status ) || $key_status != 'failed' ) {
374+ if ( akismet_verify_key( '1234567890ab' ) == 'failed' )
375+ $ms[] = 'no_connection';
376+ else
377+ $ms[] = 'key_empty';
378+ }
379+ $key_status = 'empty';
380+ } else {
381+ $key_status = akismet_verify_key( $key );
382+ }
383+ if ( $key_status == 'valid' ) {
384+ $ms[] = 'key_valid';
385+ } else if ( $key_status == 'invalid' ) {
386+ delete_option('wordpress_api_key');
387+ $ms[] = 'key_empty';
388+ } else if ( !empty($key) && $key_status == 'failed' ) {
389+ $ms[] = 'key_failed';
390+ }
391+ }
392+
393+ $messages = array(
394+ 'new_key_empty' => array('color' => 'aa0', 'text' => __('Your key has been cleared.')),
395+ 'new_key_valid' => array('color' => '4AB915', 'text' => __('Your key has been verified. Happy blogging!')),
396+ 'new_key_invalid' => array('color' => '888', 'text' => __('The key you entered is invalid. Please double-check it.')),
397+ 'new_key_failed' => array('color' => '888', 'text' => __('The key you entered could not be verified because a connection to akismet.com could not be established. Please check your server configuration.')),
398+ 'no_connection' => array('color' => '888', 'text' => __('There was a problem connecting to the Akismet server. Please check your server configuration.')),
399+ 'key_empty' => array('color' => 'aa0', 'text' => sprintf(__('Please enter an API key. (<a href="%s" style="color:#fff">Get your key.</a>)'), 'http://akismet.com/get/')),
400+ 'key_valid' => array('color' => '4AB915', 'text' => __('This key is valid.')),
401+ 'key_failed' => array('color' => 'aa0', 'text' => __('The key below was previously validated but a connection to akismet.com can not be established at this time. Please check your server configuration.')),
402+ 'bad_home_url' => array('color' => '888', 'text' => sprintf( __('Your WordPress home URL %s is invalid. Please fix the <a href="%s">home option</a>.'), esc_html( get_bloginfo('url') ), admin_url('options.php#home') ) ),
403+ );
404+?>
405+<?php if ( !empty($_POST['submit'] ) ) : ?>
406+<div id="message" class="updated fade"><p><strong><?php _e('Options saved.') ?></strong></p></div>
407+<?php endif; ?>
408+<div class="wrap">
409+<h2><?php _e('Akismet Configuration'); ?></h2>
410+<?php if (isset($_GET['message']) && $_GET['message'] == 'success') { ?>
411+ <div class="updated below-h2" id="message"><p><?php _e( '<strong>Sign up success!</strong> Please check your email for your Akismet API Key and enter it below.' ); ?></p></div>
412+<?php } ?>
413+<div class="narrow">
414+<form action="" method="post" id="akismet-conf" style="margin: auto; width: 400px; ">
415+<?php if ( !$wpcom_api_key ) { ?>
416+ <p><?php printf(__('For many people, <a href="%1$s">Akismet</a> will greatly reduce or even completely eliminate the comment and trackback spam you get on your site. If one does happen to get through, simply mark it as "spam" on the moderation screen and Akismet will learn from the mistakes. If you don\'t have an API key yet, you can get one at <a href="%2$s">Akismet.com</a>.'), 'http://akismet.com/', 'http://akismet.com/get/'); ?></p>
417+
418+<h3><label for="key"><?php _e('Akismet API Key'); ?></label></h3>
419+<?php foreach ( $ms as $m ) : ?>
420+ <p style="padding: .5em; background-color: #<?php echo $messages[$m]['color']; ?>; color: #fff; font-weight: bold;"><?php echo $messages[$m]['text']; ?></p>
421+<?php endforeach; ?>
422+<p><input id="key" name="key" type="text" size="15" maxlength="12" value="<?php echo get_option('wordpress_api_key'); ?>" style="font-family: 'Courier New', Courier, mono; font-size: 1.5em;" /> (<?php _e('<a href="http://akismet.com/get/">What is this?</a>'); ?>)</p>
423+<?php if ( isset( $invalid_key) && $invalid_key ) { ?>
424+<h3><?php _e('Why might my key be invalid?'); ?></h3>
425+<p><?php _e('This can mean one of two things, either you copied the key wrong or that the plugin is unable to reach the Akismet servers, which is most often caused by an issue with your web host around firewalls or similar.'); ?></p>
426+<?php } ?>
427+<?php } ?>
428+<?php akismet_nonce_field($akismet_nonce) ?>
429+<p><label><input name="akismet_discard_month" id="akismet_discard_month" value="true" type="checkbox" <?php if ( get_option('akismet_discard_month') == 'true' ) echo ' checked="checked" '; ?> /> <?php _e('Auto-delete spam submitted on posts more than a month old.'); ?></label></p>
430+<p><label><input name="akismet_show_user_comments_approved" id="akismet_show_user_comments_approved" value="true" type="checkbox" <?php if ( get_option('akismet_show_user_comments_approved') == 'true' ) echo ' checked="checked" '; ?> /> <?php _e('Show the number of comments you\'ve approved beside each comment author.'); ?></label></p>
431+ <p class="submit"><input type="submit" name="submit" value="<?php _e('Update options &raquo;'); ?>" /></p>
432+</form>
433+
434+<form action="" method="post" id="akismet-connectivity" style="margin: auto; width: 400px; ">
435+
436+<h3><?php _e('Server Connectivity'); ?></h3>
437+<?php
438+ if ( !function_exists('fsockopen') || !function_exists('gethostbynamel') ) {
439+ ?>
440+ <p style="padding: .5em; background-color: #888; color: #fff; font-weight:bold;"><?php _e('Network functions are disabled.'); ?></p>
441+ <p><?php echo sprintf( __('Your web host or server administrator has disabled PHP\'s <code>fsockopen</code> or <code>gethostbynamel</code> functions. <strong>Akismet cannot work correctly until this is fixed.</strong> Please contact your web host or firewall administrator and give them <a href="%s" target="_blank">this information about Akismet\'s system requirements</a>.'), 'http://blog.akismet.com/akismet-hosting-faq/'); ?></p>
442+ <?php
443+ } else {
444+ $servers = akismet_get_server_connectivity();
445+ $fail_count = count($servers) - count( array_filter($servers) );
446+ if ( is_array($servers) && count($servers) > 0 ) {
447+ // some connections work, some fail
448+ if ( $fail_count > 0 && $fail_count < count($servers) ) { ?>
449+ <p style="padding: .5em; background-color: #aa0; color: #fff; font-weight:bold;"><?php _e('Unable to reach some Akismet servers.'); ?></p>
450+ <p><?php echo sprintf( __('A network problem or firewall is blocking some connections from your web server to Akismet.com. Akismet is working but this may cause problems during times of network congestion. Please contact your web host or firewall administrator and give them <a href="%s" target="_blank">this information about Akismet and firewalls</a>.'), 'http://blog.akismet.com/akismet-hosting-faq/'); ?></p>
451+ <?php
452+ // all connections fail
453+ } elseif ( $fail_count > 0 ) { ?>
454+ <p style="padding: .5em; background-color: #888; color: #fff; font-weight:bold;"><?php _e('Unable to reach any Akismet servers.'); ?></p>
455+ <p><?php echo sprintf( __('A network problem or firewall is blocking all connections from your web server to Akismet.com. <strong>Akismet cannot work correctly until this is fixed.</strong> Please contact your web host or firewall administrator and give them <a href="%s" target="_blank">this information about Akismet and firewalls</a>.'), 'http://blog.akismet.com/akismet-hosting-faq/'); ?></p>
456+ <?php
457+ // all connections work
458+ } else { ?>
459+ <p style="padding: .5em; background-color: #4AB915; color: #fff; font-weight:bold;"><?php _e('All Akismet servers are available.'); ?></p>
460+ <p><?php _e('Akismet is working correctly. All servers are accessible.'); ?></p>
461+ <?php
462+ }
463+ } else {
464+ ?>
465+ <p style="padding: .5em; background-color: #888; color: #fff; font-weight:bold;"><?php _e('Unable to find Akismet servers.'); ?></p>
466+ <p><?php echo sprintf( __('A DNS problem or firewall is preventing all access from your web server to Akismet.com. <strong>Akismet cannot work correctly until this is fixed.</strong> Please contact your web host or firewall administrator and give them <a href="%s" target="_blank">this information about Akismet and firewalls</a>.'), 'http://blog.akismet.com/akismet-hosting-faq/'); ?></p>
467+ <?php
468+ }
469+ }
470+
471+ if ( !empty($servers) ) {
472+?>
473+<table style="width: 100%;">
474+<thead><th><?php _e('Akismet server'); ?></th><th><?php _e('Network Status'); ?></th></thead>
475+<tbody>
476+<?php
477+ asort($servers);
478+ foreach ( $servers as $ip => $status ) {
479+ $color = ( $status ? '#4AB915' : '#888');
480+ ?>
481+ <tr>
482+ <td><?php echo htmlspecialchars($ip); ?></td>
483+ <td style="padding: 0 .5em; font-weight:bold; color: #fff; background-color: <?php echo $color; ?>"><?php echo ($status ? __('Accessible') : __('Re-trying') ); ?></td>
484+
485+ <?php
486+ }
487+ }
488+?>
489+</tbody>
490+</table>
491+ <p><?php if ( get_option('akismet_connectivity_time') ) echo sprintf( __('Last checked %s ago.'), human_time_diff( get_option('akismet_connectivity_time') ) ); ?></p>
492+ <p class="submit"><input type="submit" name="check" value="<?php _e('Check network status &raquo;'); ?>" /></p>
493+ <p><?php printf( __('<a href="%s" target="_blank">Click here</a> to confirm that <a href="%s" target="_blank">Akismet.com is up</a>.'), 'http://status.automattic.com/9931/136079/Akismet-API', 'http://status.automattic.com/9931/136079/Akismet-API' ); ?></p>
494+</form>
495+
496+</div>
497+</div>
498+<?php
499+}
500+
501+function akismet_stats_page() {
502+ if ( function_exists('add_submenu_page') )
503+ add_submenu_page('index.php', __('Akismet Stats'), __('Akismet Stats'), 'manage_options', 'akismet-stats-display', 'akismet_stats_display');
504+
505+}
506+
507+function akismet_stats_script() {
508+ ?>
509+<script type="text/javascript">
510+function resizeIframe() {
511+
512+ document.getElementById('akismet-stats-frame').style.height = "2500px";
513+
514+};
515+function resizeIframeInit() {
516+ document.getElementById('akismet-stats-frame').onload = resizeIframe;
517+ window.onresize = resizeIframe;
518+}
519+addLoadEvent(resizeIframeInit);
520+</script><?php
521+}
522+
523+
524+function akismet_stats_display() {
525+ global $akismet_api_host, $akismet_api_port, $wpcom_api_key;
526+ $blog = urlencode( get_bloginfo('url') );
527+
528+ $url = 'http://';
529+ if ( is_ssl() )
530+ $url = 'https://';
531+
532+ $url .= 'akismet.com/web/1.0/user-stats.php';
533+ $url .= "?blog={$blog}&api_key=" . akismet_get_key();
534+ ?>
535+ <div class="wrap">
536+ <iframe src="<?php echo $url; ?>" width="100%" height="100%" frameborder="0" id="akismet-stats-frame"></iframe>
537+ </div>
538+ <?php
539+}
540+
541+function akismet_stats() {
542+ if ( !function_exists('did_action') || did_action( 'rightnow_end' ) ) // We already displayed this info in the "Right Now" section
543+ return;
544+ if ( !$count = get_option('akismet_spam_count') )
545+ return;
546+ $path = plugin_basename(__FILE__);
547+ echo '<h3>' . _x( 'Spam', 'comments' ) . '</h3>';
548+ global $submenu;
549+ if ( isset( $submenu['edit-comments.php'] ) )
550+ $link = 'edit-comments.php';
551+ else
552+ $link = 'edit.php';
553+ echo '<p>'.sprintf( _n( '<a href="%1$s">Akismet</a> has protected your site from <a href="%2$s">%3$s spam comments</a>.', '<a href="%1$s">Akismet</a> has protected your site from <a href="%2$s">%3$s spam comments</a>.', $count ), 'http://akismet.com/', clean_url("$link?page=akismet-admin"), number_format_i18n($count) ).'</p>';
554+}
555+add_action('activity_box_end', 'akismet_stats');
556+
557+function akismet_admin_warnings() {
558+ global $wpcom_api_key;
559+ if ( !get_option('wordpress_api_key') && !$wpcom_api_key && !isset($_POST['submit']) ) {
560+ function akismet_warning() {
561+ echo "
562+ <div id='akismet-warning' class='updated fade'><p><strong>".__('Akismet is almost ready.')."</strong> ".sprintf(__('You must <a href="%1$s">enter your Akismet API key</a> for it to work.'), "plugins.php?page=akismet-key-config")."</p></div>
563+ ";
564+ }
565+ add_action('admin_notices', 'akismet_warning');
566+ return;
567+ } elseif ( ( empty($_SERVER['SCRIPT_FILENAME']) || basename($_SERVER['SCRIPT_FILENAME']) == 'edit-comments.php' ) && wp_next_scheduled('akismet_schedule_cron_recheck') ) {
568+ function akismet_warning() {
569+ global $wpdb;
570+ $waiting = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM $wpdb->commentmeta WHERE meta_key = 'akismet_error'" ) );
571+ $next_check = human_time_diff( wp_next_scheduled('akismet_schedule_cron_recheck') );
572+ if ( $waiting > 0 )
573+ echo "
574+ <div id='akismet-warning' class='updated fade'><p><strong>".__('Akismet has detected a problem.')."</strong> ".sprintf(_n('A server or network problem prevented Akismet from checking %d comment. It has been temporarily held for moderation and will be automatically re-checked in %s.', 'A server or network problem prevented Akismet from checking %d comments. They have been temporarily held for moderation and will be automatically re-checked in %s.', $waiting), number_format_i18n( $waiting ), $next_check)."</p></div>
575+ ";
576+ }
577+ add_action('admin_notices', 'akismet_warning');
578+ return;
579+ }
580+}
581+
582+// FIXME placeholder
583+
584+function akismet_comment_row_action( $a, $comment ) {
585+
586+ // failsafe for old WP versions
587+ if ( !function_exists('add_comment_meta') )
588+ return $a;
589+
590+ $akismet_result = get_comment_meta( $comment->comment_ID, 'akismet_result', true );
591+ $user_result = get_comment_meta( $comment->comment_ID, 'akismet_user_result', true);
592+ $comment_status = wp_get_comment_status( $comment->comment_ID );
593+ $desc = null;
594+ if ( !$user_result || $user_result == $akismet_result ) {
595+ // Show the original Akismet result if the user hasn't overridden it, or if their decision was the same
596+ if ( $akismet_result == 'true' && $comment_status != 'spam' && $comment_status != 'trash' )
597+ $desc = __( 'Flagged as spam by Akismet' );
598+ elseif ( $akismet_result == 'false' && $comment_status == 'spam' )
599+ $desc = __( 'Cleared by Akismet' );
600+ } else {
601+ $who = get_comment_meta( $comment->comment_ID, 'akismet_user', true );
602+ if ( $user_result == 'true' )
603+ $desc = sprintf( __('Flagged as spam by %s'), $who );
604+ else
605+ $desc = sprintf( __('Un-spammed by %s'), $who );
606+ }
607+
608+ // add a History item to the hover links, just after Edit
609+ if ( $akismet_result ) {
610+ $b = array();
611+ foreach ( $a as $k => $item ) {
612+ $b[ $k ] = $item;
613+ if ( $k == 'edit' )
614+ $b['history'] = '<a href="comment.php?action=editcomment&amp;c='.$comment->comment_ID.'#akismet-status" title="'. esc_attr__( 'View comment history' ) . '"> '. __('History') . '</a>';
615+ }
616+
617+ $a = $b;
618+ }
619+
620+ if ( $desc )
621+ echo '<span class="akismet-status" commentid="'.$comment->comment_ID.'"><a href="comment.php?action=editcomment&amp;c='.$comment->comment_ID.'#akismet-status" title="' . esc_attr__( 'View comment history' ) . '">'.htmlspecialchars($desc).'</a></span>';
622+
623+ if ( apply_filters( 'akismet_show_user_comments_approved', get_option('akismet_show_user_comments_approved') ) == 'true' ) {
624+ $comment_count = akismet_get_user_comments_approved( $comment->user_id, $comment->comment_author_email, $comment->comment_author, $comment->comment_author_url );
625+ $comment_count = intval( $comment_count );
626+ echo '<span class="akismet-user-comment-count" commentid="'.$comment->comment_ID.'" style="display:none;"><br><span class="akismet-user-comment-counts">'.sprintf( _n( '%s approved', '%s approved', $comment_count ), number_format_i18n( $comment_count ) ) . '</span></span>';
627+ }
628+
629+ return $a;
630+}
631+
632+add_filter( 'comment_row_actions', 'akismet_comment_row_action', 10, 2 );
633+
634+function akismet_comment_status_meta_box($comment) {
635+ $history = akismet_get_comment_history( $comment->comment_ID );
636+
637+ if ( $history ) {
638+ echo '<div class="akismet-history" style="margin: 13px;">';
639+ foreach ( $history as $row ) {
640+ $time = date( 'D d M Y @ h:i:m a', $row['time'] ) . ' GMT';
641+ echo '<div style="margin-bottom: 13px;"><span style="color: #999;" alt="' . $time . '" title="' . $time . '">' . sprintf( __('%s ago'), human_time_diff( $row['time'] ) ) . '</span> - ';
642+ echo htmlspecialchars( $row['message'] ) . '</div>';
643+ }
644+
645+ echo '</div>';
646+
647+ }
648+}
649+
650+
651+// add an extra column header to the comments screen
652+function akismet_comments_columns( $columns ) {
653+ $columns[ 'akismet' ] = __( 'Akismet' );
654+ return $columns;
655+}
656+
657+#add_filter( 'manage_edit-comments_columns', 'akismet_comments_columns' );
658+
659+// Show stuff in the extra column
660+function akismet_comment_column_row( $column, $comment_id ) {
661+ if ( $column != 'akismet' )
662+ return;
663+
664+ $history = akismet_get_comment_history( $comment_id );
665+
666+ if ( $history ) {
667+ echo '<dl class="akismet-history">';
668+ foreach ( $history as $row ) {
669+ echo '<dt>' . sprintf( __('%s ago'), human_time_diff( $row['time'] ) ) . '</dt>';
670+ echo '<dd>' . htmlspecialchars( $row['message'] ) . '</dd>';
671+ }
672+
673+ echo '</dl>';
674+ }
675+}
676+
677+#add_action( 'manage_comments_custom_column', 'akismet_comment_column_row', 10, 2 );
678+
679+// END FIXME
680+
681+// call out URLS in comments
682+function akismet_text_add_link_callback( $m ) {
683+
684+ // bare link?
685+ if ( $m[4] == $m[2] )
686+ return '<a '.$m[1].' href="'.$m[2].'" '.$m[3].' class="comment-link">'.$m[4].'</a>';
687+ else
688+ return '<span title="'.$m[2].'" class="comment-link"><a '.$m[1].' href="'.$m[2].'" '.$m[3].' class="comment-link">'.$m[4].'</a></span>';
689+}
690+
691+function akismet_text_add_link_class( $comment_text ) {
692+
693+ return preg_replace_callback( '#<a ([^>]*)href="([^"]+)"([^>]*)>(.*?)</a>#i', 'akismet_text_add_link_callback', $comment_text );
694+}
695+
696+add_filter('comment_text', 'akismet_text_add_link_class');
697+
698+
699+// WP 2.5+
700+function akismet_rightnow() {
701+ global $submenu, $wp_db_version;
702+
703+ // clean_url was deprecated in WP 3.0
704+ $esc_url = 'clean_url';
705+ if ( function_exists( 'esc_url' ) )
706+ $esc_url = 'esc_url';
707+
708+ if ( 8645 < $wp_db_version ) // 2.7
709+ $link = 'edit-comments.php?comment_status=spam';
710+ elseif ( isset( $submenu['edit-comments.php'] ) )
711+ $link = 'edit-comments.php?page=akismet-admin';
712+ else
713+ $link = 'edit.php?page=akismet-admin';
714+
715+ if ( $count = get_option('akismet_spam_count') ) {
716+ $intro = sprintf( _n(
717+ '<a href="%1$s">Akismet</a> has protected your site from %2$s spam comment already. ',
718+ '<a href="%1$s">Akismet</a> has protected your site from %2$s spam comments already. ',
719+ $count
720+ ), 'http://akismet.com/', number_format_i18n( $count ) );
721+ } else {
722+ $intro = sprintf( __('<a href="%1$s">Akismet</a> blocks spam from getting to your blog. '), 'http://akismet.com/' );
723+ }
724+
725+ if ( $queue_count = akismet_spam_count() ) {
726+ $queue_text = sprintf( _n(
727+ 'There\'s <a href="%2$s">%1$s comment</a> in your spam queue right now.',
728+ 'There are <a href="%2$s">%1$s comments</a> in your spam queue right now.',
729+ $queue_count
730+ ), number_format_i18n( $queue_count ), $esc_url($link) );
731+ } else {
732+ $queue_text = sprintf( __( "There's nothing in your <a href='%1\$s'>spam queue</a> at the moment." ), $esc_url($link) );
733+ }
734+
735+ $text = $intro . '<br />' . $queue_text;
736+ echo "<p class='akismet-right-now'>$text</p>\n";
737+}
738+
739+add_action('rightnow_end', 'akismet_rightnow');
740+
741+
742+// For WP >= 2.5
743+function akismet_check_for_spam_button($comment_status) {
744+ if ( 'approved' == $comment_status )
745+ return;
746+ if ( function_exists('plugins_url') )
747+ $link = 'admin.php?action=akismet_recheck_queue';
748+ else
749+ $link = 'edit-comments.php?page=akismet-admin&amp;recheckqueue=true&amp;noheader=true';
750+ echo "</div><div class='alignleft'><a class='button-secondary checkforspam' href='$link'>" . __('Check for Spam') . "</a>";
751+}
752+add_action('manage_comments_nav', 'akismet_check_for_spam_button');
753+
754+function akismet_submit_nonspam_comment ( $comment_id ) {
755+ global $wpdb, $akismet_api_host, $akismet_api_port, $current_user, $current_site;
756+ $comment_id = (int) $comment_id;
757+
758+ $comment = $wpdb->get_row("SELECT * FROM $wpdb->comments WHERE comment_ID = '$comment_id'");
759+ if ( !$comment ) // it was deleted
760+ return;
761+
762+ // use the original version stored in comment_meta if available
763+ $as_submitted = get_comment_meta( $comment_id, 'akismet_as_submitted', true);
764+ if ( $as_submitted && is_array($as_submitted) && isset($as_submitted['comment_content']) ) {
765+ $comment = (object) array_merge( (array)$comment, $as_submitted );
766+ }
767+
768+ $comment->blog = get_bloginfo('url');
769+ $comment->blog_lang = get_locale();
770+ $comment->blog_charset = get_option('blog_charset');
771+ $comment->permalink = get_permalink($comment->comment_post_ID);
772+ $comment->reporter_ip = $_SERVER['REMOTE_ADDR'];
773+ if ( is_object($current_user) ) {
774+ $comment->reporter = $current_user->user_login;
775+ }
776+ if ( is_object($current_site) ) {
777+ $comment->site_domain = $current_site->domain;
778+ }
779+
780+ $comment->user_role = '';
781+ if ( isset( $comment->user_ID ) )
782+ $comment->user_role = akismet_get_user_roles($comment->user_ID);
783+
784+ if ( akismet_test_mode() )
785+ $comment->is_test = 'true';
786+
787+ $query_string = '';
788+ foreach ( $comment as $key => $data )
789+ $query_string .= $key . '=' . urlencode( stripslashes($data) ) . '&';
790+
791+ $response = akismet_http_post($query_string, $akismet_api_host, "/1.1/submit-ham", $akismet_api_port);
792+ if ( $comment->reporter ) {
793+ akismet_update_comment_history( $comment_id, sprintf( __('%s reported this comment as not spam'), $comment->reporter ), 'report-ham' );
794+ update_comment_meta( $comment_id, 'akismet_user_result', 'false' );
795+ update_comment_meta( $comment_id, 'akismet_user', $comment->reporter );
796+ }
797+
798+ do_action('akismet_submit_nonspam_comment', $comment_id, $response[1]);
799+}
800+
801+function akismet_submit_spam_comment ( $comment_id ) {
802+ global $wpdb, $akismet_api_host, $akismet_api_port, $current_user, $current_site;
803+ $comment_id = (int) $comment_id;
804+
805+ $comment = $wpdb->get_row("SELECT * FROM $wpdb->comments WHERE comment_ID = '$comment_id'");
806+ if ( !$comment ) // it was deleted
807+ return;
808+ if ( 'spam' != $comment->comment_approved )
809+ return;
810+
811+ // use the original version stored in comment_meta if available
812+ $as_submitted = get_comment_meta( $comment_id, 'akismet_as_submitted', true);
813+ if ( $as_submitted && is_array($as_submitted) && isset($as_submitted['comment_content']) ) {
814+ $comment = (object) array_merge( (array)$comment, $as_submitted );
815+ }
816+
817+ $comment->blog = get_bloginfo('url');
818+ $comment->blog_lang = get_locale();
819+ $comment->blog_charset = get_option('blog_charset');
820+ $comment->permalink = get_permalink($comment->comment_post_ID);
821+ $comment->reporter_ip = $_SERVER['REMOTE_ADDR'];
822+ if ( is_object($current_user) ) {
823+ $comment->reporter = $current_user->user_login;
824+ }
825+ if ( is_object($current_site) ) {
826+ $comment->site_domain = $current_site->domain;
827+ }
828+
829+ $comment->user_role = '';
830+ if ( isset( $comment->user_ID ) )
831+ $comment->user_role = akismet_get_user_roles($comment->user_ID);
832+
833+ if ( akismet_test_mode() )
834+ $comment->is_test = 'true';
835+
836+ $query_string = '';
837+ foreach ( $comment as $key => $data )
838+ $query_string .= $key . '=' . urlencode( stripslashes($data) ) . '&';
839+
840+ $response = akismet_http_post($query_string, $akismet_api_host, "/1.1/submit-spam", $akismet_api_port);
841+ if ( $comment->reporter ) {
842+ akismet_update_comment_history( $comment_id, sprintf( __('%s reported this comment as spam'), $comment->reporter ), 'report-spam' );
843+ update_comment_meta( $comment_id, 'akismet_user_result', 'true' );
844+ update_comment_meta( $comment_id, 'akismet_user', $comment->reporter );
845+ }
846+ do_action('akismet_submit_spam_comment', $comment_id, $response[1]);
847+}
848+
849+// For WP 2.7+
850+function akismet_transition_comment_status( $new_status, $old_status, $comment ) {
851+ if ( $new_status == $old_status )
852+ return;
853+
854+ if ( !is_admin() )
855+ return;
856+
857+ if ( !current_user_can( 'edit_post', $comment->comment_post_ID ) && !current_user_can( 'moderate_comments' ) )
858+ return;
859+
860+ if ( defined('WP_IMPORTING') && WP_IMPORTING == true )
861+ return;
862+
863+ global $current_user;
864+ $reporter = '';
865+ if ( is_object( $current_user ) )
866+ $reporter = $current_user->user_login;
867+
868+ // Assumption alert:
869+ // We want to submit comments to Akismet only when a moderator explicitly spams or approves it - not if the status
870+ // is changed automatically by another plugin. Unfortunately WordPress doesn't provide an unambiguous way to
871+ // determine why the transition_comment_status action was triggered. And there are several different ways by which
872+ // to spam and unspam comments: bulk actions, ajax, links in moderation emails, the dashboard, and perhaps others.
873+ // We'll assume that this is an explicit user action if POST or GET has an 'action' key.
874+ if ( isset($_POST['action']) || isset($_GET['action']) ) {
875+ if ( $new_status == 'spam' && ( $old_status == 'approved' || $old_status == 'unapproved' || !$old_status ) ) {
876+ return akismet_submit_spam_comment( $comment->comment_ID );
877+ } elseif ( $old_status == 'spam' && ( $new_status == 'approved' || $new_status == 'unapproved' ) ) {
878+ return akismet_submit_nonspam_comment( $comment->comment_ID );
879+ }
880+ }
881+
882+ if ( !get_comment_meta( $comment->comment_ID, 'akismet_rechecking' ) )
883+ akismet_update_comment_history( $comment->comment_ID, sprintf( __('%s changed the comment status to %s'), $reporter, $new_status ), 'status-' . $new_status );
884+}
885+
886+add_action( 'transition_comment_status', 'akismet_transition_comment_status', 10, 3 );
887+
888+// Total spam in queue
889+// get_option( 'akismet_spam_count' ) is the total caught ever
890+function akismet_spam_count( $type = false ) {
891+ global $wpdb;
892+
893+ if ( !$type ) { // total
894+ $count = wp_cache_get( 'akismet_spam_count', 'widget' );
895+ if ( false === $count ) {
896+ if ( function_exists('wp_count_comments') ) {
897+ $count = wp_count_comments();
898+ $count = $count->spam;
899+ } else {
900+ $count = (int) $wpdb->get_var("SELECT COUNT(comment_ID) FROM $wpdb->comments WHERE comment_approved = 'spam'");
901+ }
902+ wp_cache_set( 'akismet_spam_count', $count, 'widget', 3600 );
903+ }
904+ return $count;
905+ } elseif ( 'comments' == $type || 'comment' == $type ) { // comments
906+ $type = '';
907+ } else { // pingback, trackback, ...
908+ $type = $wpdb->escape( $type );
909+ }
910+
911+ return (int) $wpdb->get_var("SELECT COUNT(comment_ID) FROM $wpdb->comments WHERE comment_approved = 'spam' AND comment_type='$type'");
912+}
913+
914+
915+function akismet_recheck_queue() {
916+ global $wpdb, $akismet_api_host, $akismet_api_port;
917+
918+ if ( ! ( isset( $_GET['recheckqueue'] ) || ( isset( $_REQUEST['action'] ) && 'akismet_recheck_queue' == $_REQUEST['action'] ) ) )
919+ return;
920+
921+ $moderation = $wpdb->get_results( "SELECT * FROM $wpdb->comments WHERE comment_approved = '0'", ARRAY_A );
922+ foreach ( (array) $moderation as $c ) {
923+ $c['user_ip'] = $c['comment_author_IP'];
924+ $c['user_agent'] = $c['comment_agent'];
925+ $c['referrer'] = '';
926+ $c['blog'] = get_bloginfo('url');
927+ $c['blog_lang'] = get_locale();
928+ $c['blog_charset'] = get_option('blog_charset');
929+ $c['permalink'] = get_permalink($c['comment_post_ID']);
930+
931+ $c['user_role'] = '';
932+ if ( isset( $c['user_ID'] ) )
933+ $c['user_role'] = akismet_get_user_roles($c['user_ID']);
934+
935+ if ( akismet_test_mode() )
936+ $c['is_test'] = 'true';
937+
938+ $id = (int) $c['comment_ID'];
939+
940+ $query_string = '';
941+ foreach ( $c as $key => $data )
942+ $query_string .= $key . '=' . urlencode( stripslashes($data) ) . '&';
943+
944+ $response = akismet_http_post($query_string, $akismet_api_host, '/1.1/comment-check', $akismet_api_port);
945+ if ( 'true' == $response[1] ) {
946+ wp_set_comment_status($c['comment_ID'], 'spam');
947+ update_comment_meta( $c['comment_ID'], 'akismet_result', 'true' );
948+ akismet_update_comment_history( $c['comment_ID'], __('Akismet re-checked and caught this comment as spam'), 'check-spam' );
949+
950+ } elseif ( 'false' == $response[1] ) {
951+ update_comment_meta( $c['comment_ID'], 'akismet_result', 'false' );
952+ akismet_update_comment_history( $c['comment_ID'], __('Akismet re-checked and cleared this comment'), 'check-ham' );
953+ // abnormal result: error
954+ } else {
955+ update_comment_meta( $c['comment_ID'], 'akismet_result', 'error' );
956+ akismet_update_comment_history( $c['comment_ID'], sprintf( __('Akismet was unable to re-check this comment (response: %s)'), $response[1]), 'check-error' );
957+ }
958+
959+ }
960+ wp_redirect( $_SERVER['HTTP_REFERER'] );
961+ exit;
962+}
963+
964+add_action('admin_action_akismet_recheck_queue', 'akismet_recheck_queue');
965+
966+// Check connectivity between the WordPress blog and Akismet's servers.
967+// Returns an associative array of server IP addresses, where the key is the IP address, and value is true (available) or false (unable to connect).
968+function akismet_check_server_connectivity() {
969+ global $akismet_api_host, $akismet_api_port, $wpcom_api_key;
970+
971+ $test_host = 'rest.akismet.com';
972+
973+ // Some web hosts may disable one or both functions
974+ if ( !function_exists('fsockopen') || !function_exists('gethostbynamel') )
975+ return array();
976+
977+ $ips = gethostbynamel($test_host);
978+ if ( !$ips || !is_array($ips) || !count($ips) )
979+ return array();
980+
981+ $servers = array();
982+ foreach ( $ips as $ip ) {
983+ $response = akismet_verify_key( akismet_get_key(), $ip );
984+ // even if the key is invalid, at least we know we have connectivity
985+ if ( $response == 'valid' || $response == 'invalid' )
986+ $servers[$ip] = true;
987+ else
988+ $servers[$ip] = false;
989+ }
990+
991+ return $servers;
992+}
993+
994+// Check the server connectivity and store the results in an option.
995+// Cached results will be used if not older than the specified timeout in seconds; use $cache_timeout = 0 to force an update.
996+// Returns the same associative array as akismet_check_server_connectivity()
997+function akismet_get_server_connectivity( $cache_timeout = 86400 ) {
998+ $servers = get_option('akismet_available_servers');
999+ if ( (time() - get_option('akismet_connectivity_time') < $cache_timeout) && $servers !== false )
1000+ return $servers;
1001+
1002+ // There's a race condition here but the effect is harmless.
1003+ $servers = akismet_check_server_connectivity();
1004+ update_option('akismet_available_servers', $servers);
1005+ update_option('akismet_connectivity_time', time());
1006+ return $servers;
1007+}
1008+
1009+// Returns true if server connectivity was OK at the last check, false if there was a problem that needs to be fixed.
1010+function akismet_server_connectivity_ok() {
1011+ // skip the check on WPMU because the status page is hidden
1012+ global $wpcom_api_key;
1013+ if ( $wpcom_api_key )
1014+ return true;
1015+ $servers = akismet_get_server_connectivity();
1016+ return !( empty($servers) || !count($servers) || count( array_filter($servers) ) < count($servers) );
1017+}
1018+
1019
1020=== added file 'wp-content/plugins/akismet/akismet.css'
1021--- wp-content/plugins/akismet/akismet.css 1970-01-01 00:00:00 +0000
1022+++ wp-content/plugins/akismet/akismet.css 2011-01-25 16:02:14 +0000
1023@@ -0,0 +1,7 @@
1024+#submitted-on { position: relative; }
1025+#the-comment-list .author .akismet-user-comment-count { display: inline; }
1026+#dashboard_recent_comments .akismet-status { display: none; } /* never show the flagged by text on the dashboard */
1027+.akismet-status { float: right; }
1028+.akismet-status a { color: #AAA; font-style: italic; }
1029+span.comment-link a { text-decoration: underline; }
1030+span.comment-link:after { content: " " attr(title) " "; color: #aaa; text-decoration: none; }
1031
1032=== added file 'wp-content/plugins/akismet/akismet.js'
1033--- wp-content/plugins/akismet/akismet.js 1970-01-01 00:00:00 +0000
1034+++ wp-content/plugins/akismet/akismet.js 2011-01-25 16:02:14 +0000
1035@@ -0,0 +1,10 @@
1036+jQuery(document).ready(function () {
1037+ jQuery('.akismet-status').each(function () {
1038+ var thisId = jQuery(this).attr('commentid');
1039+ jQuery(this).prependTo('#comment-' + thisId + ' .column-comment div:first-child');
1040+ });
1041+ jQuery('.akismet-user-comment-count').each(function () {
1042+ var thisId = jQuery(this).attr('commentid');
1043+ jQuery(this).insertAfter('#comment-' + thisId + ' .author strong:first').show();
1044+ });
1045+});
1046
1047=== modified file 'wp-content/plugins/akismet/akismet.php'
1048--- wp-content/plugins/akismet/akismet.php 2011-01-25 15:27:25 +0000
1049+++ wp-content/plugins/akismet/akismet.php 2011-01-25 16:02:14 +0000
1050@@ -1,21 +1,56 @@
1051 <?php
1052+/**
1053+ * @package Akismet
1054+ */
1055 /*
1056 Plugin Name: Akismet
1057 Plugin URI: http://akismet.com/
1058-Description: Akismet checks your comments against the Akismet web service to see if they look like spam or not. You need an <a href="http://akismet.com/get/">API key</a> to use it. You can review the spam it catches under "Comments." To show off your Akismet stats just put <code>&lt;?php akismet_counter(); ?&gt;</code> in your template. See also: <a href="http://wordpress.org/extend/plugins/stats/">WP Stats plugin</a>.
1059-Version: 2.3.0
1060+Description: Used by millions, Akismet is quite possibly the best way in the world to <strong>protect your blog from comment and track-back spam</strong>. It keeps your site protected from spam even while you sleep. To get started: 1) Click the "Activate" link to the left of this description, 2) <a href="http://akismet.com/get/?return=true">Sign up for an Akismet API key</a>, and 3) Go to your <a href="plugins.php?page=akismet-key-config">Akismet configuration</a> page, and save your API key.
1061+Version: 2.5.2
1062 Author: Automattic
1063 Author URI: http://automattic.com/wordpress-plugins/
1064-*/
1065-
1066-define('AKISMET_VERSION', '2.3.0');
1067-
1068-// If you hardcode a WP.com API key here, all key config screens will be hidden
1069+License: GPLv2
1070+*/
1071+
1072+/*
1073+This program is free software; you can redistribute it and/or
1074+modify it under the terms of the GNU General Public License
1075+as published by the Free Software Foundation; either version 2
1076+of the License, or (at your option) any later version.
1077+
1078+This program is distributed in the hope that it will be useful,
1079+but WITHOUT ANY WARRANTY; without even the implied warranty of
1080+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1081+GNU General Public License for more details.
1082+
1083+You should have received a copy of the GNU General Public License
1084+along with this program; if not, write to the Free Software
1085+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
1086+*/
1087+
1088+define('AKISMET_VERSION', '2.5.2');
1089+define('AKISMET_PLUGIN_URL', plugin_dir_url( __FILE__ ));
1090+
1091+/** If you hardcode a WP.com API key here, all key config screens will be hidden */
1092 if ( defined('WPCOM_API_KEY') )
1093 $wpcom_api_key = constant('WPCOM_API_KEY');
1094 else
1095 $wpcom_api_key = '';
1096
1097+// Make sure we don't expose any info if called directly
1098+if ( !function_exists( 'add_action' ) ) {
1099+ echo "Hi there! I'm just a plugin, not much I can do when called directly.";
1100+ exit;
1101+}
1102+
1103+if ( isset($wp_db_version) && $wp_db_version <= 9872 )
1104+ include_once dirname( __FILE__ ) . '/legacy.php';
1105+
1106+include_once dirname( __FILE__ ) . '/widget.php';
1107+
1108+if ( is_admin() )
1109+ require_once dirname( __FILE__ ) . '/admin.php';
1110+
1111 function akismet_init() {
1112 global $wpcom_api_key, $akismet_api_host, $akismet_api_port;
1113
1114@@ -25,235 +60,9 @@
1115 $akismet_api_host = get_option('wordpress_api_key') . '.rest.akismet.com';
1116
1117 $akismet_api_port = 80;
1118- add_action('admin_menu', 'akismet_config_page');
1119- add_action('admin_menu', 'akismet_stats_page');
1120- akismet_admin_warnings();
1121 }
1122 add_action('init', 'akismet_init');
1123
1124-function akismet_admin_init() {
1125- if ( function_exists( 'get_plugin_page_hook' ) )
1126- $hook = get_plugin_page_hook( 'akismet-stats-display', 'index.php' );
1127- else
1128- $hook = 'dashboard_page_akismet-stats-display';
1129- add_action('admin_head-'.$hook, 'akismet_stats_script');
1130-}
1131-add_action('admin_init', 'akismet_admin_init');
1132-
1133-if ( !function_exists('wp_nonce_field') ) {
1134- function akismet_nonce_field($action = -1) { return; }
1135- $akismet_nonce = -1;
1136-} else {
1137- function akismet_nonce_field($action = -1) { return wp_nonce_field($action); }
1138- $akismet_nonce = 'akismet-update-key';
1139-}
1140-
1141-if ( !function_exists('number_format_i18n') ) {
1142- function number_format_i18n( $number, $decimals = null ) { return number_format( $number, $decimals ); }
1143-}
1144-
1145-function akismet_config_page() {
1146- if ( function_exists('add_submenu_page') )
1147- add_submenu_page('plugins.php', __('Akismet Configuration'), __('Akismet Configuration'), 'manage_options', 'akismet-key-config', 'akismet_conf');
1148-
1149-}
1150-
1151-function akismet_conf() {
1152- global $akismet_nonce, $wpcom_api_key;
1153-
1154- if ( isset($_POST['submit']) ) {
1155- if ( function_exists('current_user_can') && !current_user_can('manage_options') )
1156- die(__('Cheatin&#8217; uh?'));
1157-
1158- check_admin_referer( $akismet_nonce );
1159- $key = preg_replace( '/[^a-h0-9]/i', '', $_POST['key'] );
1160-
1161- if ( empty($key) ) {
1162- $key_status = 'empty';
1163- $ms[] = 'new_key_empty';
1164- delete_option('wordpress_api_key');
1165- } else {
1166- $key_status = akismet_verify_key( $key );
1167- }
1168-
1169- if ( $key_status == 'valid' ) {
1170- update_option('wordpress_api_key', $key);
1171- $ms[] = 'new_key_valid';
1172- } else if ( $key_status == 'invalid' ) {
1173- $ms[] = 'new_key_invalid';
1174- } else if ( $key_status == 'failed' ) {
1175- $ms[] = 'new_key_failed';
1176- }
1177-
1178- if ( isset( $_POST['akismet_discard_month'] ) )
1179- update_option( 'akismet_discard_month', 'true' );
1180- else
1181- update_option( 'akismet_discard_month', 'false' );
1182- } elseif ( isset($_POST['check']) ) {
1183- akismet_get_server_connectivity(0);
1184- }
1185-
1186- if ( $key_status != 'valid' ) {
1187- $key = get_option('wordpress_api_key');
1188- if ( empty( $key ) ) {
1189- if ( $key_status != 'failed' ) {
1190- if ( akismet_verify_key( '1234567890ab' ) == 'failed' )
1191- $ms[] = 'no_connection';
1192- else
1193- $ms[] = 'key_empty';
1194- }
1195- $key_status = 'empty';
1196- } else {
1197- $key_status = akismet_verify_key( $key );
1198- }
1199- if ( $key_status == 'valid' ) {
1200- $ms[] = 'key_valid';
1201- } else if ( $key_status == 'invalid' ) {
1202- delete_option('wordpress_api_key');
1203- $ms[] = 'key_empty';
1204- } else if ( !empty($key) && $key_status == 'failed' ) {
1205- $ms[] = 'key_failed';
1206- }
1207- }
1208-
1209- $messages = array(
1210- 'new_key_empty' => array('color' => 'aa0', 'text' => __('Your key has been cleared.')),
1211- 'new_key_valid' => array('color' => '2d2', 'text' => __('Your key has been verified. Happy blogging!')),
1212- 'new_key_invalid' => array('color' => 'd22', 'text' => __('The key you entered is invalid. Please double-check it.')),
1213- 'new_key_failed' => array('color' => 'd22', 'text' => __('The key you entered could not be verified because a connection to akismet.com could not be established. Please check your server configuration.')),
1214- 'no_connection' => array('color' => 'd22', 'text' => __('There was a problem connecting to the Akismet server. Please check your server configuration.')),
1215- 'key_empty' => array('color' => 'aa0', 'text' => sprintf(__('Please enter an API key. (<a href="%s" style="color:#fff">Get your key.</a>)'), 'http://akismet.com/get/')),
1216- 'key_valid' => array('color' => '2d2', 'text' => __('This key is valid.')),
1217- 'key_failed' => array('color' => 'aa0', 'text' => __('The key below was previously validated but a connection to akismet.com can not be established at this time. Please check your server configuration.')));
1218-?>
1219-<?php if ( !empty($_POST['submit'] ) ) : ?>
1220-<div id="message" class="updated fade"><p><strong><?php _e('Options saved.') ?></strong></p></div>
1221-<?php endif; ?>
1222-<div class="wrap">
1223-<h2><?php _e('Akismet Configuration'); ?></h2>
1224-<div class="narrow">
1225-<form action="" method="post" id="akismet-conf" style="margin: auto; width: 400px; ">
1226-<?php if ( !$wpcom_api_key ) { ?>
1227- <p><?php printf(__('For many people, <a href="%1$s">Akismet</a> will greatly reduce or even completely eliminate the comment and trackback spam you get on your site. If one does happen to get through, simply mark it as "spam" on the moderation screen and Akismet will learn from the mistakes. If you don\'t have an API key yet, you can get one at <a href="%2$s">Akismet.com</a>.'), 'http://akismet.com/', 'http://akismet.com/get/'); ?></p>
1228-
1229-<h3><label for="key"><?php _e('Akismet API Key'); ?></label></h3>
1230-<?php foreach ( $ms as $m ) : ?>
1231- <p style="padding: .5em; background-color: #<?php echo $messages[$m]['color']; ?>; color: #fff; font-weight: bold;"><?php echo $messages[$m]['text']; ?></p>
1232-<?php endforeach; ?>
1233-<p><input id="key" name="key" type="text" size="15" maxlength="12" value="<?php echo get_option('wordpress_api_key'); ?>" style="font-family: 'Courier New', Courier, mono; font-size: 1.5em;" /> (<?php _e('<a href="http://akismet.com/get/">What is this?</a>'); ?>)</p>
1234-<?php if ( $invalid_key ) { ?>
1235-<h3><?php _e('Why might my key be invalid?'); ?></h3>
1236-<p><?php _e('This can mean one of two things, either you copied the key wrong or that the plugin is unable to reach the Akismet servers, which is most often caused by an issue with your web host around firewalls or similar.'); ?></p>
1237-<?php } ?>
1238-<?php } ?>
1239-<?php akismet_nonce_field($akismet_nonce) ?>
1240-<p><label><input name="akismet_discard_month" id="akismet_discard_month" value="true" type="checkbox" <?php if ( get_option('akismet_discard_month') == 'true' ) echo ' checked="checked" '; ?> /> <?php _e('Automatically discard spam comments on posts older than a month.'); ?></label></p>
1241- <p class="submit"><input type="submit" name="submit" value="<?php _e('Update options &raquo;'); ?>" /></p>
1242-</form>
1243-
1244-<form action="" method="post" id="akismet-connectivity" style="margin: auto; width: 400px; ">
1245-
1246-<h3><?php _e('Server Connectivity'); ?></h3>
1247-<?php
1248- if ( !function_exists('fsockopen') || !function_exists('gethostbynamel') ) {
1249- ?>
1250- <p style="padding: .5em; background-color: #d22; color: #fff; font-weight:bold;"><?php _e('Network functions are disabled.'); ?></p>
1251- <p><?php echo sprintf( __('Your web host or server administrator has disabled PHP\'s <code>fsockopen</code> or <code>gethostbynamel</code> functions. <strong>Akismet cannot work correctly until this is fixed.</strong> Please contact your web host or firewall administrator and give them <a href="%s" target="_blank">this information about Akismet\'s system requirements</a>.'), 'http://blog.akismet.com/akismet-hosting-faq/'); ?></p>
1252- <?php
1253- } else {
1254- $servers = akismet_get_server_connectivity();
1255- $fail_count = count($servers) - count( array_filter($servers) );
1256- if ( is_array($servers) && count($servers) > 0 ) {
1257- // some connections work, some fail
1258- if ( $fail_count > 0 && $fail_count < count($servers) ) { ?>
1259- <p style="padding: .5em; background-color: #aa0; color: #fff; font-weight:bold;"><?php _e('Unable to reach some Akismet servers.'); ?></p>
1260- <p><?php echo sprintf( __('A network problem or firewall is blocking some connections from your web server to Akismet.com. Akismet is working but this may cause problems during times of network congestion. Please contact your web host or firewall administrator and give them <a href="%s" target="_blank">this information about Akismet and firewalls</a>.'), 'http://blog.akismet.com/akismet-hosting-faq/'); ?></p>
1261- <?php
1262- // all connections fail
1263- } elseif ( $fail_count > 0 ) { ?>
1264- <p style="padding: .5em; background-color: #d22; color: #fff; font-weight:bold;"><?php _e('Unable to reach any Akismet servers.'); ?></p>
1265- <p><?php echo sprintf( __('A network problem or firewall is blocking all connections from your web server to Akismet.com. <strong>Akismet cannot work correctly until this is fixed.</strong> Please contact your web host or firewall administrator and give them <a href="%s" target="_blank">this information about Akismet and firewalls</a>.'), 'http://blog.akismet.com/akismet-hosting-faq/'); ?></p>
1266- <?php
1267- // all connections work
1268- } else { ?>
1269- <p style="padding: .5em; background-color: #2d2; color: #fff; font-weight:bold;"><?php _e('All Akismet servers are available.'); ?></p>
1270- <p><?php _e('Akismet is working correctly. All servers are accessible.'); ?></p>
1271- <?php
1272- }
1273- } else {
1274- ?>
1275- <p style="padding: .5em; background-color: #d22; color: #fff; font-weight:bold;"><?php _e('Unable to find Akismet servers.'); ?></p>
1276- <p><?php echo sprintf( __('A DNS problem or firewall is preventing all access from your web server to Akismet.com. <strong>Akismet cannot work correctly until this is fixed.</strong> Please contact your web host or firewall administrator and give them <a href="%s" target="_blank">this information about Akismet and firewalls</a>.'), 'http://blog.akismet.com/akismet-hosting-faq/'); ?></p>
1277- <?php
1278- }
1279- }
1280-
1281- if ( !empty($servers) ) {
1282-?>
1283-<table style="width: 100%;">
1284-<thead><th><?php _e('Akismet server'); ?></th><th><?php _e('Network Status'); ?></th></thead>
1285-<tbody>
1286-<?php
1287- asort($servers);
1288- foreach ( $servers as $ip => $status ) {
1289- $color = ( $status ? '#2d2' : '#d22');
1290- ?>
1291- <tr>
1292- <td><?php echo htmlspecialchars($ip); ?></td>
1293- <td style="padding: 0 .5em; font-weight:bold; color: #fff; background-color: <?php echo $color; ?>"><?php echo ($status ? __('No problems') : __('Obstructed') ); ?></td>
1294-
1295- <?php
1296- }
1297- }
1298-?>
1299-</tbody>
1300-</table>
1301- <p><?php if ( get_option('akismet_connectivity_time') ) echo sprintf( __('Last checked %s ago.'), human_time_diff( get_option('akismet_connectivity_time') ) ); ?></p>
1302- <p class="submit"><input type="submit" name="check" value="<?php _e('Check network status &raquo;'); ?>" /></p>
1303-</form>
1304-
1305-</div>
1306-</div>
1307-<?php
1308-}
1309-
1310-function akismet_stats_page() {
1311- if ( function_exists('add_submenu_page') )
1312- add_submenu_page('index.php', __('Akismet Stats'), __('Akismet Stats'), 'manage_options', 'akismet-stats-display', 'akismet_stats_display');
1313-
1314-}
1315-
1316-function akismet_stats_script() {
1317- ?>
1318-<script type="text/javascript">
1319-function resizeIframe() {
1320- var height = document.documentElement.clientHeight;
1321- height -= document.getElementById('akismet-stats-frame').offsetTop;
1322- height += 100; // magic padding
1323-
1324- document.getElementById('akismet-stats-frame').style.height = height +"px";
1325-
1326-};
1327-function resizeIframeInit() {
1328- document.getElementById('akismet-stats-frame').onload = resizeIframe;
1329- window.onresize = resizeIframe;
1330-}
1331-addLoadEvent(resizeIframeInit);
1332-</script><?php
1333-}
1334-
1335-
1336-function akismet_stats_display() {
1337- global $akismet_api_host, $akismet_api_port, $wpcom_api_key;
1338- $blog = urlencode( get_option('home') );
1339- $url = "http://".akismet_get_key().".web.akismet.com/1.0/user-stats.php?blog={$blog}";
1340- ?>
1341- <div class="wrap">
1342- <iframe src="<?php echo $url; ?>" width="100%" height="100%" frameborder="0" id="akismet-stats-frame"></iframe>
1343- </div>
1344- <?php
1345-}
1346-
1347 function akismet_get_key() {
1348 global $wpcom_api_key;
1349 if ( !empty($wpcom_api_key) )
1350@@ -272,104 +81,11 @@
1351 return $response[1];
1352 }
1353
1354-// Check connectivity between the WordPress blog and Akismet's servers.
1355-// Returns an associative array of server IP addresses, where the key is the IP address, and value is true (available) or false (unable to connect).
1356-function akismet_check_server_connectivity() {
1357- global $akismet_api_host, $akismet_api_port, $wpcom_api_key;
1358-
1359- $test_host = 'rest.akismet.com';
1360-
1361- // Some web hosts may disable one or both functions
1362- if ( !function_exists('fsockopen') || !function_exists('gethostbynamel') )
1363- return array();
1364-
1365- $ips = gethostbynamel($test_host);
1366- if ( !$ips || !is_array($ips) || !count($ips) )
1367- return array();
1368-
1369- $servers = array();
1370- foreach ( $ips as $ip ) {
1371- $response = akismet_verify_key( akismet_get_key(), $ip );
1372- // even if the key is invalid, at least we know we have connectivity
1373- if ( $response == 'valid' || $response == 'invalid' )
1374- $servers[$ip] = true;
1375- else
1376- $servers[$ip] = false;
1377- }
1378-
1379- return $servers;
1380-}
1381-
1382-// Check the server connectivity and store the results in an option.
1383-// Cached results will be used if not older than the specified timeout in seconds; use $cache_timeout = 0 to force an update.
1384-// Returns the same associative array as akismet_check_server_connectivity()
1385-function akismet_get_server_connectivity( $cache_timeout = 86400 ) {
1386- $servers = get_option('akismet_available_servers');
1387- if ( (time() - get_option('akismet_connectivity_time') < $cache_timeout) && $servers !== false )
1388- return $servers;
1389-
1390- // There's a race condition here but the effect is harmless.
1391- $servers = akismet_check_server_connectivity();
1392- update_option('akismet_available_servers', $servers);
1393- update_option('akismet_connectivity_time', time());
1394- return $servers;
1395-}
1396-
1397-// Returns true if server connectivity was OK at the last check, false if there was a problem that needs to be fixed.
1398-function akismet_server_connectivity_ok() {
1399- // skip the check on WPMU because the status page is hidden
1400- global $wpcom_api_key;
1401- if ( $wpcom_api_key )
1402+// if we're in debug or test modes, use a reduced service level so as not to polute training or stats data
1403+function akismet_test_mode() {
1404+ if ( defined('AKISMET_TEST_MODE') && AKISMET_TEST_MODE )
1405 return true;
1406- $servers = akismet_get_server_connectivity();
1407- return !( empty($servers) || !count($servers) || count( array_filter($servers) ) < count($servers) );
1408-}
1409-
1410-function akismet_admin_warnings() {
1411- global $wpcom_api_key;
1412- if ( !get_option('wordpress_api_key') && !$wpcom_api_key && !isset($_POST['submit']) ) {
1413- function akismet_warning() {
1414- echo "
1415- <div id='akismet-warning' class='updated fade'><p><strong>".__('Akismet is almost ready.')."</strong> ".sprintf(__('You must <a href="%1$s">enter your Akismet API key</a> for it to work.'), "plugins.php?page=akismet-key-config")."</p></div>
1416- ";
1417- }
1418- add_action('admin_notices', 'akismet_warning');
1419- return;
1420- } elseif ( get_option('akismet_connectivity_time') && empty($_POST) && is_admin() && !akismet_server_connectivity_ok() ) {
1421- function akismet_warning() {
1422- echo "
1423- <div id='akismet-warning' class='updated fade'><p><strong>".__('Akismet has detected a problem.')."</strong> ".sprintf(__('A server or network problem is preventing Akismet from working correctly. <a href="%1$s">Click here for more information</a> about how to fix the problem.'), "plugins.php?page=akismet-key-config")."</p></div>
1424- ";
1425- }
1426- add_action('admin_notices', 'akismet_warning');
1427- return;
1428- }
1429-}
1430-
1431-function akismet_get_host($host) {
1432- // if all servers are accessible, just return the host name.
1433- // if not, return an IP that was known to be accessible at the last check.
1434- if ( akismet_server_connectivity_ok() ) {
1435- return $host;
1436- } else {
1437- $ips = akismet_get_server_connectivity();
1438- // a firewall may be blocking access to some Akismet IPs
1439- if ( count($ips) > 0 && count(array_filter($ips)) < count($ips) ) {
1440- // use DNS to get current IPs, but exclude any known to be unreachable
1441- $dns = (array)gethostbynamel( rtrim($host, '.') . '.' );
1442- $dns = array_filter($dns);
1443- foreach ( $dns as $ip ) {
1444- if ( array_key_exists( $ip, $ips ) && empty( $ips[$ip] ) )
1445- unset($dns[$ip]);
1446- }
1447- // return a random IP from those available
1448- if ( count($dns) )
1449- return $dns[ array_rand($dns) ];
1450-
1451- }
1452- }
1453- // if all else fails try the host name
1454- return $host;
1455+ return false;
1456 }
1457
1458 // return a comma-separated list of role names for the given user
1459@@ -384,42 +100,76 @@
1460 if ( isset($comment_user->roles) )
1461 $roles = join(',', $comment_user->roles);
1462 }
1463-
1464+
1465+ if ( is_multisite() && is_super_admin( $user_id ) ) {
1466+ if ( empty( $roles ) ) {
1467+ $roles = 'super_admin';
1468+ } else {
1469+ $comment_user->roles[] = 'super_admin';
1470+ $roles = join( ',', $comment_user->roles );
1471+ }
1472+ }
1473+
1474 return $roles;
1475 }
1476
1477 // Returns array with headers in $response[0] and body in $response[1]
1478 function akismet_http_post($request, $host, $path, $port = 80, $ip=null) {
1479 global $wp_version;
1480-
1481- $akismet_version = constant('AKISMET_VERSION');
1482-
1483- $http_request = "POST $path HTTP/1.0\r\n";
1484- $http_request .= "Host: $host\r\n";
1485- $http_request .= "Content-Type: application/x-www-form-urlencoded; charset=" . get_option('blog_charset') . "\r\n";
1486- $http_request .= "Content-Length: " . strlen($request) . "\r\n";
1487- $http_request .= "User-Agent: WordPress/$wp_version | Akismet/$akismet_version\r\n";
1488- $http_request .= "\r\n";
1489- $http_request .= $request;
1490-
1491+
1492+ $akismet_ua = "WordPress/{$wp_version} | ";
1493+ $akismet_ua .= 'Akismet/' . constant( 'AKISMET_VERSION' );
1494+
1495+ $content_length = strlen( $request );
1496+
1497 $http_host = $host;
1498- // use a specific IP if provided - needed by akismet_check_server_connectivity()
1499- if ( $ip && long2ip(ip2long($ip)) ) {
1500+ // use a specific IP if provided
1501+ // needed by akismet_check_server_connectivity()
1502+ if ( $ip && long2ip( ip2long( $ip ) ) ) {
1503 $http_host = $ip;
1504 } else {
1505- $http_host = akismet_get_host($host);
1506- }
1507-
1508- $response = '';
1509- if( false != ( $fs = @fsockopen($http_host, $port, $errno, $errstr, 10) ) ) {
1510- fwrite($fs, $http_request);
1511-
1512- while ( !feof($fs) )
1513- $response .= fgets($fs, 1160); // One TCP-IP packet
1514- fclose($fs);
1515- $response = explode("\r\n\r\n", $response, 2);
1516- }
1517- return $response;
1518+ $http_host = $host;
1519+ }
1520+
1521+ // use the WP HTTP class if it is available
1522+ if ( function_exists( 'wp_remote_post' ) ) {
1523+ $http_args = array(
1524+ 'body' => $request,
1525+ 'headers' => array(
1526+ 'Content-Type' => 'application/x-www-form-urlencoded; ' .
1527+ 'charset=' . get_option( 'blog_charset' ),
1528+ 'Host' => $host,
1529+ 'User-Agent' => $akismet_ua
1530+ ),
1531+ 'httpversion' => '1.0',
1532+ 'timeout' => 15
1533+ );
1534+ $akismet_url = "http://{$http_host}{$path}";
1535+ $response = wp_remote_post( $akismet_url, $http_args );
1536+ if ( is_wp_error( $response ) )
1537+ return '';
1538+
1539+ return array( $response['headers'], $response['body'] );
1540+ } else {
1541+ $http_request = "POST $path HTTP/1.0\r\n";
1542+ $http_request .= "Host: $host\r\n";
1543+ $http_request .= 'Content-Type: application/x-www-form-urlencoded; charset=' . get_option('blog_charset') . "\r\n";
1544+ $http_request .= "Content-Length: {$content_length}\r\n";
1545+ $http_request .= "User-Agent: {$akismet_ua}\r\n";
1546+ $http_request .= "\r\n";
1547+ $http_request .= $request;
1548+
1549+ $response = '';
1550+ if( false != ( $fs = @fsockopen( $http_host, $port, $errno, $errstr, 10 ) ) ) {
1551+ fwrite( $fs, $http_request );
1552+
1553+ while ( !feof( $fs ) )
1554+ $response .= fgets( $fs, 1160 ); // One TCP-IP packet
1555+ fclose( $fs );
1556+ $response = explode( "\r\n\r\n", $response, 2 );
1557+ }
1558+ return $response;
1559+ }
1560 }
1561
1562 // filter handler used to return a spam result to pre_comment_approved
1563@@ -427,12 +177,124 @@
1564 // bump the counter here instead of when the filter is added to reduce the possibility of overcounting
1565 if ( $incr = apply_filters('akismet_spam_count_incr', 1) )
1566 update_option( 'akismet_spam_count', get_option('akismet_spam_count') + $incr );
1567+ // this is a one-shot deal
1568+ remove_filter( 'pre_comment_approved', 'akismet_result_spam' );
1569 return 'spam';
1570 }
1571
1572-function akismet_auto_check_comment( $comment ) {
1573- global $akismet_api_host, $akismet_api_port;
1574-
1575+function akismet_result_hold( $approved ) {
1576+ // once only
1577+ remove_filter( 'pre_comment_approved', 'akismet_result_hold' );
1578+ return '0';
1579+}
1580+
1581+// how many approved comments does this author have?
1582+function akismet_get_user_comments_approved( $user_id, $comment_author_email, $comment_author, $comment_author_url ) {
1583+ global $wpdb;
1584+
1585+ if ( !empty($user_id) )
1586+ return $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM $wpdb->comments WHERE user_id = %d AND comment_approved = 1", $user_id ) );
1587+
1588+ if ( !empty($comment_author_email) )
1589+ return $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM $wpdb->comments WHERE comment_author_email = %s AND comment_author = %s AND comment_author_url = %s AND comment_approved = 1", $comment_author_email, $comment_author, $comment_author_url ) );
1590+
1591+ return 0;
1592+}
1593+
1594+function akismet_microtime() {
1595+ $mtime = explode( ' ', microtime() );
1596+ return $mtime[1] + $mtime[0];
1597+}
1598+
1599+// log an event for a given comment, storing it in comment_meta
1600+function akismet_update_comment_history( $comment_id, $message, $event=null ) {
1601+ global $current_user;
1602+
1603+ // failsafe for old WP versions
1604+ if ( !function_exists('add_comment_meta') )
1605+ return false;
1606+
1607+ $user = '';
1608+ if ( is_object($current_user) && isset($current_user->user_login) )
1609+ $user = $current_user->user_login;
1610+
1611+ $event = array(
1612+ 'time' => akismet_microtime(),
1613+ 'message' => $message,
1614+ 'event' => $event,
1615+ 'user' => $user,
1616+ );
1617+
1618+ // $unique = false so as to allow multiple values per comment
1619+ $r = add_comment_meta( $comment_id, 'akismet_history', $event, false );
1620+}
1621+
1622+// get the full comment history for a given comment, as an array in reverse chronological order
1623+function akismet_get_comment_history( $comment_id ) {
1624+
1625+ // failsafe for old WP versions
1626+ if ( !function_exists('add_comment_meta') )
1627+ return false;
1628+
1629+ $history = get_comment_meta( $comment_id, 'akismet_history', false );
1630+ usort( $history, 'akismet_cmp_time' );
1631+ return $history;
1632+}
1633+
1634+function akismet_cmp_time( $a, $b ) {
1635+ return $a['time'] > $b['time'] ? -1 : 1;
1636+}
1637+
1638+// this fires on wp_insert_comment. we can't update comment_meta when akismet_auto_check_comment() runs
1639+// because we don't know the comment ID at that point.
1640+function akismet_auto_check_update_meta( $id, $comment ) {
1641+ global $akismet_last_comment;
1642+
1643+ // failsafe for old WP versions
1644+ if ( !function_exists('add_comment_meta') )
1645+ return false;
1646+
1647+ // wp_insert_comment() might be called in other contexts, so make sure this is the same comment
1648+ // as was checked by akismet_auto_check_comment
1649+ if ( is_object($comment) && !empty($akismet_last_comment) && is_array($akismet_last_comment) ) {
1650+ if ( intval($akismet_last_comment['comment_post_ID']) == intval($comment->comment_post_ID)
1651+ && $akismet_last_comment['comment_author'] == $comment->comment_author
1652+ && $akismet_last_comment['comment_author_email'] == $comment->comment_author_email ) {
1653+ // normal result: true or false
1654+ if ( $akismet_last_comment['akismet_result'] == 'true' ) {
1655+ update_comment_meta( $comment->comment_ID, 'akismet_result', 'true' );
1656+ akismet_update_comment_history( $comment->comment_ID, __('Akismet caught this comment as spam'), 'check-spam' );
1657+ if ( $comment->comment_approved != 'spam' )
1658+ akismet_update_comment_history( $comment->comment_ID, sprintf( __('Comment status was changed to %s'), $comment->comment_approved), 'status-changed'.$comment->comment_approved );
1659+ } elseif ( $akismet_last_comment['akismet_result'] == 'false' ) {
1660+ update_comment_meta( $comment->comment_ID, 'akismet_result', 'false' );
1661+ akismet_update_comment_history( $comment->comment_ID, __('Akismet cleared this comment'), 'check-ham' );
1662+ if ( $comment->comment_approved == 'spam' ) {
1663+ if ( wp_blacklist_check($comment->comment_author, $comment->comment_author_email, $comment->comment_author_url, $comment->comment_content, $comment->comment_author_IP, $comment->comment_agent) )
1664+ akismet_update_comment_history( $comment->comment_ID, __('Comment was caught by wp_blacklist_check'), 'wp-blacklisted' );
1665+ else
1666+ akismet_update_comment_history( $comment->comment_ID, sprintf( __('Comment status was changed to %s'), $comment->comment_approved), 'status-changed-'.$comment->comment_approved );
1667+ }
1668+ // abnormal result: error
1669+ } else {
1670+ update_comment_meta( $comment->comment_ID, 'akismet_error', time() );
1671+ akismet_update_comment_history( $comment->comment_ID, sprintf( __('Akismet was unable to check this comment (response: %s), will automatically retry again later.'), $akismet_last_comment['akismet_result']), 'check-error' );
1672+ }
1673+
1674+ // record the complete original data as submitted for checking
1675+ if ( isset($akismet_last_comment['comment_as_submitted']) )
1676+ update_comment_meta( $comment->comment_ID, 'akismet_as_submitted', $akismet_last_comment['comment_as_submitted'] );
1677+ }
1678+ }
1679+}
1680+
1681+add_action( 'wp_insert_comment', 'akismet_auto_check_update_meta', 10, 2 );
1682+
1683+
1684+function akismet_auto_check_comment( $commentdata ) {
1685+ global $akismet_api_host, $akismet_api_port, $akismet_last_comment;
1686+
1687+ $comment = $commentdata;
1688 $comment['user_ip'] = $_SERVER['REMOTE_ADDR'];
1689 $comment['user_agent'] = $_SERVER['HTTP_USER_AGENT'];
1690 $comment['referrer'] = $_SERVER['HTTP_REFERER'];
1691@@ -443,17 +305,44 @@
1692
1693 $comment['user_role'] = akismet_get_user_roles($comment['user_ID']);
1694
1695- $ignore = array( 'HTTP_COOKIE' );
1696-
1697- foreach ( $_SERVER as $key => $value )
1698+ $akismet_nonce_option = apply_filters( 'akismet_comment_nonce', get_option( 'akismet_comment_nonce' ) );
1699+ $comment['akismet_comment_nonce'] = 'inactive';
1700+ if ( $akismet_nonce_option == 'true' || $akismet_nonce_option == '' ) {
1701+ $comment['akismet_comment_nonce'] = 'failed';
1702+ if ( isset( $_POST['akismet_comment_nonce'] ) && wp_verify_nonce( $_POST['akismet_comment_nonce'], 'akismet_comment_nonce_' . $comment['comment_post_ID'] ) )
1703+ $comment['akismet_comment_nonce'] = 'passed';
1704+
1705+ // comment reply in wp-admin
1706+ if ( isset( $_POST['_ajax_nonce-replyto-comment'] ) && check_ajax_referer( 'replyto-comment', '_ajax_nonce-replyto-comment' ) )
1707+ $comment['akismet_comment_nonce'] = 'passed';
1708+
1709+ }
1710+
1711+ if ( akismet_test_mode() )
1712+ $comment['is_test'] = 'true';
1713+
1714+ foreach ($_POST as $key => $value ) {
1715+ if ( is_string($value) )
1716+ $comment["POST_{$key}"] = $value;
1717+ }
1718+
1719+ $ignore = array( 'HTTP_COOKIE', 'HTTP_COOKIE2', 'PHP_AUTH_PW' );
1720+
1721+ foreach ( $_SERVER as $key => $value ) {
1722 if ( !in_array( $key, $ignore ) && is_string($value) )
1723 $comment["$key"] = $value;
1724+ else
1725+ $comment["$key"] = '';
1726+ }
1727
1728 $query_string = '';
1729 foreach ( $comment as $key => $data )
1730 $query_string .= $key . '=' . urlencode( stripslashes($data) ) . '&';
1731+
1732+ $commentdata['comment_as_submitted'] = $comment;
1733
1734 $response = akismet_http_post($query_string, $akismet_api_host, '/1.1/comment-check', $akismet_api_port);
1735+ $commentdata['akismet_result'] = $response[1];
1736 if ( 'true' == $response[1] ) {
1737 // akismet_spam_count will be incremented later by akismet_result_spam()
1738 add_filter('pre_comment_approved', 'akismet_result_spam');
1739@@ -469,10 +358,17 @@
1740 // akismet_result_spam() won't be called so bump the counter here
1741 if ( $incr = apply_filters('akismet_spam_count_incr', 1) )
1742 update_option( 'akismet_spam_count', get_option('akismet_spam_count') + $incr );
1743- die;
1744+ wp_redirect( $_SERVER['HTTP_REFERER'] );
1745+ die();
1746 }
1747 }
1748
1749+ // if the response is neither true nor false, hold the comment for moderation and schedule a recheck
1750+ if ( 'true' != $response[1] && 'false' != $response[1] ) {
1751+ add_filter('pre_comment_approved', 'akismet_result_hold');
1752+ wp_schedule_single_event( time() + 1200, 'akismet_schedule_cron_recheck' );
1753+ }
1754+
1755 if ( function_exists('wp_next_scheduled') && function_exists('wp_schedule_event') ) {
1756 // WP 2.1+: delete old comments daily
1757 if ( !wp_next_scheduled('akismet_scheduled_delete') )
1758@@ -481,706 +377,130 @@
1759 // WP 2.0: run this one time in ten
1760 akismet_delete_old();
1761 }
1762- return $comment;
1763+ $akismet_last_comment = $commentdata;
1764+ return $commentdata;
1765 }
1766
1767+add_action('preprocess_comment', 'akismet_auto_check_comment', 1);
1768+
1769 function akismet_delete_old() {
1770 global $wpdb;
1771 $now_gmt = current_time('mysql', 1);
1772- $wpdb->query("DELETE FROM $wpdb->comments WHERE DATE_SUB('$now_gmt', INTERVAL 15 DAY) > comment_date_gmt AND comment_approved = 'spam'");
1773+ $comment_ids = $wpdb->get_col("SELECT comment_id FROM $wpdb->comments WHERE DATE_SUB('$now_gmt', INTERVAL 15 DAY) > comment_date_gmt AND comment_approved = 'spam'");
1774+ if ( empty( $comment_ids ) )
1775+ return;
1776+
1777+ $comma_comment_ids = implode( ', ', array_map('intval', $comment_ids) );
1778+
1779+ do_action( 'delete_comment', $comment_ids );
1780+ $wpdb->query("DELETE FROM $wpdb->comments WHERE comment_id IN ( $comma_comment_ids )");
1781+ $wpdb->query("DELETE FROM $wpdb->commentmeta WHERE comment_id IN ( $comma_comment_ids )");
1782+ clean_comment_cache( $comment_ids );
1783 $n = mt_rand(1, 5000);
1784 if ( apply_filters('akismet_optimize_table', ($n == 11)) ) // lucky number
1785 $wpdb->query("OPTIMIZE TABLE $wpdb->comments");
1786+
1787 }
1788
1789 add_action('akismet_scheduled_delete', 'akismet_delete_old');
1790
1791-function akismet_submit_nonspam_comment ( $comment_id ) {
1792- global $wpdb, $akismet_api_host, $akismet_api_port, $current_user, $current_site;
1793- $comment_id = (int) $comment_id;
1794-
1795- $comment = $wpdb->get_row("SELECT * FROM $wpdb->comments WHERE comment_ID = '$comment_id'");
1796- if ( !$comment ) // it was deleted
1797- return;
1798- $comment->blog = get_option('home');
1799- $comment->blog_lang = get_locale();
1800- $comment->blog_charset = get_option('blog_charset');
1801- $comment->permalink = get_permalink($comment->comment_post_ID);
1802- if ( is_object($current_user) ) {
1803- $comment->reporter = $current_user->user_login;
1804- }
1805- if ( is_object($current_site) ) {
1806- $comment->site_domain = $current_site->domain;
1807- }
1808- $comment->user_role = akismet_get_user_roles($comment->user_ID);
1809-
1810- $query_string = '';
1811- foreach ( $comment as $key => $data )
1812- $query_string .= $key . '=' . urlencode( stripslashes($data) ) . '&';
1813-
1814- $response = akismet_http_post($query_string, $akismet_api_host, "/1.1/submit-ham", $akismet_api_port);
1815-}
1816-
1817-function akismet_submit_spam_comment ( $comment_id ) {
1818- global $wpdb, $akismet_api_host, $akismet_api_port, $current_user, $current_site;
1819- $comment_id = (int) $comment_id;
1820-
1821- $comment = $wpdb->get_row("SELECT * FROM $wpdb->comments WHERE comment_ID = '$comment_id'");
1822- if ( !$comment ) // it was deleted
1823- return;
1824- if ( 'spam' != $comment->comment_approved )
1825- return;
1826- $comment->blog = get_option('home');
1827- $comment->blog_lang = get_locale();
1828- $comment->blog_charset = get_option('blog_charset');
1829- $comment->permalink = get_permalink($comment->comment_post_ID);
1830- if ( is_object($current_user) ) {
1831- $comment->reporter = $current_user->user_login;
1832- }
1833- if ( is_object($current_site) ) {
1834- $comment->site_domain = $current_site->domain;
1835- }
1836- $comment->user_role = akismet_get_user_roles($comment->user_ID);
1837- $query_string = '';
1838- foreach ( $comment as $key => $data )
1839- $query_string .= $key . '=' . urlencode( stripslashes($data) ) . '&';
1840-
1841- $response = akismet_http_post($query_string, $akismet_api_host, "/1.1/submit-spam", $akismet_api_port);
1842-}
1843-
1844-add_action('preprocess_comment', 'akismet_auto_check_comment', 1);
1845-
1846-// For old versions of WP only
1847-function akismet_set_comment_status( $comment_id, $status ) {
1848- if ( $status == 'spam' ) {
1849- akismet_submit_spam_comment( $comment_id );
1850- } elseif ( $status == 'approve' ) {
1851- akismet_submit_nonspam_comment( $comment_id );
1852- }
1853-}
1854-
1855-// For WP 2.7+
1856-function akismet_transition_comment_status( $new_status, $old_status, $comment ) {
1857- if ( $new_status == $old_status )
1858- return;
1859-
1860- if ( $new_status == 'spam' ) {
1861- akismet_submit_spam_comment( $comment->comment_ID );
1862- } elseif ( $old_status == 'spam' && ( $new_status == 'approved' || $new_status == 'unapproved' ) ) {
1863- akismet_submit_nonspam_comment( $comment->comment_ID );
1864- }
1865-}
1866-
1867-function akismet_spamtoham( $comment ) { akismet_submit_nonspam_comment( $comment->comment_ID ); }
1868-
1869-if ( function_exists( 'wp_transition_comment_status' ) ) {
1870- add_action( 'transition_comment_status', 'akismet_transition_comment_status', 10, 3 );
1871-} else {
1872- add_action('wp_set_comment_status', 'akismet_set_comment_status', 10, 2);
1873- add_action('edit_comment', 'akismet_submit_spam_comment');
1874- add_filter( 'comment_spam_to_approved', 'akismet_spamtoham' );
1875- add_filter( 'comment_spam_to_unapproved', 'akismet_spamtoham' );
1876-}
1877-// Total spam in queue
1878-// get_option( 'akismet_spam_count' ) is the total caught ever
1879-function akismet_spam_count( $type = false ) {
1880+function akismet_check_db_comment( $id, $recheck_reason = 'recheck_queue' ) {
1881+ global $wpdb, $akismet_api_host, $akismet_api_port;
1882+
1883+ $id = (int) $id;
1884+ $c = $wpdb->get_row( "SELECT * FROM $wpdb->comments WHERE comment_ID = '$id'", ARRAY_A );
1885+ if ( !$c )
1886+ return;
1887+
1888+ $c['user_ip'] = $c['comment_author_IP'];
1889+ $c['user_agent'] = $c['comment_agent'];
1890+ $c['referrer'] = '';
1891+ $c['blog'] = get_option('home');
1892+ $c['blog_lang'] = get_locale();
1893+ $c['blog_charset'] = get_option('blog_charset');
1894+ $c['permalink'] = get_permalink($c['comment_post_ID']);
1895+ $id = $c['comment_ID'];
1896+ if ( akismet_test_mode() )
1897+ $c['is_test'] = 'true';
1898+ $c['recheck_reason'] = $recheck_reason;
1899+
1900+ $query_string = '';
1901+ foreach ( $c as $key => $data )
1902+ $query_string .= $key . '=' . urlencode( stripslashes($data) ) . '&';
1903+
1904+ $response = akismet_http_post($query_string, $akismet_api_host, '/1.1/comment-check', $akismet_api_port);
1905+ return $response[1];
1906+}
1907+
1908+function akismet_cron_recheck() {
1909 global $wpdb;
1910
1911- if ( !$type ) { // total
1912- $count = wp_cache_get( 'akismet_spam_count', 'widget' );
1913- if ( false === $count ) {
1914- if ( function_exists('wp_count_comments') ) {
1915- $count = wp_count_comments();
1916- $count = $count->spam;
1917- } else {
1918- $count = (int) $wpdb->get_var("SELECT COUNT(comment_ID) FROM $wpdb->comments WHERE comment_approved = 'spam'");
1919+ delete_option('akismet_available_servers');
1920+
1921+ $comment_errors = $wpdb->get_col( "
1922+ SELECT comment_id
1923+ FROM {$wpdb->prefix}commentmeta
1924+ WHERE meta_key = 'akismet_error'
1925+ LIMIT 100
1926+ " );
1927+
1928+ foreach ( (array) $comment_errors as $comment_id ) {
1929+ // if the comment no longer exists, remove the meta entry from the queue to avoid getting stuck
1930+ if ( !get_comment( $comment_id ) ) {
1931+ delete_comment_meta( $comment_id, 'akismet_error' );
1932+ continue;
1933+ }
1934+
1935+ add_comment_meta( $comment_id, 'akismet_rechecking', true );
1936+ $status = akismet_check_db_comment( $comment_id, 'retry' );
1937+
1938+ $msg = '';
1939+ if ( $status == 'true' ) {
1940+ $msg = __( 'Akismet caught this comment as spam during an automatic retry.' );
1941+ } elseif ( $status == 'false' ) {
1942+ $msg = __( 'Akismet cleared this comment during an automatic retry.' );
1943+ }
1944+
1945+ // If we got back a legit response then update the comment history
1946+ // other wise just bail now and try again later. No point in
1947+ // re-trying all the comments once we hit one failure.
1948+ if ( !empty( $msg ) ) {
1949+ delete_comment_meta( $comment_id, 'akismet_error' );
1950+ akismet_update_comment_history( $comment_id, $msg, 'cron-retry' );
1951+ update_comment_meta( $comment_id, 'akismet_result', $status );
1952+ // make sure the comment status is still pending. if it isn't, that means the user has already moved it elsewhere.
1953+ $comment = get_comment( $comment_id );
1954+ if ( $comment && 'unapproved' == wp_get_comment_status( $comment_id ) ) {
1955+ if ( $status == 'true' ) {
1956+ wp_spam_comment( $comment_id );
1957+ } elseif ( $status == 'false' ) {
1958+ // comment is good, but it's still in the pending queue. depending on the moderation settings
1959+ // we may need to change it to approved.
1960+ if ( check_comment($comment->comment_author, $comment->comment_author_email, $comment->comment_author_url, $comment->comment_content, $comment->comment_author_IP, $comment->comment_agent, $comment->comment_type) )
1961+ wp_set_comment_status( $comment_id, 1 );
1962+ }
1963 }
1964- wp_cache_set( 'akismet_spam_count', $count, 'widget', 3600 );
1965+ } else {
1966+ delete_comment_meta( $comment_id, 'akismet_rechecking' );
1967+ wp_schedule_single_event( time() + 1200, 'akismet_schedule_cron_recheck' );
1968+ return;
1969 }
1970- return $count;
1971- } elseif ( 'comments' == $type || 'comment' == $type ) { // comments
1972- $type = '';
1973- } else { // pingback, trackback, ...
1974- $type = $wpdb->escape( $type );
1975- }
1976-
1977- return (int) $wpdb->get_var("SELECT COUNT(comment_ID) FROM $wpdb->comments WHERE comment_approved = 'spam' AND comment_type='$type'");
1978-}
1979-
1980-function akismet_spam_comments( $type = false, $page = 1, $per_page = 50 ) {
1981- global $wpdb;
1982-
1983- $page = (int) $page;
1984- if ( $page < 2 )
1985- $page = 1;
1986-
1987- $per_page = (int) $per_page;
1988- if ( $per_page < 1 )
1989- $per_page = 50;
1990-
1991- $start = ( $page - 1 ) * $per_page;
1992- $end = $start + $per_page;
1993-
1994- if ( $type ) {
1995- if ( 'comments' == $type || 'comment' == $type )
1996- $type = '';
1997- else
1998- $type = $wpdb->escape( $type );
1999- return $wpdb->get_results( "SELECT * FROM $wpdb->comments WHERE comment_approved = 'spam' AND comment_type='$type' ORDER BY comment_date DESC LIMIT $start, $end");
2000- }
2001-
2002- // All
2003- return $wpdb->get_results( "SELECT * FROM $wpdb->comments WHERE comment_approved = 'spam' ORDER BY comment_date DESC LIMIT $start, $end");
2004-}
2005-
2006-// Totals for each comment type
2007-// returns array( type => count, ... )
2008-function akismet_spam_totals() {
2009- global $wpdb;
2010- $totals = $wpdb->get_results( "SELECT comment_type, COUNT(*) AS cc FROM $wpdb->comments WHERE comment_approved = 'spam' GROUP BY comment_type" );
2011- $return = array();
2012- foreach ( $totals as $total )
2013- $return[$total->comment_type ? $total->comment_type : 'comment'] = $total->cc;
2014- return $return;
2015-}
2016-
2017-function akismet_manage_page() {
2018- global $wpdb, $submenu, $wp_db_version;
2019-
2020- // WP 2.7 has its own spam management page
2021- if ( 8645 <= $wp_db_version )
2022- return;
2023-
2024- $count = sprintf(__('Akismet Spam (%s)'), akismet_spam_count());
2025- if ( isset( $submenu['edit-comments.php'] ) )
2026- add_submenu_page('edit-comments.php', __('Akismet Spam'), $count, 'moderate_comments', 'akismet-admin', 'akismet_caught' );
2027- elseif ( function_exists('add_management_page') )
2028- add_management_page(__('Akismet Spam'), $count, 'moderate_comments', 'akismet-admin', 'akismet_caught');
2029-}
2030-
2031-function akismet_caught() {
2032- global $wpdb, $comment, $akismet_caught, $akismet_nonce;
2033-
2034- akismet_recheck_queue();
2035- if (isset($_POST['submit']) && 'recover' == $_POST['action'] && ! empty($_POST['not_spam'])) {
2036- check_admin_referer( $akismet_nonce );
2037- if ( function_exists('current_user_can') && !current_user_can('moderate_comments') )
2038- die(__('You do not have sufficient permission to moderate comments.'));
2039-
2040- $i = 0;
2041- foreach ($_POST['not_spam'] as $comment):
2042- $comment = (int) $comment;
2043- if ( function_exists('wp_set_comment_status') )
2044- wp_set_comment_status($comment, 'approve');
2045- else
2046- $wpdb->query("UPDATE $wpdb->comments SET comment_approved = '1' WHERE comment_ID = '$comment'");
2047- akismet_submit_nonspam_comment($comment);
2048- ++$i;
2049- endforeach;
2050- $to = add_query_arg( 'recovered', $i, $_SERVER['HTTP_REFERER'] );
2051- wp_redirect( $to );
2052- exit;
2053- }
2054- if ('delete' == $_POST['action']) {
2055- check_admin_referer( $akismet_nonce );
2056- if ( function_exists('current_user_can') && !current_user_can('moderate_comments') )
2057- die(__('You do not have sufficient permission to moderate comments.'));
2058-
2059- $delete_time = $wpdb->escape( $_POST['display_time'] );
2060- $nuked = $wpdb->query( "DELETE FROM $wpdb->comments WHERE comment_approved = 'spam' AND '$delete_time' > comment_date_gmt" );
2061- wp_cache_delete( 'akismet_spam_count', 'widget' );
2062- $to = add_query_arg( 'deleted', 'all', $_SERVER['HTTP_REFERER'] );
2063- wp_redirect( $to );
2064- exit;
2065- }
2066-
2067-if ( isset( $_GET['recovered'] ) ) {
2068- $i = (int) $_GET['recovered'];
2069- echo '<div class="updated"><p>' . sprintf(__('%1$s comments recovered.'), $i) . "</p></div>";
2070-}
2071-
2072-if (isset( $_GET['deleted'] ) )
2073- echo '<div class="updated"><p>' . __('All spam deleted.') . '</p></div>';
2074-
2075-if ( isset( $GLOBALS['submenu']['edit-comments.php'] ) )
2076- $link = 'edit-comments.php';
2077-else
2078- $link = 'edit.php';
2079-?>
2080-<style type="text/css">
2081-.akismet-tabs {
2082- list-style: none;
2083- margin: 0;
2084- padding: 0;
2085- clear: both;
2086- border-bottom: 1px solid #ccc;
2087- height: 31px;
2088- margin-bottom: 20px;
2089- background: #ddd;
2090- border-top: 1px solid #bdbdbd;
2091-}
2092-.akismet-tabs li {
2093- float: left;
2094- margin: 5px 0 0 20px;
2095-}
2096-.akismet-tabs a {
2097- display: block;
2098- padding: 4px .5em 3px;
2099- border-bottom: none;
2100- color: #036;
2101-}
2102-.akismet-tabs .active a {
2103- background: #fff;
2104- border: 1px solid #ccc;
2105- border-bottom: none;
2106- color: #000;
2107- font-weight: bold;
2108- padding-bottom: 4px;
2109-}
2110-#akismetsearch {
2111- float: right;
2112- margin-top: -.5em;
2113-}
2114-
2115-#akismetsearch p {
2116- margin: 0;
2117- padding: 0;
2118-}
2119-</style>
2120-<div class="wrap">
2121-<h2><?php _e('Caught Spam') ?></h2>
2122-<?php
2123-$count = get_option( 'akismet_spam_count' );
2124-if ( $count ) {
2125-?>
2126-<p><?php printf(__('Akismet has caught <strong>%1$s spam</strong> for you since you first installed it.'), number_format_i18n($count) ); ?></p>
2127-<?php
2128-}
2129-
2130-$spam_count = akismet_spam_count();
2131-
2132-if ( 0 == $spam_count ) {
2133- echo '<p>'.__('You have no spam currently in the queue. Must be your lucky day. :)').'</p>';
2134- echo '</div>';
2135-} else {
2136- echo '<p>'.__('You can delete all of the spam from your database with a single click. This operation cannot be undone, so you may wish to check to ensure that no legitimate comments got through first. Spam is automatically deleted after 15 days, so don&#8217;t sweat it.').'</p>';
2137-?>
2138-<?php if ( !isset( $_POST['s'] ) ) { ?>
2139-<form method="post" action="<?php echo attribute_escape( add_query_arg( 'noheader', 'true' ) ); ?>">
2140-<?php akismet_nonce_field($akismet_nonce) ?>
2141-<input type="hidden" name="action" value="delete" />
2142-<?php printf(__('There are currently %1$s comments identified as spam.'), $spam_count); ?>&nbsp; &nbsp; <input type="submit" class="button delete" name="Submit" value="<?php _e('Delete all'); ?>" />
2143-<input type="hidden" name="display_time" value="<?php echo current_time('mysql', 1); ?>" />
2144-</form>
2145-<?php } ?>
2146-</div>
2147-<div class="wrap">
2148-<?php if ( isset( $_POST['s'] ) ) { ?>
2149-<h2><?php _e('Search'); ?></h2>
2150-<?php } else { ?>
2151-<?php echo '<p>'.__('These are the latest comments identified as spam by Akismet. If you see any mistakes, simply mark the comment as "not spam" and Akismet will learn from the submission. If you wish to recover a comment from spam, simply select the comment, and click Not Spam. After 15 days we clean out the junk for you.').'</p>'; ?>
2152-<?php } ?>
2153-<?php
2154-if ( isset( $_POST['s'] ) ) {
2155- $s = $wpdb->escape($_POST['s']);
2156- $comments = $wpdb->get_results("SELECT * FROM $wpdb->comments WHERE
2157- (comment_author LIKE '%$s%' OR
2158- comment_author_email LIKE '%$s%' OR
2159- comment_author_url LIKE ('%$s%') OR
2160- comment_author_IP LIKE ('%$s%') OR
2161- comment_content LIKE ('%$s%') ) AND
2162- comment_approved = 'spam'
2163- ORDER BY comment_date DESC");
2164-} else {
2165- if ( isset( $_GET['apage'] ) )
2166- $page = (int) $_GET['apage'];
2167- else
2168- $page = 1;
2169-
2170- if ( $page < 2 )
2171- $page = 1;
2172-
2173- $current_type = false;
2174- if ( isset( $_GET['ctype'] ) )
2175- $current_type = preg_replace( '|[^a-z]|', '', $_GET['ctype'] );
2176-
2177- $comments = akismet_spam_comments( $current_type, $page );
2178- $total = akismet_spam_count( $current_type );
2179- $totals = akismet_spam_totals();
2180-?>
2181-<ul class="akismet-tabs">
2182-<li <?php if ( !isset( $_GET['ctype'] ) ) echo ' class="active"'; ?>><a href="edit-comments.php?page=akismet-admin"><?php _e('All'); ?></a></li>
2183-<?php
2184-foreach ( $totals as $type => $type_count ) {
2185- if ( 'comment' == $type ) {
2186- $type = 'comments';
2187- $show = __('Comments');
2188- } else {
2189- $show = ucwords( $type );
2190- }
2191- $type_count = number_format_i18n( $type_count );
2192- $extra = $current_type === $type ? ' class="active"' : '';
2193- echo "<li $extra><a href='edit-comments.php?page=akismet-admin&amp;ctype=$type'>$show ($type_count)</a></li>";
2194-}
2195-do_action( 'akismet_tabs' ); // so plugins can add more tabs easily
2196-?>
2197-</ul>
2198-<?php
2199-}
2200-
2201-if ($comments) {
2202-?>
2203-<form method="post" action="<?php echo attribute_escape("$link?page=akismet-admin"); ?>" id="akismetsearch">
2204-<p> <input type="text" name="s" value="<?php if (isset($_POST['s'])) echo attribute_escape($_POST['s']); ?>" size="17" />
2205- <input type="submit" class="button" name="submit" value="<?php echo attribute_escape(__('Search Spam &raquo;')) ?>" /> </p>
2206-</form>
2207-<?php if ( $total > 50 ) {
2208-$total_pages = ceil( $total / 50 );
2209-$r = '';
2210-if ( 1 < $page ) {
2211- $args['apage'] = ( 1 == $page - 1 ) ? '' : $page - 1;
2212- $r .= '<a class="prev" href="' . clean_url(add_query_arg( $args )) . '">'. __('&laquo; Previous Page') .'</a>' . "\n";
2213-}
2214-if ( ( $total_pages = ceil( $total / 50 ) ) > 1 ) {
2215- for ( $page_num = 1; $page_num <= $total_pages; $page_num++ ) :
2216- if ( $page == $page_num ) :
2217- $r .= "<strong>$page_num</strong>\n";
2218- else :
2219- $p = false;
2220- if ( $page_num < 3 || ( $page_num >= $page - 3 && $page_num <= $page + 3 ) || $page_num > $total_pages - 3 ) :
2221- $args['apage'] = ( 1 == $page_num ) ? '' : $page_num;
2222- $r .= '<a class="page-numbers" href="' . clean_url(add_query_arg($args)) . '">' . ( $page_num ) . "</a>\n";
2223- $in = true;
2224- elseif ( $in == true ) :
2225- $r .= "...\n";
2226- $in = false;
2227- endif;
2228- endif;
2229- endfor;
2230-}
2231-if ( ( $page ) * 50 < $total || -1 == $total ) {
2232- $args['apage'] = $page + 1;
2233- $r .= '<a class="next" href="' . clean_url(add_query_arg($args)) . '">'. __('Next Page &raquo;') .'</a>' . "\n";
2234-}
2235-echo "<p>$r</p>";
2236-?>
2237-
2238-<?php } ?>
2239-<form style="clear: both;" method="post" action="<?php echo attribute_escape( add_query_arg( 'noheader', 'true' ) ); ?>">
2240-<?php akismet_nonce_field($akismet_nonce) ?>
2241-<input type="hidden" name="action" value="recover" />
2242-<ul id="spam-list" class="commentlist" style="list-style: none; margin: 0; padding: 0;">
2243-<?php
2244-$i = 0;
2245-foreach($comments as $comment) {
2246- $i++;
2247- $comment_date = mysql2date(get_option("date_format") . " @ " . get_option("time_format"), $comment->comment_date);
2248- $post = get_post($comment->comment_post_ID);
2249- $post_title = $post->post_title;
2250- if ($i % 2) $class = 'class="alternate"';
2251- else $class = '';
2252- echo "\n\t<li id='comment-$comment->comment_ID' $class>";
2253- ?>
2254-
2255-<p><strong><?php comment_author() ?></strong> <?php if ($comment->comment_author_email) { ?>| <?php comment_author_email_link() ?> <?php } if ($comment->comment_author_url && 'http://' != $comment->comment_author_url) { ?> | <?php comment_author_url_link() ?> <?php } ?>| <?php _e('IP:') ?> <a href="http://ws.arin.net/cgi-bin/whois.pl?queryinput=<?php comment_author_IP() ?>"><?php comment_author_IP() ?></a></p>
2256-
2257-<?php comment_text() ?>
2258-
2259-<p><label for="spam-<?php echo $comment->comment_ID; ?>">
2260-<input type="checkbox" id="spam-<?php echo $comment->comment_ID; ?>" name="not_spam[]" value="<?php echo $comment->comment_ID; ?>" />
2261-<?php _e('Not Spam') ?></label> &#8212; <?php comment_date('M j, g:i A'); ?> &#8212; [
2262-<?php
2263-$post = get_post($comment->comment_post_ID);
2264-$post_title = wp_specialchars( $post->post_title, 'double' );
2265-$post_title = ('' == $post_title) ? "# $comment->comment_post_ID" : $post_title;
2266-?>
2267- <a href="<?php echo get_permalink($comment->comment_post_ID); ?>" title="<?php echo $post_title; ?>"><?php _e('View Post') ?></a> ] </p>
2268-
2269-
2270-<?php
2271-}
2272-?>
2273-</ul>
2274-<?php if ( $total > 50 ) {
2275-$total_pages = ceil( $total / 50 );
2276-$r = '';
2277-if ( 1 < $page ) {
2278- $args['apage'] = ( 1 == $page - 1 ) ? '' : $page - 1;
2279- $r .= '<a class="prev" href="' . clean_url(add_query_arg( $args )) . '">'. __('&laquo; Previous Page') .'</a>' . "\n";
2280-}
2281-if ( ( $total_pages = ceil( $total / 50 ) ) > 1 ) {
2282- for ( $page_num = 1; $page_num <= $total_pages; $page_num++ ) :
2283- if ( $page == $page_num ) :
2284- $r .= "<strong>$page_num</strong>\n";
2285- else :
2286- $p = false;
2287- if ( $page_num < 3 || ( $page_num >= $page - 3 && $page_num <= $page + 3 ) || $page_num > $total_pages - 3 ) :
2288- $args['apage'] = ( 1 == $page_num ) ? '' : $page_num;
2289- $r .= '<a class="page-numbers" href="' . clean_url(add_query_arg($args)) . '">' . ( $page_num ) . "</a>\n";
2290- $in = true;
2291- elseif ( $in == true ) :
2292- $r .= "...\n";
2293- $in = false;
2294- endif;
2295- endif;
2296- endfor;
2297-}
2298-if ( ( $page ) * 50 < $total || -1 == $total ) {
2299- $args['apage'] = $page + 1;
2300- $r .= '<a class="next" href="' . clean_url(add_query_arg($args)) . '">'. __('Next Page &raquo;') .'</a>' . "\n";
2301-}
2302-echo "<p>$r</p>";
2303-}
2304-?>
2305-<p class="submit">
2306-<input type="submit" name="submit" value="<?php echo attribute_escape(__('De-spam marked comments &raquo;')); ?>" />
2307-</p>
2308-<p><?php _e('Comments you de-spam will be submitted to Akismet as mistakes so it can learn and get better.'); ?></p>
2309-</form>
2310-<?php
2311-} else {
2312-?>
2313-<p><?php _e('No results found.'); ?></p>
2314-<?php } ?>
2315-
2316-<?php if ( !isset( $_POST['s'] ) ) { ?>
2317-<form method="post" action="<?php echo attribute_escape( add_query_arg( 'noheader', 'true' ) ); ?>">
2318-<?php akismet_nonce_field($akismet_nonce) ?>
2319-<p><input type="hidden" name="action" value="delete" />
2320-<?php printf(__('There are currently %1$s comments identified as spam.'), $spam_count); ?>&nbsp; &nbsp; <input type="submit" name="Submit" class="button" value="<?php echo attribute_escape(__('Delete all')); ?>" />
2321-<input type="hidden" name="display_time" value="<?php echo current_time('mysql', 1); ?>" /></p>
2322-</form>
2323-<?php } ?>
2324-</div>
2325-<?php
2326- }
2327-}
2328-
2329-add_action('admin_menu', 'akismet_manage_page');
2330-
2331-// WP < 2.5
2332-function akismet_stats() {
2333- if ( !function_exists('did_action') || did_action( 'rightnow_end' ) ) // We already displayed this info in the "Right Now" section
2334- return;
2335- if ( !$count = get_option('akismet_spam_count') )
2336- return;
2337- $path = plugin_basename(__FILE__);
2338- echo '<h3>'.__('Spam').'</h3>';
2339- global $submenu;
2340- if ( isset( $submenu['edit-comments.php'] ) )
2341- $link = 'edit-comments.php';
2342- else
2343- $link = 'edit.php';
2344- echo '<p>'.sprintf(__('<a href="%1$s">Akismet</a> has protected your site from <a href="%2$s">%3$s spam comments</a>.'), 'http://akismet.com/', clean_url("$link?page=akismet-admin"), number_format_i18n($count) ).'</p>';
2345-}
2346-
2347-add_action('activity_box_end', 'akismet_stats');
2348-
2349-// WP 2.5+
2350-function akismet_rightnow() {
2351- global $submenu, $wp_db_version;
2352-
2353- if ( 8645 < $wp_db_version ) // 2.7
2354- $link = 'edit-comments.php?comment_status=spam';
2355- elseif ( isset( $submenu['edit-comments.php'] ) )
2356- $link = 'edit-comments.php?page=akismet-admin';
2357- else
2358- $link = 'edit.php?page=akismet-admin';
2359-
2360- if ( $count = get_option('akismet_spam_count') ) {
2361- $intro = sprintf( __ngettext(
2362- '<a href="%1$s">Akismet</a> has protected your site from %2$s spam comment already,',
2363- '<a href="%1$s">Akismet</a> has protected your site from %2$s spam comments already,',
2364- $count
2365- ), 'http://akismet.com/', number_format_i18n( $count ) );
2366- } else {
2367- $intro = sprintf( __('<a href="%1$s">Akismet</a> blocks spam from getting to your blog,'), 'http://akismet.com/' );
2368- }
2369-
2370- if ( $queue_count = akismet_spam_count() ) {
2371- $queue_text = sprintf( __ngettext(
2372- 'and there\'s <a href="%2$s">%1$s comment</a> in your spam queue right now.',
2373- 'and there are <a href="%2$s">%1$s comments</a> in your spam queue right now.',
2374- $queue_count
2375- ), number_format_i18n( $queue_count ), clean_url($link) );
2376- } else {
2377- $queue_text = sprintf( __( "but there's nothing in your <a href='%1\$s'>spam queue</a> at the moment." ), clean_url($link) );
2378- }
2379-
2380- $text = sprintf( _c( '%1$s %2$s|akismet_rightnow' ), $intro, $queue_text );
2381-
2382- echo "<p class='akismet-right-now'>$text</p>\n";
2383-}
2384+ }
2385
2386-add_action('rightnow_end', 'akismet_rightnow');
2387-
2388-// For WP <= 2.3.x
2389-global $pagenow;
2390-
2391-if ( 'moderation.php' == $pagenow ) {
2392- function akismet_recheck_button( $page ) {
2393- global $submenu;
2394- if ( isset( $submenu['edit-comments.php'] ) )
2395- $link = 'edit-comments.php';
2396- else
2397- $link = 'edit.php';
2398- $button = "<a href='$link?page=akismet-admin&amp;recheckqueue=true&amp;noheader=true' style='display: block; width: 100px; position: absolute; right: 7%; padding: 5px; font-size: 14px; text-decoration: underline; background: #fff; border: 1px solid #ccc;'>" . __('Recheck Queue for Spam') . "</a>";
2399- $page = str_replace( '<div class="wrap">', '<div class="wrap">' . $button, $page );
2400- return $page;
2401- }
2402-
2403- if ( $wpdb->get_var( "SELECT COUNT(*) FROM $wpdb->comments WHERE comment_approved = '0'" ) )
2404- ob_start( 'akismet_recheck_button' );
2405-}
2406-
2407-// For WP >= 2.5
2408-function akismet_check_for_spam_button($comment_status) {
2409- if ( 'approved' == $comment_status )
2410- return;
2411- if ( function_exists('plugins_url') )
2412- $link = 'admin.php?action=akismet_recheck_queue';
2413- else
2414- $link = 'edit-comments.php?page=akismet-admin&amp;recheckqueue=true&amp;noheader=true';
2415- echo "</div><div class='alignleft'><a class='button-secondary checkforspam' href='$link'>" . __('Check for Spam') . "</a>";
2416-}
2417-add_action('manage_comments_nav', 'akismet_check_for_spam_button');
2418-
2419-function akismet_recheck_queue() {
2420- global $wpdb, $akismet_api_host, $akismet_api_port;
2421-
2422- if ( ! ( isset( $_GET['recheckqueue'] ) || ( isset( $_REQUEST['action'] ) && 'akismet_recheck_queue' == $_REQUEST['action'] ) ) )
2423- return;
2424-
2425- $moderation = $wpdb->get_results( "SELECT * FROM $wpdb->comments WHERE comment_approved = '0'", ARRAY_A );
2426- foreach ( (array) $moderation as $c ) {
2427- $c['user_ip'] = $c['comment_author_IP'];
2428- $c['user_agent'] = $c['comment_agent'];
2429- $c['referrer'] = '';
2430- $c['blog'] = get_option('home');
2431- $c['blog_lang'] = get_locale();
2432- $c['blog_charset'] = get_option('blog_charset');
2433- $c['permalink'] = get_permalink($c['comment_post_ID']);
2434- $c['user_role'] = akismet_get_user_roles($c['user_ID']);
2435- $id = (int) $c['comment_ID'];
2436-
2437- $query_string = '';
2438- foreach ( $c as $key => $data )
2439- $query_string .= $key . '=' . urlencode( stripslashes($data) ) . '&';
2440-
2441- $response = akismet_http_post($query_string, $akismet_api_host, '/1.1/comment-check', $akismet_api_port);
2442- if ( 'true' == $response[1] ) {
2443- $wpdb->query( "UPDATE $wpdb->comments SET comment_approved = 'spam' WHERE comment_ID = $id" );
2444- }
2445- }
2446- wp_redirect( $_SERVER['HTTP_REFERER'] );
2447- exit;
2448-}
2449-
2450-add_action('admin_action_akismet_recheck_queue', 'akismet_recheck_queue');
2451-
2452-function akismet_check_db_comment( $id ) {
2453- global $wpdb, $akismet_api_host, $akismet_api_port;
2454-
2455- $id = (int) $id;
2456- $c = $wpdb->get_row( "SELECT * FROM $wpdb->comments WHERE comment_ID = '$id'", ARRAY_A );
2457- if ( !$c )
2458- return;
2459-
2460- $c['user_ip'] = $c['comment_author_IP'];
2461- $c['user_agent'] = $c['comment_agent'];
2462- $c['referrer'] = '';
2463- $c['blog'] = get_option('home');
2464- $c['blog_lang'] = get_locale();
2465- $c['blog_charset'] = get_option('blog_charset');
2466- $c['permalink'] = get_permalink($c['comment_post_ID']);
2467- $id = $c['comment_ID'];
2468-
2469- $query_string = '';
2470- foreach ( $c as $key => $data )
2471- $query_string .= $key . '=' . urlencode( stripslashes($data) ) . '&';
2472-
2473- $response = akismet_http_post($query_string, $akismet_api_host, '/1.1/comment-check', $akismet_api_port);
2474- return $response[1];
2475-}
2476-
2477-// This option causes tons of FPs, was removed in 2.1
2478-function akismet_kill_proxy_check( $option ) { return 0; }
2479-add_filter('option_open_proxy_check', 'akismet_kill_proxy_check');
2480-
2481-// Widget stuff
2482-function widget_akismet_register() {
2483- if ( function_exists('register_sidebar_widget') ) :
2484- function widget_akismet($args) {
2485- extract($args);
2486- $options = get_option('widget_akismet');
2487- $count = number_format_i18n(get_option('akismet_spam_count'));
2488- ?>
2489- <?php echo $before_widget; ?>
2490- <?php echo $before_title . $options['title'] . $after_title; ?>
2491- <div id="akismetwrap"><div id="akismetstats"><a id="aka" href="http://akismet.com" title=""><?php printf( __( '%1$s %2$sspam comments%3$s %4$sblocked by%5$s<br />%6$sAkismet%7$s' ), '<span id="akismet1"><span id="akismetcount">' . $count . '</span>', '<span id="akismetsc">', '</span></span>', '<span id="akismet2"><span id="akismetbb">', '</span>', '<span id="akismeta">', '</span></span>' ); ?></a></div></div>
2492- <?php echo $after_widget; ?>
2493- <?php
2494- }
2495-
2496- function widget_akismet_style() {
2497- ?>
2498-<style type="text/css">
2499-#aka,#aka:link,#aka:hover,#aka:visited,#aka:active{color:#fff;text-decoration:none}
2500-#aka:hover{border:none;text-decoration:none}
2501-#aka:hover #akismet1{display:none}
2502-#aka:hover #akismet2,#akismet1{display:block}
2503-#akismet2{display:none;padding-top:2px}
2504-#akismeta{font-size:16px;font-weight:bold;line-height:18px;text-decoration:none}
2505-#akismetcount{display:block;font:15px Verdana,Arial,Sans-Serif;font-weight:bold;text-decoration:none}
2506-#akismetwrap #akismetstats{background:url(<?php echo get_option('siteurl'); ?>/wp-content/plugins/akismet/akismet.gif) no-repeat top left;border:none;color:#fff;font:11px 'Trebuchet MS','Myriad Pro',sans-serif;height:40px;line-height:100%;overflow:hidden;padding:8px 0 0;text-align:center;width:120px}
2507-</style>
2508- <?php
2509- }
2510-
2511- function widget_akismet_control() {
2512- $options = $newoptions = get_option('widget_akismet');
2513- if ( $_POST["akismet-submit"] ) {
2514- $newoptions['title'] = strip_tags(stripslashes($_POST["akismet-title"]));
2515- if ( empty($newoptions['title']) ) $newoptions['title'] = __('Spam Blocked');
2516- }
2517- if ( $options != $newoptions ) {
2518- $options = $newoptions;
2519- update_option('widget_akismet', $options);
2520- }
2521- $title = htmlspecialchars($options['title'], ENT_QUOTES);
2522- ?>
2523- <p><label for="akismet-title"><?php _e('Title:'); ?> <input style="width: 250px;" id="akismet-title" name="akismet-title" type="text" value="<?php echo $title; ?>" /></label></p>
2524- <input type="hidden" id="akismet-submit" name="akismet-submit" value="1" />
2525- <?php
2526- }
2527-
2528- register_sidebar_widget('Akismet', 'widget_akismet', null, 'akismet');
2529- register_widget_control('Akismet', 'widget_akismet_control', null, 75, 'akismet');
2530- if ( is_active_widget('widget_akismet') )
2531- add_action('wp_head', 'widget_akismet_style');
2532- endif;
2533-}
2534-
2535-add_action('init', 'widget_akismet_register');
2536-
2537-// Counter for non-widget users
2538-function akismet_counter() {
2539-?>
2540-<style type="text/css">
2541-#akismetwrap #aka,#aka:link,#aka:hover,#aka:visited,#aka:active{color:#fff;text-decoration:none}
2542-#aka:hover{border:none;text-decoration:none}
2543-#aka:hover #akismet1{display:none}
2544-#aka:hover #akismet2,#akismet1{display:block}
2545-#akismet2{display:none;padding-top:2px}
2546-#akismeta{font-size:16px;font-weight:bold;line-height:18px;text-decoration:none}
2547-#akismetcount{display:block;font:15px Verdana,Arial,Sans-Serif;font-weight:bold;text-decoration:none}
2548-#akismetwrap #akismetstats{background:url(<?php echo get_option('siteurl'); ?>/wp-content/plugins/akismet/akismet.gif) no-repeat top left;border:none;color:#fff;font:11px 'Trebuchet MS','Myriad Pro',sans-serif;height:40px;line-height:100%;overflow:hidden;padding:8px 0 0;text-align:center;width:120px}
2549-</style>
2550-<?php
2551-$count = number_format_i18n(get_option('akismet_spam_count'));
2552-?>
2553-<div id="akismetwrap"><div id="akismetstats"><a id="aka" href="http://akismet.com" title=""><div id="akismet1"><span id="akismetcount"><?php echo $count; ?></span> <span id="akismetsc"><?php _e('spam comments') ?></span></div> <div id="akismet2"><span id="akismetbb"><?php _e('blocked by') ?></span><br /><span id="akismeta">Akismet</span></div></a></div></div>
2554-<?php
2555-}
2556-
2557-?>
2558+ $remaining = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM $wpdb->commentmeta WHERE meta_key = 'akismet_error'" ) );
2559+ if ( $remaining && !wp_next_scheduled('akismet_schedule_cron_recheck') ) {
2560+ wp_schedule_single_event( time() + 1200, 'akismet_schedule_cron_recheck' );
2561+ }
2562+}
2563+add_action( 'akismet_schedule_cron_recheck', 'akismet_cron_recheck' );
2564+
2565+function akismet_add_comment_nonce( $post_id ) {
2566+ echo '<p style="display: none;">';
2567+ wp_nonce_field( 'akismet_comment_nonce_' . $post_id, 'akismet_comment_nonce', FALSE );
2568+ echo '</p>';
2569+}
2570+
2571+$akismet_comment_nonce_option = apply_filters( 'akismet_comment_nonce', get_option( 'akismet_comment_nonce' ) );
2572+
2573+if ( $akismet_comment_nonce_option == 'true' || $akismet_comment_nonce_option == '' )
2574+ add_action( 'comment_form', 'akismet_add_comment_nonce' );
2575
2576=== added file 'wp-content/plugins/akismet/legacy.php'
2577--- wp-content/plugins/akismet/legacy.php 1970-01-01 00:00:00 +0000
2578+++ wp-content/plugins/akismet/legacy.php 2011-01-25 16:02:14 +0000
2579@@ -0,0 +1,396 @@
2580+<?php
2581+
2582+function akismet_spam_comments( $type = false, $page = 1, $per_page = 50 ) {
2583+ global $wpdb;
2584+
2585+ $page = (int) $page;
2586+ if ( $page < 2 )
2587+ $page = 1;
2588+
2589+ $per_page = (int) $per_page;
2590+ if ( $per_page < 1 )
2591+ $per_page = 50;
2592+
2593+ $start = ( $page - 1 ) * $per_page;
2594+ $end = $start + $per_page;
2595+
2596+ if ( $type ) {
2597+ if ( 'comments' == $type || 'comment' == $type )
2598+ $type = '';
2599+ else
2600+ $type = $wpdb->escape( $type );
2601+ return $wpdb->get_results( "SELECT * FROM $wpdb->comments WHERE comment_approved = 'spam' AND comment_type='$type' ORDER BY comment_date DESC LIMIT $start, $end");
2602+ }
2603+
2604+ // All
2605+ return $wpdb->get_results( "SELECT * FROM $wpdb->comments WHERE comment_approved = 'spam' ORDER BY comment_date DESC LIMIT $start, $end");
2606+}
2607+
2608+// Totals for each comment type
2609+// returns array( type => count, ... )
2610+function akismet_spam_totals() {
2611+ global $wpdb;
2612+ $totals = $wpdb->get_results( "SELECT comment_type, COUNT(*) AS cc FROM $wpdb->comments WHERE comment_approved = 'spam' GROUP BY comment_type" );
2613+ $return = array();
2614+ foreach ( $totals as $total )
2615+ $return[$total->comment_type ? $total->comment_type : 'comment'] = $total->cc;
2616+ return $return;
2617+}
2618+
2619+function akismet_manage_page() {
2620+ global $wpdb, $submenu, $wp_db_version;
2621+
2622+ // WP 2.7 has its own spam management page
2623+ if ( 8645 <= $wp_db_version )
2624+ return;
2625+
2626+ $count = sprintf(__('Akismet Spam (%s)'), akismet_spam_count());
2627+ if ( isset( $submenu['edit-comments.php'] ) )
2628+ add_submenu_page('edit-comments.php', __('Akismet Spam'), $count, 'moderate_comments', 'akismet-admin', 'akismet_caught' );
2629+ elseif ( function_exists('add_management_page') )
2630+ add_management_page(__('Akismet Spam'), $count, 'moderate_comments', 'akismet-admin', 'akismet_caught');
2631+}
2632+
2633+function akismet_caught() {
2634+ global $wpdb, $comment, $akismet_caught, $akismet_nonce;
2635+
2636+ akismet_recheck_queue();
2637+ if (isset($_POST['submit']) && 'recover' == $_POST['action'] && ! empty($_POST['not_spam'])) {
2638+ check_admin_referer( $akismet_nonce );
2639+ if ( function_exists('current_user_can') && !current_user_can('moderate_comments') )
2640+ die(__('You do not have sufficient permission to moderate comments.'));
2641+
2642+ $i = 0;
2643+ foreach ($_POST['not_spam'] as $comment):
2644+ $comment = (int) $comment;
2645+ if ( function_exists('wp_set_comment_status') )
2646+ wp_set_comment_status($comment, 'approve');
2647+ else
2648+ $wpdb->query("UPDATE $wpdb->comments SET comment_approved = '1' WHERE comment_ID = '$comment'");
2649+ akismet_submit_nonspam_comment($comment);
2650+ ++$i;
2651+ endforeach;
2652+ $to = add_query_arg( 'recovered', $i, $_SERVER['HTTP_REFERER'] );
2653+ wp_redirect( $to );
2654+ exit;
2655+ }
2656+ if ('delete' == $_POST['action']) {
2657+ check_admin_referer( $akismet_nonce );
2658+ if ( function_exists('current_user_can') && !current_user_can('moderate_comments') )
2659+ die(__('You do not have sufficient permission to moderate comments.'));
2660+
2661+ $delete_time = $wpdb->escape( $_POST['display_time'] );
2662+ $comment_ids = $wpdb->get_col( "SELECT comment_id FROM $wpdb->comments WHERE comment_approved = 'spam' AND '$delete_time' > comment_date_gmt" );
2663+ if ( !empty( $comment_ids ) ) {
2664+ do_action( 'delete_comment', $comment_ids );
2665+ $wpdb->query( "DELETE FROM $wpdb->comments WHERE comment_id IN ( " . implode( ', ', $comment_ids ) . " )");
2666+ wp_cache_delete( 'akismet_spam_count', 'widget' );
2667+ }
2668+ $to = add_query_arg( 'deleted', 'all', $_SERVER['HTTP_REFERER'] );
2669+ wp_redirect( $to );
2670+ exit;
2671+ }
2672+
2673+if ( isset( $_GET['recovered'] ) ) {
2674+ $i = (int) $_GET['recovered'];
2675+ echo '<div class="updated"><p>' . sprintf(__('%1$s comments recovered.'), $i) . "</p></div>";
2676+}
2677+
2678+if (isset( $_GET['deleted'] ) )
2679+ echo '<div class="updated"><p>' . __('All spam deleted.') . '</p></div>';
2680+
2681+if ( isset( $GLOBALS['submenu']['edit-comments.php'] ) )
2682+ $link = 'edit-comments.php';
2683+else
2684+ $link = 'edit.php';
2685+?>
2686+<style type="text/css">
2687+.akismet-tabs {
2688+ list-style: none;
2689+ margin: 0;
2690+ padding: 0;
2691+ clear: both;
2692+ border-bottom: 1px solid #ccc;
2693+ height: 31px;
2694+ margin-bottom: 20px;
2695+ background: #ddd;
2696+ border-top: 1px solid #bdbdbd;
2697+}
2698+.akismet-tabs li {
2699+ float: left;
2700+ margin: 5px 0 0 20px;
2701+}
2702+.akismet-tabs a {
2703+ display: block;
2704+ padding: 4px .5em 3px;
2705+ border-bottom: none;
2706+ color: #036;
2707+}
2708+.akismet-tabs .active a {
2709+ background: #fff;
2710+ border: 1px solid #ccc;
2711+ border-bottom: none;
2712+ color: #000;
2713+ font-weight: bold;
2714+ padding-bottom: 4px;
2715+}
2716+#akismetsearch {
2717+ float: right;
2718+ margin-top: -.5em;
2719+}
2720+
2721+#akismetsearch p {
2722+ margin: 0;
2723+ padding: 0;
2724+}
2725+</style>
2726+<div class="wrap">
2727+<h2><?php _e('Caught Spam') ?></h2>
2728+<?php
2729+$count = get_option( 'akismet_spam_count' );
2730+if ( $count ) {
2731+?>
2732+<p><?php printf(__('Akismet has caught <strong>%1$s spam</strong> for you since you first installed it.'), number_format_i18n($count) ); ?></p>
2733+<?php
2734+}
2735+
2736+$spam_count = akismet_spam_count();
2737+
2738+if ( 0 == $spam_count ) {
2739+ echo '<p>'.__('You have no spam currently in the queue. Must be your lucky day. :)').'</p>';
2740+ echo '</div>';
2741+} else {
2742+ echo '<p>'.__('You can delete all of the spam from your database with a single click. This operation cannot be undone, so you may wish to check to ensure that no legitimate comments got through first. Spam is automatically deleted after 15 days, so don&#8217;t sweat it.').'</p>';
2743+?>
2744+<?php if ( !isset( $_POST['s'] ) ) { ?>
2745+<form method="post" action="<?php echo attribute_escape( add_query_arg( 'noheader', 'true' ) ); ?>">
2746+<?php akismet_nonce_field($akismet_nonce) ?>
2747+<input type="hidden" name="action" value="delete" />
2748+<?php printf(__('There are currently %1$s comments identified as spam.'), $spam_count); ?>&nbsp; &nbsp; <input type="submit" class="button delete" name="Submit" value="<?php _e('Delete all'); ?>" />
2749+<input type="hidden" name="display_time" value="<?php echo current_time('mysql', 1); ?>" />
2750+</form>
2751+<?php } ?>
2752+</div>
2753+<div class="wrap">
2754+<?php if ( isset( $_POST['s'] ) ) { ?>
2755+<h2><?php _e('Search'); ?></h2>
2756+<?php } else { ?>
2757+<?php echo '<p>'.__('These are the latest comments identified as spam by Akismet. If you see any mistakes, simply mark the comment as "not spam" and Akismet will learn from the submission. If you wish to recover a comment from spam, simply select the comment, and click Not Spam. After 15 days we clean out the junk for you.').'</p>'; ?>
2758+<?php } ?>
2759+<?php
2760+if ( isset( $_POST['s'] ) ) {
2761+ $s = $wpdb->escape($_POST['s']);
2762+ $comments = $wpdb->get_results("SELECT * FROM $wpdb->comments WHERE
2763+ (comment_author LIKE '%$s%' OR
2764+ comment_author_email LIKE '%$s%' OR
2765+ comment_author_url LIKE ('%$s%') OR
2766+ comment_author_IP LIKE ('%$s%') OR
2767+ comment_content LIKE ('%$s%') ) AND
2768+ comment_approved = 'spam'
2769+ ORDER BY comment_date DESC");
2770+} else {
2771+ if ( isset( $_GET['apage'] ) )
2772+ $page = (int) $_GET['apage'];
2773+ else
2774+ $page = 1;
2775+
2776+ if ( $page < 2 )
2777+ $page = 1;
2778+
2779+ $current_type = false;
2780+ if ( isset( $_GET['ctype'] ) )
2781+ $current_type = preg_replace( '|[^a-z]|', '', $_GET['ctype'] );
2782+
2783+ $comments = akismet_spam_comments( $current_type, $page );
2784+ $total = akismet_spam_count( $current_type );
2785+ $totals = akismet_spam_totals();
2786+?>
2787+<ul class="akismet-tabs">
2788+<li <?php if ( !isset( $_GET['ctype'] ) ) echo ' class="active"'; ?>><a href="edit-comments.php?page=akismet-admin"><?php _e('All'); ?></a></li>
2789+<?php
2790+foreach ( $totals as $type => $type_count ) {
2791+ if ( 'comment' == $type ) {
2792+ $type = 'comments';
2793+ $show = __('Comments');
2794+ } else {
2795+ $show = ucwords( $type );
2796+ }
2797+ $type_count = number_format_i18n( $type_count );
2798+ $extra = $current_type === $type ? ' class="active"' : '';
2799+ echo "<li $extra><a href='edit-comments.php?page=akismet-admin&amp;ctype=$type'>$show ($type_count)</a></li>";
2800+}
2801+do_action( 'akismet_tabs' ); // so plugins can add more tabs easily
2802+?>
2803+</ul>
2804+<?php
2805+}
2806+
2807+if ($comments) {
2808+?>
2809+<form method="post" action="<?php echo attribute_escape("$link?page=akismet-admin"); ?>" id="akismetsearch">
2810+<p> <input type="text" name="s" value="<?php if (isset($_POST['s'])) echo attribute_escape($_POST['s']); ?>" size="17" />
2811+ <input type="submit" class="button" name="submit" value="<?php echo attribute_escape(__('Search Spam &raquo;')) ?>" /> </p>
2812+</form>
2813+<?php if ( $total > 50 ) {
2814+$total_pages = ceil( $total / 50 );
2815+$r = '';
2816+if ( 1 < $page ) {
2817+ $args['apage'] = ( 1 == $page - 1 ) ? '' : $page - 1;
2818+ $r .= '<a class="prev" href="' . clean_url(add_query_arg( $args )) . '">'. __('&laquo; Previous Page') .'</a>' . "\n";
2819+}
2820+if ( ( $total_pages = ceil( $total / 50 ) ) > 1 ) {
2821+ for ( $page_num = 1; $page_num <= $total_pages; $page_num++ ) :
2822+ if ( $page == $page_num ) :
2823+ $r .= "<strong>$page_num</strong>\n";
2824+ else :
2825+ $p = false;
2826+ if ( $page_num < 3 || ( $page_num >= $page - 3 && $page_num <= $page + 3 ) || $page_num > $total_pages - 3 ) :
2827+ $args['apage'] = ( 1 == $page_num ) ? '' : $page_num;
2828+ $r .= '<a class="page-numbers" href="' . clean_url(add_query_arg($args)) . '">' . ( $page_num ) . "</a>\n";
2829+ $in = true;
2830+ elseif ( $in == true ) :
2831+ $r .= "...\n";
2832+ $in = false;
2833+ endif;
2834+ endif;
2835+ endfor;
2836+}
2837+if ( ( $page ) * 50 < $total || -1 == $total ) {
2838+ $args['apage'] = $page + 1;
2839+ $r .= '<a class="next" href="' . clean_url(add_query_arg($args)) . '">'. __('Next Page &raquo;') .'</a>' . "\n";
2840+}
2841+echo "<p>$r</p>";
2842+?>
2843+
2844+<?php } ?>
2845+<form style="clear: both;" method="post" action="<?php echo attribute_escape( add_query_arg( 'noheader', 'true' ) ); ?>">
2846+<?php akismet_nonce_field($akismet_nonce) ?>
2847+<input type="hidden" name="action" value="recover" />
2848+<ul id="spam-list" class="commentlist" style="list-style: none; margin: 0; padding: 0;">
2849+<?php
2850+$i = 0;
2851+foreach($comments as $comment) {
2852+ $i++;
2853+ $comment_date = mysql2date(get_option("date_format") . " @ " . get_option("time_format"), $comment->comment_date);
2854+ $post = get_post($comment->comment_post_ID);
2855+ $post_title = $post->post_title;
2856+ if ($i % 2) $class = 'class="alternate"';
2857+ else $class = '';
2858+ echo "\n\t<li id='comment-$comment->comment_ID' $class>";
2859+ ?>
2860+
2861+<p><strong><?php comment_author() ?></strong> <?php if ($comment->comment_author_email) { ?>| <?php comment_author_email_link() ?> <?php } if ($comment->comment_author_url && 'http://' != $comment->comment_author_url) { ?> | <?php comment_author_url_link() ?> <?php } ?>| <?php _e('IP:') ?> <a href="http://ws.arin.net/cgi-bin/whois.pl?queryinput=<?php comment_author_IP() ?>"><?php comment_author_IP() ?></a></p>
2862+
2863+<?php comment_text() ?>
2864+
2865+<p><label for="spam-<?php echo $comment->comment_ID; ?>">
2866+<input type="checkbox" id="spam-<?php echo $comment->comment_ID; ?>" name="not_spam[]" value="<?php echo $comment->comment_ID; ?>" />
2867+<?php _e('Not Spam') ?></label> &#8212; <?php comment_date('M j, g:i A'); ?> &#8212; [
2868+<?php
2869+$post = get_post($comment->comment_post_ID);
2870+$post_title = wp_specialchars( $post->post_title, 'double' );
2871+$post_title = ('' == $post_title) ? "# $comment->comment_post_ID" : $post_title;
2872+?>
2873+ <a href="<?php echo get_permalink($comment->comment_post_ID); ?>" title="<?php echo $post_title; ?>"><?php _e('View Post') ?></a> ] </p>
2874+
2875+
2876+<?php
2877+}
2878+?>
2879+</ul>
2880+<?php if ( $total > 50 ) {
2881+$total_pages = ceil( $total / 50 );
2882+$r = '';
2883+if ( 1 < $page ) {
2884+ $args['apage'] = ( 1 == $page - 1 ) ? '' : $page - 1;
2885+ $r .= '<a class="prev" href="' . clean_url(add_query_arg( $args )) . '">'. __('&laquo; Previous Page') .'</a>' . "\n";
2886+}
2887+if ( ( $total_pages = ceil( $total / 50 ) ) > 1 ) {
2888+ for ( $page_num = 1; $page_num <= $total_pages; $page_num++ ) :
2889+ if ( $page == $page_num ) :
2890+ $r .= "<strong>$page_num</strong>\n";
2891+ else :
2892+ $p = false;
2893+ if ( $page_num < 3 || ( $page_num >= $page - 3 && $page_num <= $page + 3 ) || $page_num > $total_pages - 3 ) :
2894+ $args['apage'] = ( 1 == $page_num ) ? '' : $page_num;
2895+ $r .= '<a class="page-numbers" href="' . clean_url(add_query_arg($args)) . '">' . ( $page_num ) . "</a>\n";
2896+ $in = true;
2897+ elseif ( $in == true ) :
2898+ $r .= "...\n";
2899+ $in = false;
2900+ endif;
2901+ endif;
2902+ endfor;
2903+}
2904+if ( ( $page ) * 50 < $total || -1 == $total ) {
2905+ $args['apage'] = $page + 1;
2906+ $r .= '<a class="next" href="' . clean_url(add_query_arg($args)) . '">'. __('Next Page &raquo;') .'</a>' . "\n";
2907+}
2908+echo "<p>$r</p>";
2909+}
2910+?>
2911+<p class="submit">
2912+<input type="submit" name="submit" value="<?php echo attribute_escape(__('De-spam marked comments &raquo;')); ?>" />
2913+</p>
2914+<p><?php _e('Comments you de-spam will be submitted to Akismet as mistakes so it can learn and get better.'); ?></p>
2915+</form>
2916+<?php
2917+} else {
2918+?>
2919+<p><?php _e('No results found.'); ?></p>
2920+<?php } ?>
2921+
2922+<?php if ( !isset( $_POST['s'] ) ) { ?>
2923+<form method="post" action="<?php echo attribute_escape( add_query_arg( 'noheader', 'true' ) ); ?>">
2924+<?php akismet_nonce_field($akismet_nonce) ?>
2925+<p><input type="hidden" name="action" value="delete" />
2926+<?php printf(__('There are currently %1$s comments identified as spam.'), $spam_count); ?>&nbsp; &nbsp; <input type="submit" name="Submit" class="button" value="<?php echo attribute_escape(__('Delete all')); ?>" />
2927+<input type="hidden" name="display_time" value="<?php echo current_time('mysql', 1); ?>" /></p>
2928+</form>
2929+<?php } ?>
2930+</div>
2931+<?php
2932+ }
2933+}
2934+
2935+add_action('admin_menu', 'akismet_manage_page');
2936+
2937+function redirect_old_akismet_urls( ) {
2938+ global $wp_db_version;
2939+ $script_name = array_pop( split( '/', $_SERVER['PHP_SELF'] ) );
2940+
2941+ $page = '';
2942+ if ( !empty( $_GET['page'] ) )
2943+ $page = $_GET['page'];
2944+
2945+ // 2.7 redirect for people who might have bookmarked the old page
2946+ if ( 8204 < $wp_db_version && ( 'edit-comments.php' == $script_name || 'edit.php' == $script_name ) && 'akismet-admin' == $page ) {
2947+ $new_url = esc_url( 'edit-comments.php?comment_status=spam' );
2948+ wp_redirect( $new_url, 301 );
2949+ exit;
2950+ }
2951+}
2952+add_action( 'admin_init', 'redirect_old_akismet_urls' );
2953+
2954+// For WP <= 2.3.x
2955+global $pagenow;
2956+
2957+if ( 'moderation.php' == $pagenow ) {
2958+ function akismet_recheck_button( $page ) {
2959+ global $submenu;
2960+ if ( isset( $submenu['edit-comments.php'] ) )
2961+ $link = 'edit-comments.php';
2962+ else
2963+ $link = 'edit.php';
2964+ $button = "<a href='$link?page=akismet-admin&amp;recheckqueue=true&amp;noheader=true' style='display: block; width: 100px; position: absolute; right: 7%; padding: 5px; font-size: 14px; text-decoration: underline; background: #fff; border: 1px solid #ccc;'>" . __('Recheck Queue for Spam') . "</a>";
2965+ $page = str_replace( '<div class="wrap">', '<div class="wrap">' . $button, $page );
2966+ return $page;
2967+ }
2968+
2969+ if ( $wpdb->get_var( "SELECT COUNT(*) FROM $wpdb->comments WHERE comment_approved = '0'" ) )
2970+ ob_start( 'akismet_recheck_button' );
2971+}
2972+
2973+// This option causes tons of FPs, was removed in 2.1
2974+function akismet_kill_proxy_check( $option ) { return 0; }
2975+add_filter('option_open_proxy_check', 'akismet_kill_proxy_check');
2976
2977=== modified file 'wp-content/plugins/akismet/readme.txt'
2978--- wp-content/plugins/akismet/readme.txt 2011-01-25 15:27:25 +0000
2979+++ wp-content/plugins/akismet/readme.txt 2011-01-25 16:02:14 +0000
2980@@ -1,9 +1,10 @@
2981 === Akismet ===
2982-Contributors: matt, ryan, andy, mdawaffe, tellyworth, automattic
2983+Contributors: matt, ryan, andy, mdawaffe, tellyworth, josephscott, lessbloat, automattic
2984 Tags: akismet, comments, spam
2985-Requires at least: 2.0
2986-Tested up to: 3.0
2987-Stable tag: 2.3.0
2988+Requires at least: 3.0
2989+Tested up to: 3.1
2990+Stable tag: 2.5.2
2991+License: GPLv2
2992
2993 Akismet checks your comments against the Akismet web service to see if they look like spam or not.
2994
2995@@ -12,11 +13,15 @@
2996 Akismet checks your comments against the Akismet web service to see if they look like spam or not and lets you
2997 review the spam it catches under your blog's "Comments" admin screen.
2998
2999-Want to show off how much spam Akismet has caught for you? Just put `<?php akismet_counter(); ?>` in your template.
3000-
3001-See also: [WP Stats plugin](http://wordpress.org/extend/plugins/stats/).
3002-
3003-PS: You'll need an [Akismet.com API key](http://akismet.com/get/) to use it.
3004+Major new features in Akismet 2.5 include:
3005+
3006+* A comment status history, so you can easily see which comments were caught or cleared by Akismet, and which were spammed or unspammed by a moderator
3007+* Links are highlighted in the comment body, to reveal hidden or misleading links
3008+* If your web host is unable to reach Akismet's servers, the plugin will automatically retry when your connection is back up
3009+* Moderators can see the number of approved comments for each user
3010+* Spam and Unspam reports now include more information, to help improve accuracy
3011+
3012+PS: You'll need an [Akismet.com API key](http://akismet.com/get/) to use it. Keys are free for personal blogs, with paid subscriptions available for businesses and commercial sites.
3013
3014 == Installation ==
3015
3016@@ -26,6 +31,59 @@
3017
3018 == Changelog ==
3019
3020+= 2.5.2 =
3021+
3022+* Properly format the comment count for author counts
3023+* Look for super admins on multisite installs when looking up user roles
3024+* Increase the HTTP request timeout
3025+* Removed padding for author approved count
3026+* Fix typo in function name
3027+* Set Akismet stats iframe height to fixed 2500px. Better to have one tall scroll bar than two side by side.
3028+
3029+= 2.5.1 =
3030+
3031+* Fix a bug that caused the "Auto delete" option to fail to discard comments correctly
3032+* Remove the comment nonce form field from the 'Akismet Configuration' page in favor of using a filter, akismet_comment_nonce
3033+* Fixed padding bug in "author" column of posts screen
3034+* Added margin-top to "cleared by ..." badges on dashboard
3035+* Fix possible error when calling akismet_cron_recheck()
3036+* Fix more PHP warnings
3037+* Clean up XHTML warnings for comment nonce
3038+* Fix for possible condition where scheduled comment re-checks could get stuck
3039+* Clean up the comment meta details after deleting a comment
3040+* Only show the status badge if the comment status has been changed by someone/something other than Akismet
3041+* Show a 'History' link in the row-actions
3042+* Translation fixes
3043+* Reduced font-size on author name
3044+* Moved "flagged by..." notification to top right corner of comment container and removed heavy styling
3045+* Hid "flagged by..." notification while on dashboard
3046+
3047+= 2.5.0 =
3048+
3049+* Track comment actions under 'Akismet Status' on the edit comment screen
3050+* Fix a few remaining deprecated function calls ( props Mike Glendinning )
3051+* Use HTTPS for the stats IFRAME when wp-admin is using HTTPS
3052+* Use the WordPress HTTP class if available
3053+* Move the admin UI code to a separate file, only loaded when needed
3054+* Add cron retry feature, to replace the old connectivity check
3055+* Display Akismet status badge beside each comment
3056+* Record history for each comment, and display it on the edit page
3057+* Record the complete comment as originally submitted in comment_meta, to use when reporting spam and ham
3058+* Highlight links in comment content
3059+* New option, "Show the number of comments you've approved beside each comment author."
3060+* New option, "Use a nonce on the comment form."
3061+
3062+= 2.4.0 =
3063+
3064+* Spell out that the license is GPLv2
3065+* Fix PHP warnings
3066+* Fix WordPress deprecated function calls
3067+* Fire the delete_comment action when deleting comments
3068+* Move code specific for older WP versions to legacy.php
3069+* General code clean up
3070+
3071+= 2.3.0 =
3072+
3073 * Fix "Are you sure" nonce message on config screen in WPMU
3074 * Fix XHTML compliance issue in sidebar widget
3075 * Change author link; remove some old references to WordPress.com accounts
3076
3077=== added file 'wp-content/plugins/akismet/widget.php'
3078--- wp-content/plugins/akismet/widget.php 1970-01-01 00:00:00 +0000
3079+++ wp-content/plugins/akismet/widget.php 2011-01-25 16:02:14 +0000
3080@@ -0,0 +1,90 @@
3081+<?php
3082+/**
3083+ * @package Akismet
3084+ */
3085+// Widget stuff
3086+function widget_akismet_register() {
3087+ if ( function_exists('register_sidebar_widget') ) :
3088+ function widget_akismet($args) {
3089+ extract($args);
3090+ $options = get_option('widget_akismet');
3091+ $count = get_option('akismet_spam_count');
3092+ ?>
3093+ <?php echo $before_widget; ?>
3094+ <?php echo $before_title . $options['title'] . $after_title; ?>
3095+ <div id="akismetwrap"><div id="akismetstats"><a id="aka" href="http://akismet.com" title=""><?php printf( _n( '%1$s%2$s%3$s %4$sspam comment%5$s %6$sblocked by%7$s<br />%8$sAkismet%9$s', '%1$s%2$s%3$s %4$sspam comments%5$s %6$sblocked by%7$s<br />%8$sAkismet%9$s', $count ), '<span id="akismet1"><span id="akismetcount">', number_format_i18n( $count ), '</span>', '<span id="akismetsc">', '</span></span>', '<span id="akismet2"><span id="akismetbb">', '</span>', '<span id="akismeta">', '</span></span>' ); ?></a></div></div>
3096+ <?php echo $after_widget; ?>
3097+ <?php
3098+ }
3099+
3100+ function widget_akismet_style() {
3101+ $plugin_dir = '/wp-content/plugins';
3102+ if ( defined( 'PLUGINDIR' ) )
3103+ $plugin_dir = '/' . PLUGINDIR;
3104+
3105+ ?>
3106+<style type="text/css">
3107+#aka,#aka:link,#aka:hover,#aka:visited,#aka:active{color:#fff;text-decoration:none}
3108+#aka:hover{border:none;text-decoration:none}
3109+#aka:hover #akismet1{display:none}
3110+#aka:hover #akismet2,#akismet1{display:block}
3111+#akismet2{display:none;padding-top:2px}
3112+#akismeta{font-size:16px;font-weight:bold;line-height:18px;text-decoration:none}
3113+#akismetcount{display:block;font:15px Verdana,Arial,Sans-Serif;font-weight:bold;text-decoration:none}
3114+#akismetwrap #akismetstats{background:url(<?php echo get_option('siteurl'), $plugin_dir; ?>/akismet/akismet.gif) no-repeat top left;border:none;color:#fff;font:11px 'Trebuchet MS','Myriad Pro',sans-serif;height:40px;line-height:100%;overflow:hidden;padding:8px 0 0;text-align:center;width:120px}
3115+</style>
3116+ <?php
3117+ }
3118+
3119+ function widget_akismet_control() {
3120+ $options = $newoptions = get_option('widget_akismet');
3121+ if ( isset( $_POST['akismet-submit'] ) && $_POST["akismet-submit"] ) {
3122+ $newoptions['title'] = strip_tags(stripslashes($_POST["akismet-title"]));
3123+ if ( empty($newoptions['title']) ) $newoptions['title'] = __('Spam Blocked');
3124+ }
3125+ if ( $options != $newoptions ) {
3126+ $options = $newoptions;
3127+ update_option('widget_akismet', $options);
3128+ }
3129+ $title = htmlspecialchars($options['title'], ENT_QUOTES);
3130+ ?>
3131+ <p><label for="akismet-title"><?php _e('Title:'); ?> <input style="width: 250px;" id="akismet-title" name="akismet-title" type="text" value="<?php echo $title; ?>" /></label></p>
3132+ <input type="hidden" id="akismet-submit" name="akismet-submit" value="1" />
3133+ <?php
3134+ }
3135+
3136+ if ( function_exists( 'wp_register_sidebar_widget' ) ) {
3137+ wp_register_sidebar_widget( 'akismet', 'Akismet', 'widget_akismet', null, 'akismet');
3138+ wp_register_widget_control( 'akismet', 'Akismet', 'widget_akismet_control', null, 75, 'akismet');
3139+ } else {
3140+ register_sidebar_widget('Akismet', 'widget_akismet', null, 'akismet');
3141+ register_widget_control('Akismet', 'widget_akismet_control', null, 75, 'akismet');
3142+ }
3143+ if ( is_active_widget('widget_akismet') )
3144+ add_action('wp_head', 'widget_akismet_style');
3145+ endif;
3146+}
3147+
3148+add_action('init', 'widget_akismet_register');
3149+
3150+// Counter for non-widget users
3151+function akismet_counter() {
3152+ $plugin_dir = '/wp-content/plugins';
3153+ if ( defined( 'PLUGINDIR' ) )
3154+ $plugin_dir = '/' . PLUGINDIR;
3155+
3156+?>
3157+<style type="text/css">
3158+#akismetwrap #aka,#aka:link,#aka:hover,#aka:visited,#aka:active{color:#fff;text-decoration:none}
3159+#aka:hover{border:none;text-decoration:none}
3160+#aka:hover #akismet1{display:none}
3161+#aka:hover #akismet2,#akismet1{display:block}
3162+#akismet2{display:none;padding-top:2px}
3163+#akismeta{font-size:16px;font-weight:bold;line-height:18px;text-decoration:none}
3164+#akismetcount{display:block;font:15px Verdana,Arial,Sans-Serif;font-weight:bold;text-decoration:none}
3165+#akismetwrap #akismetstats{background:url(<?php echo get_option('siteurl'), $plugin_dir; ?>/akismet/akismet.gif) no-repeat top left;border:none;color:#fff;font:11px 'Trebuchet MS','Myriad Pro',sans-serif;height:40px;line-height:100%;overflow:hidden;padding:8px 0 0;text-align:center;width:120px}
3166+</style>
3167+<?php
3168+$count = get_option('akismet_spam_count');
3169+printf( _n( '<div id="akismetwrap"><div id="akismetstats"><a id="aka" href="http://akismet.com" title=""><div id="akismet1"><span id="akismetcount">%1$s</span> <span id="akismetsc">spam comment</span></div> <div id="akismet2"><span id="akismetbb">blocked by</span><br /><span id="akismeta">Akismet</span></div></a></div></div>', '<div id="akismetwrap"><div id="akismetstats"><a id="aka" href="http://akismet.com" title=""><div id="akismet1"><span id="akismetcount">%1$s</span> <span id="akismetsc">spam comments</span></div> <div id="akismet2"><span id="akismetbb">blocked by</span><br /><span id="akismeta">Akismet</span></div></a></div></div>', $count ), number_format_i18n( $count ) );
3170+}
3171
3172=== modified file 'wp-includes/canonical.php'
3173--- wp-includes/canonical.php 2011-01-25 15:27:25 +0000
3174+++ wp-includes/canonical.php 2011-01-25 16:02:14 +0000
3175@@ -103,10 +103,6 @@
3176 } elseif ( is_single() && !empty($_GET['p']) && ! $redirect_url ) {
3177 if ( $redirect_url = get_permalink(get_query_var('p')) )
3178 $redirect['query'] = remove_query_arg(array('p', 'post_type'), $redirect['query']);
3179- if ( get_query_var( 'page' ) ) {
3180- $redirect_url = trailingslashit( $redirect_url ) . user_trailingslashit( get_query_var( 'page' ), 'single_paged' );
3181- $redirect['query'] = remove_query_arg( 'page', $redirect['query'] );
3182- }
3183 } elseif ( is_single() && !empty($_GET['name']) && ! $redirect_url ) {
3184 if ( $redirect_url = get_permalink( $wp_query->get_queried_object_id() ) )
3185 $redirect['query'] = remove_query_arg('name', $redirect['query']);
3186@@ -180,12 +176,18 @@
3187
3188 }
3189 } elseif ( is_single() && strpos($wp_rewrite->permalink_structure, '%category%') !== false ) {
3190- $category = get_term_by('slug', get_query_var('category_name'), 'category');
3191+ $category = get_category_by_path(get_query_var('category_name'));
3192 $post_terms = wp_get_object_terms($wp_query->get_queried_object_id(), 'category', array('fields' => 'tt_ids'));
3193 if ( (!$category || is_wp_error($category)) || ( !is_wp_error($post_terms) && !empty($post_terms) && !in_array($category->term_taxonomy_id, $post_terms) ) )
3194 $redirect_url = get_permalink($wp_query->get_queried_object_id());
3195 }
3196
3197+ // Post Paging
3198+ if ( is_singular() && get_query_var('page') && $redirect_url ) {
3199+ $redirect_url = trailingslashit( $redirect_url ) . user_trailingslashit( get_query_var( 'page' ), 'single_paged' );
3200+ $redirect['query'] = remove_query_arg( 'page', $redirect['query'] );
3201+ }
3202+
3203 // paging and feeds
3204 if ( get_query_var('paged') || is_feed() || get_query_var('cpage') ) {
3205 if ( !$redirect_url )
3206
3207=== modified file 'wp-includes/capabilities.php'
3208--- wp-includes/capabilities.php 2011-01-25 15:27:25 +0000
3209+++ wp-includes/capabilities.php 2011-01-25 16:02:14 +0000
3210@@ -799,9 +799,6 @@
3211 case 'remove_user':
3212 $caps[] = 'remove_users';
3213 break;
3214- case 'delete_user':
3215- $caps[] = 'delete_users';
3216- break;
3217 case 'promote_user':
3218 $caps[] = 'promote_users';
3219 break;
3220@@ -1028,10 +1025,13 @@
3221 case 'delete_user':
3222 case 'delete_users':
3223 // If multisite these caps are allowed only for super admins.
3224- if ( is_multisite() && !is_super_admin( $user_id ) )
3225+ if ( is_multisite() && !is_super_admin( $user_id ) ) {
3226 $caps[] = 'do_not_allow';
3227- else
3228+ } else {
3229+ if ( 'delete_user' == $cap )
3230+ $cap = 'delete_users';
3231 $caps[] = $cap;
3232+ }
3233 break;
3234 case 'create_users':
3235 if ( is_multisite() && !get_site_option( 'add_new_users' ) )
3236@@ -1079,9 +1079,6 @@
3237 function current_user_can_for_blog( $blog_id, $capability ) {
3238 $current_user = wp_get_current_user();
3239
3240- if ( is_multisite() && is_super_admin() )
3241- return true;
3242-
3243 if ( empty( $current_user ) )
3244 return false;
3245
3246
3247=== modified file 'wp-includes/comment.php'
3248--- wp-includes/comment.php 2011-01-25 15:27:25 +0000
3249+++ wp-includes/comment.php 2011-01-25 16:02:14 +0000
3250@@ -18,9 +18,8 @@
3251 * check fails. If any of the parameter contents match the blacklist of words,
3252 * then the check fails.
3253 *
3254- * If the comment is a trackback and part of the blogroll, then the trackback is
3255- * automatically whitelisted. If the comment author was approved before, then
3256- * the comment is automatically whitelisted.
3257+ * If the comment author was approved before, then the comment is
3258+ * automatically whitelisted.
3259 *
3260 * If none of the checks fail, then the failback is to set the check to pass
3261 * (return true).
3262@@ -80,16 +79,7 @@
3263
3264 // Comment whitelisting:
3265 if ( 1 == get_option('comment_whitelist')) {
3266- if ( 'trackback' == $comment_type || 'pingback' == $comment_type ) { // check if domain is in blogroll
3267- $uri = parse_url($url);
3268- $domain = $uri['host'];
3269- $uri = parse_url( home_url() );
3270- $home_domain = $uri['host'];
3271- if ( $wpdb->get_var($wpdb->prepare("SELECT link_id FROM $wpdb->links WHERE link_url LIKE (%s) LIMIT 1", '%'.$domain.'%')) || $domain == $home_domain )
3272- return true;
3273- else
3274- return false;
3275- } elseif ( $author != '' && $email != '' ) {
3276+ if ( 'trackback' != $comment_type && 'pingback' != $comment_type && $author != '' && $email != '' ) {
3277 // expected_slashed ($author, $email)
3278 $ok_to_comment = $wpdb->get_var("SELECT comment_approved FROM $wpdb->comments WHERE comment_author = '$author' AND comment_author_email = '$email' and comment_approved = '1' LIMIT 1");
3279 if ( ( 1 == $ok_to_comment ) &&
3280@@ -1654,7 +1644,7 @@
3281 trackback($tb_ping, $post_title, $excerpt, $post_id);
3282 $pinged[] = $tb_ping;
3283 } else {
3284- $wpdb->query( $wpdb->prepare("UPDATE $wpdb->posts SET to_ping = TRIM(REPLACE(to_ping, '$tb_ping', '')) WHERE ID = %d", $post_id) );
3285+ $wpdb->query( $wpdb->prepare("UPDATE $wpdb->posts SET to_ping = TRIM(REPLACE(to_ping, %s, '')) WHERE ID = %d", $tb_ping, $post_id) );
3286 }
3287 }
3288 }
3289
3290=== modified file 'wp-includes/formatting.php'
3291--- wp-includes/formatting.php 2011-01-25 15:27:25 +0000
3292+++ wp-includes/formatting.php 2011-01-25 16:02:14 +0000
3293@@ -2236,7 +2236,8 @@
3294
3295 // Replace ampersands and single quotes only when displaying.
3296 if ( 'display' == $_context ) {
3297- $url = preg_replace('/&([^#])(?![a-z]{2,8};)/', '&#038;$1', $url);
3298+ $url = wp_kses_normalize_entities( $url );
3299+ $url = str_replace( '&amp;', '&#038;', $url );
3300 $url = str_replace( "'", '&#039;', $url );
3301 }
3302
3303
3304=== modified file 'wp-includes/functions.php'
3305--- wp-includes/functions.php 2011-01-25 15:27:25 +0000
3306+++ wp-includes/functions.php 2011-01-25 16:02:14 +0000
3307@@ -2125,7 +2125,7 @@
3308 $siteurl = get_option( 'siteurl' );
3309 $upload_path = get_option( 'upload_path' );
3310 $upload_path = trim($upload_path);
3311- $main_override = defined( 'MULTISITE' ) && is_main_site();
3312+ $main_override = is_multisite() && defined( 'MULTISITE' ) && is_main_site();
3313 if ( empty($upload_path) ) {
3314 $dir = WP_CONTENT_DIR . '/uploads';
3315 } else {
3316
3317=== modified file 'wp-includes/kses.php'
3318--- wp-includes/kses.php 2011-01-25 15:27:25 +0000
3319+++ wp-includes/kses.php 2011-01-25 16:02:14 +0000
3320@@ -670,7 +670,7 @@
3321 break;
3322 }
3323
3324- if ( $arreach['name'] == 'style' ) {
3325+ if ( strtolower($arreach['name']) == 'style' ) {
3326 $orig_value = $arreach['value'];
3327
3328 $value = safecss_filter_attr($orig_value);
3329@@ -762,7 +762,7 @@
3330 # "value"
3331 {
3332 $thisval = $match[1];
3333- if ( in_array($attrname, $uris) )
3334+ if ( in_array(strtolower($attrname), $uris) )
3335 $thisval = wp_kses_bad_protocol($thisval, $allowed_protocols);
3336
3337 if(FALSE === array_key_exists($attrname, $attrarr)) {
3338@@ -778,7 +778,7 @@
3339 # 'value'
3340 {
3341 $thisval = $match[1];
3342- if ( in_array($attrname, $uris) )
3343+ if ( in_array(strtolower($attrname), $uris) )
3344 $thisval = wp_kses_bad_protocol($thisval, $allowed_protocols);
3345
3346 if(FALSE === array_key_exists($attrname, $attrarr)) {
3347@@ -794,7 +794,7 @@
3348 # value
3349 {
3350 $thisval = $match[1];
3351- if ( in_array($attrname, $uris) )
3352+ if ( in_array(strtolower($attrname), $uris) )
3353 $thisval = wp_kses_bad_protocol($thisval, $allowed_protocols);
3354
3355 if(FALSE === array_key_exists($attrname, $attrarr)) {
3356@@ -1017,14 +1017,9 @@
3357 * @return string Sanitized content
3358 */
3359 function wp_kses_bad_protocol_once($string, $allowed_protocols) {
3360- global $_kses_allowed_protocols;
3361- $_kses_allowed_protocols = $allowed_protocols;
3362-
3363- $string2 = preg_split('/:|&#58;|&#x3a;/i', $string, 2);
3364- if ( isset($string2[1]) && !preg_match('%/\?%', $string2[0]) )
3365- $string = wp_kses_bad_protocol_once2($string2[0]) . trim($string2[1]);
3366- else
3367- $string = preg_replace_callback('/^((&[^;]*;|[\sA-Za-z0-9])*)'.'(:|&#58;|&#[Xx]3[Aa];)\s*/', 'wp_kses_bad_protocol_once2', $string);
3368+ $string2 = preg_split( '/:|&#0*58;|&#x0*3a;/i', $string, 2 );
3369+ if ( isset($string2[1]) && ! preg_match('%/\?%', $string2[0]) )
3370+ $string = wp_kses_bad_protocol_once2( $string2[0], $allowed_protocols ) . trim( $string2[1] );
3371
3372 return $string;
3373 }
3374@@ -1038,29 +1033,19 @@
3375 * @access private
3376 * @since 1.0.0
3377 *
3378- * @param mixed $matches string or preg_replace_callback() matches array to check for bad protocols
3379+ * @param string $string URI scheme to check against the whitelist
3380+ * @param string $allowed_protocols Allowed protocols
3381 * @return string Sanitized content
3382 */
3383-function wp_kses_bad_protocol_once2($matches) {
3384- global $_kses_allowed_protocols;
3385-
3386- if ( is_array($matches) ) {
3387- if ( empty($matches[1]) )
3388- return '';
3389-
3390- $string = $matches[1];
3391- } else {
3392- $string = $matches;
3393- }
3394-
3395+function wp_kses_bad_protocol_once2( $string, $allowed_protocols ) {
3396 $string2 = wp_kses_decode_entities($string);
3397 $string2 = preg_replace('/\s/', '', $string2);
3398 $string2 = wp_kses_no_null($string2);
3399 $string2 = strtolower($string2);
3400
3401 $allowed = false;
3402- foreach ( (array) $_kses_allowed_protocols as $one_protocol)
3403- if (strtolower($one_protocol) == $string2) {
3404+ foreach ( (array) $allowed_protocols as $one_protocol )
3405+ if ( strtolower($one_protocol) == $string2 ) {
3406 $allowed = true;
3407 break;
3408 }
3409
3410=== modified file 'wp-includes/load.php'
3411--- wp-includes/load.php 2011-01-25 15:27:25 +0000
3412+++ wp-includes/load.php 2011-01-25 16:02:14 +0000
3413@@ -579,7 +579,7 @@
3414 if ( defined( 'MULTISITE' ) )
3415 return MULTISITE;
3416
3417- if ( defined( 'VHOST' ) || defined( 'SUNRISE' ) )
3418+ if ( defined( 'SUBDOMAIN_INSTALL' ) || defined( 'VHOST' ) || defined( 'SUNRISE' ) )
3419 return true;
3420
3421 return false;
3422
3423=== modified file 'wp-includes/ms-files.php'
3424--- wp-includes/ms-files.php 2011-01-25 15:27:25 +0000
3425+++ wp-includes/ms-files.php 2011-01-25 16:02:14 +0000
3426@@ -29,14 +29,14 @@
3427 die( '404 &#8212; File not found.' );
3428 }
3429
3430-$mime = wp_check_filetype( $_SERVER[ 'REQUEST_URI' ] );
3431+$mime = wp_check_filetype( $file );
3432 if( false === $mime[ 'type' ] && function_exists( 'mime_content_type' ) )
3433 $mime[ 'type' ] = mime_content_type( $file );
3434
3435 if( $mime[ 'type' ] )
3436 $mimetype = $mime[ 'type' ];
3437 else
3438- $mimetype = 'image/' . substr( $_SERVER[ 'REQUEST_URI' ], strrpos( $_SERVER[ 'REQUEST_URI' ], '.' ) + 1 );
3439+ $mimetype = 'image/' . substr( $file, strrpos( $file, '.' ) + 1 );
3440
3441 header( 'Content-type: ' . $mimetype ); // always send this
3442 if ( false === strpos( $_SERVER['SERVER_SOFTWARE'], 'Microsoft-IIS' ) )
3443
3444=== modified file 'wp-includes/version.php'
3445--- wp-includes/version.php 2011-01-25 15:27:25 +0000
3446+++ wp-includes/version.php 2011-01-25 16:02:14 +0000
3447@@ -8,7 +8,7 @@
3448 *
3449 * @global string $wp_version
3450 */
3451-$wp_version = '3.0.1';
3452+$wp_version = '3.0.4';
3453
3454 /**
3455 * Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.
3456
3457=== modified file 'xmlrpc.php'
3458--- xmlrpc.php 2011-01-25 15:27:25 +0000
3459+++ xmlrpc.php 2011-01-25 16:02:14 +0000
3460@@ -1156,9 +1156,12 @@
3461
3462 do_action('xmlrpc_call', 'wp.deleteComment');
3463
3464- if ( ! get_comment($comment_ID) )
3465+ if ( !$comment = get_comment( $comment_ID ) )
3466 return new IXR_Error( 404, __( 'Invalid comment ID.' ) );
3467
3468+ if ( !current_user_can( 'edit_post', $comment->comment_post_ID ) )
3469+ return new IXR_Error( 403, __( 'You are not allowed to moderate comments on this site.' ) );
3470+
3471 return wp_delete_comment($comment_ID);
3472 }
3473
3474@@ -1185,11 +1188,14 @@
3475 if ( !current_user_can( 'moderate_comments' ) )
3476 return new IXR_Error( 403, __( 'You are not allowed to moderate comments on this site.' ) );
3477
3478+ if ( !$comment = get_comment( $comment_ID ) )
3479+ return new IXR_Error( 404, __( 'Invalid comment ID.' ) );
3480+
3481+ if ( !current_user_can( 'edit_post', $comment->comment_post_ID ) )
3482+ return new IXR_Error( 403, __( 'You are not allowed to moderate comments on this site.' ) );
3483+
3484 do_action('xmlrpc_call', 'wp.editComment');
3485
3486- if ( ! get_comment($comment_ID) )
3487- return new IXR_Error( 404, __( 'Invalid comment ID.' ) );
3488-
3489 if ( isset($content_struct['status']) ) {
3490 $statuses = get_comment_statuses();
3491 $statuses = array_keys($statuses);
3492@@ -1417,7 +1423,7 @@
3493 if ( !$user = $this->login($username, $password) )
3494 return $this->error;
3495
3496- if ( !current_user_can( 'edit_posts' ) )
3497+ if ( !current_user_can( 'edit_pages' ) )
3498 return new IXR_Error( 403, __( 'You are not allowed access to details about this site.' ) );
3499
3500 do_action('xmlrpc_call', 'wp.getPageStatusList');
3501@@ -1957,7 +1963,7 @@
3502 if ( !$actual_post || $actual_post['post_type'] != 'post' )
3503 return new IXR_Error(404, __('Sorry, no such post.'));
3504
3505- if ( !current_user_can('edit_post', $post_ID) )
3506+ if ( !current_user_can('delete_post', $post_ID) )
3507 return new IXR_Error(401, __('Sorry, you do not have the right to delete this post.'));
3508
3509 $result = wp_delete_post($post_ID);
3510@@ -1987,30 +1993,42 @@
3511 $username = $args[1];
3512 $password = $args[2];
3513 $content_struct = $args[3];
3514- $publish = $args[4];
3515+ $publish = isset( $args[4] ) ? $args[4] : 0;
3516
3517 if ( !$user = $this->login($username, $password) )
3518 return $this->error;
3519
3520 do_action('xmlrpc_call', 'metaWeblog.newPost');
3521
3522- $cap = ( $publish ) ? 'publish_posts' : 'edit_posts';
3523- $error_message = __( 'Sorry, you are not allowed to publish posts on this site.' );
3524- $post_type = 'post';
3525 $page_template = '';
3526 if ( !empty( $content_struct['post_type'] ) ) {
3527 if ( $content_struct['post_type'] == 'page' ) {
3528- $cap = ( $publish ) ? 'publish_pages' : 'edit_pages';
3529+ if ( $publish || 'publish' == $content_struct['page_status'])
3530+ $cap = 'publish_pages';
3531+ else
3532+ $cap = 'edit_pages';
3533 $error_message = __( 'Sorry, you are not allowed to publish pages on this site.' );
3534 $post_type = 'page';
3535 if ( !empty( $content_struct['wp_page_template'] ) )
3536 $page_template = $content_struct['wp_page_template'];
3537 } elseif ( $content_struct['post_type'] == 'post' ) {
3538- // This is the default, no changes needed
3539+ if ( $publish || 'publish' == $content_struct['post_status'])
3540+ $cap = 'publish_posts';
3541+ else
3542+ $cap = 'edit_posts';
3543+ $error_message = __( 'Sorry, you are not allowed to publish posts on this site.' );
3544+ $post_type = 'post';
3545 } else {
3546 // No other post_type values are allowed here
3547 return new IXR_Error( 401, __( 'Invalid post type.' ) );
3548 }
3549+ } else {
3550+ if ( $publish || 'publish' == $content_struct['post_status'])
3551+ $cap = 'publish_posts';
3552+ else
3553+ $cap = 'edit_posts';
3554+ $error_message = __( 'Sorry, you are not allowed to publish posts on this site.' );
3555+ $post_type = 'post';
3556 }
3557
3558 if ( !current_user_can( $cap ) )
3559@@ -2275,17 +2293,32 @@
3560 $page_template = '';
3561 if ( !empty( $content_struct['post_type'] ) ) {
3562 if ( $content_struct['post_type'] == 'page' ) {
3563- $cap = ( $publish ) ? 'publish_pages' : 'edit_pages';
3564+ if ( $publish || 'publish' == $content_struct['page_status'] )
3565+ $cap = 'publish_pages';
3566+ else
3567+ $cap = 'edit_pages';
3568 $error_message = __( 'Sorry, you are not allowed to publish pages on this site.' );
3569 $post_type = 'page';
3570 if ( !empty( $content_struct['wp_page_template'] ) )
3571 $page_template = $content_struct['wp_page_template'];
3572 } elseif ( $content_struct['post_type'] == 'post' ) {
3573- // This is the default, no changes needed
3574+ if ( $publish || 'publish' == $content_struct['post_status'] )
3575+ $cap = 'publish_posts';
3576+ else
3577+ $cap = 'edit_posts';
3578+ $error_message = __( 'Sorry, you are not allowed to publish posts on this site.' );
3579+ $post_type = 'post';
3580 } else {
3581 // No other post_type values are allowed here
3582 return new IXR_Error( 401, __( 'Invalid post type.' ) );
3583 }
3584+ } else {
3585+ if ( $publish || 'publish' == $content_struct['post_status'] )
3586+ $cap = 'publish_posts';
3587+ else
3588+ $cap = 'edit_posts';
3589+ $error_message = __( 'Sorry, you are not allowed to publish posts on this site.' );
3590+ $post_type = 'post';
3591 }
3592
3593 if ( !current_user_can( $cap ) )
3594@@ -3101,7 +3134,7 @@
3595
3596 do_action('xmlrpc_call', 'mt.publishPost');
3597
3598- if ( !current_user_can('edit_post', $post_ID) )
3599+ if ( !current_user_can('publish_posts') || !current_user_can('edit_post', $post_ID) )
3600 return new IXR_Error(401, __('Sorry, you cannot edit this post.'));
3601
3602 $postdata = wp_get_single_post($post_ID,ARRAY_A);
3603@@ -3339,4 +3372,4 @@
3604
3605 $wp_xmlrpc_server = new wp_xmlrpc_server();
3606 $wp_xmlrpc_server->serve_request();
3607-?>
3608+?>
3609\ No newline at end of file

Subscribers

People subscribed via source and target branches