PageRenderTime 294ms CodeModel.GetById 100ms app.highlight 127ms RepoModel.GetById 55ms app.codeStats 0ms

/wp-content/plugins/akismet/admin.php

https://bitbucket.org/aqge/deptandashboard
PHP | 812 lines | 665 code | 110 blank | 37 comment | 186 complexity | f09d09a5eaf0fc71b72dc919627f5823 MD5 | raw file
  1<?php
  2add_action( 'admin_menu', 'akismet_admin_menu' );
  3	
  4akismet_admin_warnings();
  5
  6function akismet_admin_init() {
  7    global $wp_version;
  8    
  9    // all admin functions are disabled in old versions
 10    if ( !function_exists('is_multisite') && version_compare( $wp_version, '3.0', '<' ) ) {
 11        
 12        function akismet_version_warning() {
 13            echo "
 14            <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>
 15            ";
 16        }
 17        add_action('admin_notices', 'akismet_version_warning'); 
 18        
 19        return; 
 20    }
 21
 22    if ( function_exists( 'get_plugin_page_hook' ) )
 23        $hook = get_plugin_page_hook( 'akismet-stats-display', 'index.php' );
 24    else
 25        $hook = 'dashboard_page_akismet-stats-display';
 26    add_action('admin_head-'.$hook, 'akismet_stats_script');
 27    add_meta_box('akismet-status', __('Comment History'), 'akismet_comment_status_meta_box', 'comment', 'normal');
 28}
 29add_action('admin_init', 'akismet_admin_init');
 30
 31add_action( 'admin_enqueue_scripts', 'akismet_load_js_and_css' );
 32function akismet_load_js_and_css() {
 33	global $hook_suffix;
 34
 35	if (
 36		$hook_suffix == 'index.php'	# dashboard
 37		|| $hook_suffix == 'edit-comments.php' 
 38		|| $hook_suffix == 'comment.php' 
 39		|| $hook_suffix == 'post.php' 
 40		|| $hook_suffix == 'plugins_page_akismet-key-config'
 41	) {
 42		wp_register_style( 'akismet.css', AKISMET_PLUGIN_URL . 'akismet.css', array(), '2.5.4.4' );
 43		wp_enqueue_style( 'akismet.css');
 44	
 45		wp_register_script( 'akismet.js', AKISMET_PLUGIN_URL . 'akismet.js', array('jquery'), '2.5.4.6' );
 46		wp_enqueue_script( 'akismet.js' );
 47		wp_localize_script( 'akismet.js', 'WPAkismet', array(
 48			'comment_author_url_nonce' => wp_create_nonce( 'comment_author_url_nonce' )
 49		) );
 50	}
 51}
 52
 53
 54function akismet_nonce_field($action = -1) { return wp_nonce_field($action); }
 55$akismet_nonce = 'akismet-update-key';
 56
 57function akismet_plugin_action_links( $links, $file ) {
 58	if ( $file == plugin_basename( dirname(__FILE__).'/akismet.php' ) ) {
 59		$links[] = '<a href="admin.php?page=akismet-key-config">'.__('Settings').'</a>';
 60	}
 61
 62	return $links;
 63}
 64
 65add_filter( 'plugin_action_links', 'akismet_plugin_action_links', 10, 2 );
 66
 67function akismet_conf() {
 68	global $akismet_nonce, $wpcom_api_key;
 69
 70	if ( isset($_POST['submit']) ) {
 71		if ( function_exists('current_user_can') && !current_user_can('manage_options') )
 72			die(__('Cheatin&#8217; uh?'));
 73
 74		check_admin_referer( $akismet_nonce );
 75		$key = preg_replace( '/[^a-h0-9]/i', '', $_POST['key'] );
 76		$home_url = parse_url( get_bloginfo('url') );
 77
 78		if ( empty($key) ) {
 79			$key_status = 'empty';
 80			$ms[] = 'new_key_empty';
 81			delete_option('wordpress_api_key');
 82		} elseif ( empty($home_url['host']) ) {
 83			$key_status = 'empty';
 84			$ms[] = 'bad_home_url';
 85		} else {
 86			$key_status = akismet_verify_key( $key );
 87		}
 88
 89		if ( $key_status == 'valid' ) {
 90			update_option('wordpress_api_key', $key);
 91			$ms[] = 'new_key_valid';
 92		} else if ( $key_status == 'invalid' ) {
 93			$ms[] = 'new_key_invalid';
 94		} else if ( $key_status == 'failed' ) {
 95			$ms[] = 'new_key_failed';
 96		}
 97
 98		if ( isset( $_POST['akismet_discard_month'] ) )
 99			update_option( 'akismet_discard_month', 'true' );
100		else
101			update_option( 'akismet_discard_month', 'false' );
102
103		if ( isset( $_POST['akismet_show_user_comments_approved'] ) )
104			update_option( 'akismet_show_user_comments_approved', 'true' );
105		else
106			update_option( 'akismet_show_user_comments_approved', 'false' );
107
108	} elseif ( isset($_POST['check']) ) {
109		akismet_get_server_connectivity(0);
110	}
111
112	if ( empty( $key_status) ||  $key_status != 'valid' ) {
113		$key = get_option('wordpress_api_key');
114		if ( empty( $key ) ) {
115			if ( empty( $key_status ) || $key_status != 'failed' ) {
116				if ( akismet_verify_key( '1234567890ab' ) == 'failed' )
117					$ms[] = 'no_connection';
118				else
119					$ms[] = 'key_empty';
120			}
121			$key_status = 'empty';
122		} else {
123			$key_status = akismet_verify_key( $key );
124		}
125		if ( $key_status == 'valid' ) {
126			$ms[] = 'key_valid';
127		} else if ( $key_status == 'invalid' ) {
128			delete_option('wordpress_api_key');
129			$ms[] = 'key_empty';
130		} else if ( !empty($key) && $key_status == 'failed' ) {
131			$ms[] = 'key_failed';
132		}
133	}
134
135	$messages = array(
136		'new_key_empty' => array('color' => 'aa0', 'text' => __('Your key has been cleared.')),
137		'new_key_valid' => array('color' => '4AB915', 'text' => __('Your key has been verified. Happy blogging!')),
138		'new_key_invalid' => array('color' => '888', 'text' => __('The key you entered is invalid. Please double-check it.')),
139		'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.')),
140		'no_connection' => array('color' => '888', 'text' => __('There was a problem connecting to the Akismet server. Please check your server configuration.')),
141		'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/?return=true')),
142		'key_valid' => array('color' => '4AB915', 'text' => __('This key is valid.')),
143		'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.')),
144		'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') ) ),
145	);
146?>
147<?php if ( !empty($_POST['submit'] ) ) : ?>
148<div id="message" class="updated fade"><p><strong><?php _e('Options saved.') ?></strong></p></div>
149<?php endif; ?>
150<div class="wrap">
151<h2><?php _e('Akismet Configuration'); ?></h2>
152<?php if (isset($_GET['message']) && $_GET['message'] == 'success') { ?>
153	<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>
154<?php } ?>
155<div class="narrow">
156<form action="" method="post" id="akismet-conf" style="margin: auto; width: 400px; ">
157<?php if ( !$wpcom_api_key ) { ?>
158	<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/?return=true', 'http://akismet.com/get/?return=true'); ?></p>
159
160<h3><label for="key"><?php _e('Akismet API Key'); ?></label></h3>
161<?php foreach ( $ms as $m ) : ?>
162	<p style="padding: .5em; background-color: #<?php echo $messages[$m]['color']; ?>; color: #fff; font-weight: bold;"><?php echo $messages[$m]['text']; ?></p>
163<?php endforeach; ?>
164<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/?return=true">What is this?</a>'); ?>)</p>
165<?php if ( isset( $invalid_key) && $invalid_key ) { ?>
166<h3><?php _e('Why might my key be invalid?'); ?></h3>
167<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>
168<?php } ?>
169<?php } ?>
170<?php akismet_nonce_field($akismet_nonce) ?>
171<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>
172<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>
173	<p class="submit"><input type="submit" name="submit" value="<?php _e('Update options &raquo;'); ?>" /></p>
174</form>
175
176<form action="" method="post" id="akismet-connectivity" style="margin: auto; width: 400px; ">
177
178<h3><?php _e('Server Connectivity'); ?></h3>
179<?php
180	if ( !function_exists('fsockopen') || !function_exists('gethostbynamel') ) {
181		?>
182			<p style="padding: .5em; background-color: #888; color: #fff; font-weight:bold;"><?php _e('Network functions are disabled.'); ?></p>
183			<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>
184		<?php
185	} else {
186		$servers = akismet_get_server_connectivity();
187		$fail_count = count($servers) - count( array_filter($servers) );
188		if ( is_array($servers) && count($servers) > 0 ) {
189			// some connections work, some fail
190			if ( $fail_count > 0 && $fail_count < count($servers) ) { ?>
191				<p style="padding: .5em; background-color: #aa0; color: #fff; font-weight:bold;"><?php _e('Unable to reach some Akismet servers.'); ?></p>
192				<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>
193			<?php
194			// all connections fail
195			} elseif ( $fail_count > 0 ) { ?>
196				<p style="padding: .5em; background-color: #888; color: #fff; font-weight:bold;"><?php _e('Unable to reach any Akismet servers.'); ?></p>
197				<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>
198			<?php
199			// all connections work
200			} else { ?>
201				<p style="padding: .5em; background-color: #4AB915; color: #fff; font-weight:bold;"><?php  _e('All Akismet servers are available.'); ?></p>
202				<p><?php _e('Akismet is working correctly.  All servers are accessible.'); ?></p>
203			<?php
204			}
205		} else {
206			?>
207				<p style="padding: .5em; background-color: #888; color: #fff; font-weight:bold;"><?php _e('Unable to find Akismet servers.'); ?></p>
208				<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>
209			<?php
210		}
211	}
212	
213	if ( !empty($servers) ) {
214?>
215<table style="width: 100%;">
216<thead><th><?php _e('Akismet server'); ?></th><th><?php _e('Network Status'); ?></th></thead>
217<tbody>
218<?php
219		asort($servers);
220		foreach ( $servers as $ip => $status ) {
221			$color = ( $status ? '#4AB915' : '#888');
222	?>
223		<tr>
224		<td><?php echo htmlspecialchars($ip); ?></td>
225		<td style="padding: 0 .5em; font-weight:bold; color: #fff; background-color: <?php echo $color; ?>"><?php echo ($status ? __('Accessible') : __('Re-trying') ); ?></td>
226		
227	<?php
228		}
229	}
230?>
231</tbody>
232</table>
233	<p><?php if ( get_option('akismet_connectivity_time') ) echo sprintf( __('Last checked %s ago.'), human_time_diff( get_option('akismet_connectivity_time') ) ); ?></p>
234	<p class="submit"><input type="submit" name="check" value="<?php _e('Check network status &raquo;'); ?>" /></p>
235	<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>
236</form>
237
238</div>
239</div>
240<?php
241}
242
243function akismet_stats_script() {
244	?>
245<script type="text/javascript">
246function resizeIframe() {
247  
248    document.getElementById('akismet-stats-frame').style.height = "2500px";
249    
250};
251function resizeIframeInit() {
252	document.getElementById('akismet-stats-frame').onload = resizeIframe;
253	window.onresize = resizeIframe;
254}
255addLoadEvent(resizeIframeInit);
256</script><?php
257}
258
259
260function akismet_stats_display() {
261	global $akismet_api_host, $akismet_api_port, $wpcom_api_key;
262	$blog = urlencode( get_bloginfo('url') );
263
264	$url = 'http://';
265	if ( is_ssl() )
266		$url = 'https://';
267
268	$url .= 'akismet.com/web/1.0/user-stats.php';
269	$url .= "?blog={$blog}&api_key=" . akismet_get_key();
270	?>
271	<div class="wrap">
272	<iframe src="<?php echo $url; ?>" width="100%" height="100%" frameborder="0" id="akismet-stats-frame"></iframe>
273	</div>
274	<?php
275}
276
277function akismet_stats() {
278	if ( !function_exists('did_action') || did_action( 'rightnow_end' ) ) // We already displayed this info in the "Right Now" section
279		return;
280	if ( !$count = get_option('akismet_spam_count') )
281		return;
282	$path = plugin_basename(__FILE__);
283	echo '<h3>' . _x( 'Spam', 'comments' ) . '</h3>';
284	global $submenu;
285	if ( isset( $submenu['edit-comments.php'] ) )
286		$link = 'edit-comments.php';
287	else
288		$link = 'edit.php';
289	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/?return=true', clean_url("$link?page=akismet-admin"), number_format_i18n($count) ).'</p>';
290}
291add_action('activity_box_end', 'akismet_stats');
292
293function akismet_admin_warnings() {
294	global $wpcom_api_key;
295	if ( !get_option('wordpress_api_key') && !$wpcom_api_key && !isset($_POST['submit']) ) {
296		function akismet_warning() {
297			echo "
298			<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.'), "admin.php?page=akismet-key-config")."</p></div>
299			";
300		}
301		add_action('admin_notices', 'akismet_warning');
302		return;
303	} elseif ( ( empty($_SERVER['SCRIPT_FILENAME']) || basename($_SERVER['SCRIPT_FILENAME']) == 'edit-comments.php' ) &&  wp_next_scheduled('akismet_schedule_cron_recheck') ) {
304		function akismet_warning() {
305			global $wpdb;
306				$waiting = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM $wpdb->commentmeta WHERE meta_key = 'akismet_error'" ) );
307				$next_check = human_time_diff( wp_next_scheduled('akismet_schedule_cron_recheck') );
308				if ( $waiting > 0 )
309					echo "
310			<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>
311			";
312		}
313		add_action('admin_notices', 'akismet_warning');
314		return;
315	}
316}
317
318// FIXME placeholder
319
320function akismet_comment_row_action( $a, $comment ) {
321
322	// failsafe for old WP versions
323	if ( !function_exists('add_comment_meta') )
324		return $a;
325
326	$akismet_result = get_comment_meta( $comment->comment_ID, 'akismet_result', true );
327	$user_result = get_comment_meta( $comment->comment_ID, 'akismet_user_result', true);
328	$comment_status = wp_get_comment_status( $comment->comment_ID );
329	$desc = null;
330	if ( !$user_result || $user_result == $akismet_result ) {
331		// Show the original Akismet result if the user hasn't overridden it, or if their decision was the same
332		if ( $akismet_result == 'true' && $comment_status != 'spam' && $comment_status != 'trash' )
333			$desc = __( 'Flagged as spam by Akismet' );
334		elseif ( $akismet_result == 'false' && $comment_status == 'spam' )
335			$desc = __( 'Cleared by Akismet' );
336	} else {
337		$who = get_comment_meta( $comment->comment_ID, 'akismet_user', true );
338		if ( $user_result == 'true' )
339			$desc = sprintf( __('Flagged as spam by %s'), $who );
340		else
341			$desc = sprintf( __('Un-spammed by %s'), $who );
342	}
343
344	// add a History item to the hover links, just after Edit
345	if ( $akismet_result ) {
346		$b = array();
347		foreach ( $a as $k => $item ) {
348			$b[ $k ] = $item;
349			if ( $k == 'edit' )
350				$b['history'] = '<a href="comment.php?action=editcomment&amp;c='.$comment->comment_ID.'#akismet-status" title="'. esc_attr__( 'View comment history' ) . '"> '. __('History') . '</a>';
351		}
352		
353		$a = $b;
354	}
355		
356	if ( $desc )
357		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>';
358		
359	if ( apply_filters( 'akismet_show_user_comments_approved', get_option('akismet_show_user_comments_approved') ) == 'true' ) {
360		$comment_count = akismet_get_user_comments_approved( $comment->user_id, $comment->comment_author_email, $comment->comment_author, $comment->comment_author_url );
361		$comment_count = intval( $comment_count );
362		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>';
363	}
364	
365	return $a;
366}
367
368add_filter( 'comment_row_actions', 'akismet_comment_row_action', 10, 2 );
369
370function akismet_comment_status_meta_box($comment) {
371	$history = akismet_get_comment_history( $comment->comment_ID );
372
373	if ( $history ) {
374		echo '<div class="akismet-history" style="margin: 13px;">';
375		foreach ( $history as $row ) {
376			$time = date( 'D d M Y @ h:i:m a', $row['time'] ) . ' GMT';
377			echo '<div style="margin-bottom: 13px;"><span style="color: #999;" alt="' . $time . '" title="' . $time . '">' . sprintf( __('%s ago'), human_time_diff( $row['time'] ) ) . '</span> - ';
378			echo htmlspecialchars( $row['message'] ) . '</div>';
379		}
380		
381		echo '</div>';
382
383	}
384}
385
386
387// add an extra column header to the comments screen
388function akismet_comments_columns( $columns ) {
389	$columns[ 'akismet' ] = __( 'Akismet' );
390	return $columns;
391}
392
393#add_filter( 'manage_edit-comments_columns', 'akismet_comments_columns' );
394
395// Show stuff in the extra column
396function akismet_comment_column_row( $column, $comment_id ) {
397	if ( $column != 'akismet' )
398		return;
399		
400	$history = akismet_get_comment_history( $comment_id );
401	
402	if ( $history ) {
403		echo '<dl class="akismet-history">';
404		foreach ( $history as $row ) {
405			echo '<dt>' . sprintf( __('%s ago'), human_time_diff( $row['time'] ) ) . '</dt>';
406			echo '<dd>' . htmlspecialchars( $row['message'] ) . '</dd>';
407		}
408		
409		echo '</dl>';
410	}
411}
412
413#add_action( 'manage_comments_custom_column', 'akismet_comment_column_row', 10, 2 );
414
415// END FIXME
416
417// call out URLS in comments
418function akismet_text_add_link_callback( $m ) {
419	
420		// bare link?
421        if ( $m[4] == $m[2] )
422                return '<a '.$m[1].' href="'.$m[2].'" '.$m[3].' class="comment-link">'.$m[4].'</a>';
423        else
424                return '<span title="'.$m[2].'" class="comment-link"><a '.$m[1].' href="'.$m[2].'" '.$m[3].' class="comment-link">'.$m[4].'</a></span>';
425}
426
427function akismet_text_add_link_class( $comment_text ) {
428
429        return preg_replace_callback( '#<a ([^>]*)href="([^"]+)"([^>]*)>(.*?)</a>#i', 'akismet_text_add_link_callback', $comment_text );
430}
431
432add_filter('comment_text', 'akismet_text_add_link_class');
433
434
435// WP 2.5+
436function akismet_rightnow() {
437	global $submenu, $wp_db_version;
438
439	// clean_url was deprecated in WP 3.0
440	$esc_url = 'clean_url';
441	if ( function_exists( 'esc_url' ) )
442		$esc_url = 'esc_url';
443
444	if ( 8645 < $wp_db_version  ) // 2.7
445		$link = 'edit-comments.php?comment_status=spam';
446	elseif ( isset( $submenu['edit-comments.php'] ) )
447		$link = 'edit-comments.php?page=akismet-admin';
448	else
449		$link = 'edit.php?page=akismet-admin';
450
451	if ( $count = get_option('akismet_spam_count') ) {
452		$intro = sprintf( _n(
453			'<a href="%1$s">Akismet</a> has protected your site from %2$s spam comment already. ',
454			'<a href="%1$s">Akismet</a> has protected your site from %2$s spam comments already. ',
455			$count
456		), 'http://akismet.com/?return=true', number_format_i18n( $count ) );
457	} else {
458		$intro = sprintf( __('<a href="%1$s">Akismet</a> blocks spam from getting to your blog. '), 'http://akismet.com/?return=true' );
459	}
460
461	if ( $queue_count = akismet_spam_count() ) {
462		$queue_text = sprintf( _n(
463			'There\'s <a href="%2$s">%1$s comment</a> in your spam queue right now.',
464			'There are <a href="%2$s">%1$s comments</a> in your spam queue right now.',
465			$queue_count
466		), number_format_i18n( $queue_count ), $esc_url($link) );
467	} else {
468		$queue_text = sprintf( __( "There's nothing in your <a href='%1\$s'>spam queue</a> at the moment." ), $esc_url($link) );
469	}
470
471	$text = $intro . '<br />' . $queue_text;
472	echo "<p class='akismet-right-now'>$text</p>\n";
473}
474	
475add_action('rightnow_end', 'akismet_rightnow');
476
477
478// For WP >= 2.5
479function akismet_check_for_spam_button($comment_status) {
480	if ( 'approved' == $comment_status )
481		return;
482	if ( function_exists('plugins_url') )
483		$link = 'admin.php?action=akismet_recheck_queue';
484	else
485		$link = 'edit-comments.php?page=akismet-admin&amp;recheckqueue=true&amp;noheader=true';
486	echo "</div><div class='alignleft'><a class='button-secondary checkforspam' href='$link'>" . __('Check for Spam') . "</a>";
487}
488add_action('manage_comments_nav', 'akismet_check_for_spam_button');
489
490function akismet_submit_nonspam_comment ( $comment_id ) {
491	global $wpdb, $akismet_api_host, $akismet_api_port, $current_user, $current_site;
492	$comment_id = (int) $comment_id;
493
494	$comment = $wpdb->get_row("SELECT * FROM $wpdb->comments WHERE comment_ID = '$comment_id'");
495	if ( !$comment ) // it was deleted
496		return;
497		
498	// use the original version stored in comment_meta if available	
499	$as_submitted = get_comment_meta( $comment_id, 'akismet_as_submitted', true);
500	if ( $as_submitted && is_array($as_submitted) && isset($as_submitted['comment_content']) ) {
501		$comment = (object) array_merge( (array)$comment, $as_submitted );
502	}
503	
504	$comment->blog = get_bloginfo('url');
505	$comment->blog_lang = get_locale();
506	$comment->blog_charset = get_option('blog_charset');
507	$comment->permalink = get_permalink($comment->comment_post_ID);
508	$comment->reporter_ip = $_SERVER['REMOTE_ADDR'];
509	if ( is_object($current_user) ) {
510	    $comment->reporter = $current_user->user_login;
511	}
512	if ( is_object($current_site) ) {
513		$comment->site_domain = $current_site->domain;
514	}
515
516	$comment->user_role = '';
517	if ( isset( $comment->user_ID ) )
518		$comment->user_role = akismet_get_user_roles($comment->user_ID);
519
520	if ( akismet_test_mode() )
521		$comment->is_test = 'true';
522
523	$post = get_post( $comment->comment_post_ID );
524	$comment->comment_post_modified_gmt = $post->post_modified_gmt;
525
526	$query_string = '';
527	foreach ( $comment as $key => $data )
528		$query_string .= $key . '=' . urlencode( stripslashes($data) ) . '&';
529
530	$response = akismet_http_post($query_string, $akismet_api_host, "/1.1/submit-ham", $akismet_api_port);
531	if ( $comment->reporter ) {
532		akismet_update_comment_history( $comment_id, sprintf( __('%s reported this comment as not spam'), $comment->reporter ), 'report-ham' );
533		update_comment_meta( $comment_id, 'akismet_user_result', 'false' );
534		update_comment_meta( $comment_id, 'akismet_user', $comment->reporter );
535	}
536	
537	do_action('akismet_submit_nonspam_comment', $comment_id, $response[1]);
538}
539
540function akismet_submit_spam_comment ( $comment_id ) {
541	global $wpdb, $akismet_api_host, $akismet_api_port, $current_user, $current_site;
542	$comment_id = (int) $comment_id;
543
544	$comment = $wpdb->get_row("SELECT * FROM $wpdb->comments WHERE comment_ID = '$comment_id'");
545	if ( !$comment ) // it was deleted
546		return;
547	if ( 'spam' != $comment->comment_approved )
548		return;
549	
550	// use the original version stored in comment_meta if available	
551	$as_submitted = get_comment_meta( $comment_id, 'akismet_as_submitted', true);
552	if ( $as_submitted && is_array($as_submitted) && isset($as_submitted['comment_content']) ) {
553		$comment = (object) array_merge( (array)$comment, $as_submitted );
554	}
555	
556	$comment->blog = get_bloginfo('url');
557	$comment->blog_lang = get_locale();
558	$comment->blog_charset = get_option('blog_charset');
559	$comment->permalink = get_permalink($comment->comment_post_ID);
560	$comment->reporter_ip = $_SERVER['REMOTE_ADDR'];
561	if ( is_object($current_user) ) {
562	    $comment->reporter = $current_user->user_login;
563	}
564	if ( is_object($current_site) ) {
565		$comment->site_domain = $current_site->domain;
566	}
567
568	$comment->user_role = '';
569	if ( isset( $comment->user_ID ) )
570		$comment->user_role = akismet_get_user_roles($comment->user_ID);
571
572	if ( akismet_test_mode() )
573		$comment->is_test = 'true';
574
575	$post = get_post( $comment->comment_post_ID );
576	$comment->comment_post_modified_gmt = $post->post_modified_gmt;
577
578	$query_string = '';
579	foreach ( $comment as $key => $data )
580		$query_string .= $key . '=' . urlencode( stripslashes($data) ) . '&';
581
582	$response = akismet_http_post($query_string, $akismet_api_host, "/1.1/submit-spam", $akismet_api_port);
583	if ( $comment->reporter ) {
584		akismet_update_comment_history( $comment_id, sprintf( __('%s reported this comment as spam'), $comment->reporter ), 'report-spam' );
585		update_comment_meta( $comment_id, 'akismet_user_result', 'true' );
586		update_comment_meta( $comment_id, 'akismet_user', $comment->reporter );
587	}
588	do_action('akismet_submit_spam_comment', $comment_id, $response[1]);
589}
590
591// For WP 2.7+
592function akismet_transition_comment_status( $new_status, $old_status, $comment ) {
593	if ( $new_status == $old_status )
594		return;
595
596	# we don't need to record a history item for deleted comments
597	if ( $new_status == 'delete' )
598		return;
599		
600	if ( !is_admin() )
601		return;
602		
603	if ( !current_user_can( 'edit_post', $comment->comment_post_ID ) && !current_user_can( 'moderate_comments' ) )
604		return;
605
606	if ( defined('WP_IMPORTING') && WP_IMPORTING == true )
607		return;
608		
609	global $current_user;
610	$reporter = '';
611	if ( is_object( $current_user ) )
612		$reporter = $current_user->user_login;
613	
614	// Assumption alert:
615	// We want to submit comments to Akismet only when a moderator explicitly spams or approves it - not if the status
616	// is changed automatically by another plugin.  Unfortunately WordPress doesn't provide an unambiguous way to
617	// determine why the transition_comment_status action was triggered.  And there are several different ways by which
618	// to spam and unspam comments: bulk actions, ajax, links in moderation emails, the dashboard, and perhaps others.
619	// We'll assume that this is an explicit user action if POST or GET has an 'action' key.
620	if ( isset($_POST['action']) || isset($_GET['action']) ) {
621		if ( $new_status == 'spam' && ( $old_status == 'approved' || $old_status == 'unapproved' || !$old_status ) ) {
622				return akismet_submit_spam_comment( $comment->comment_ID );
623		} elseif ( $old_status == 'spam' && ( $new_status == 'approved' || $new_status == 'unapproved' ) ) {
624				return akismet_submit_nonspam_comment( $comment->comment_ID );
625		}
626	}
627	
628	if ( !get_comment_meta( $comment->comment_ID, 'akismet_rechecking' ) )
629		akismet_update_comment_history( $comment->comment_ID, sprintf( __('%s changed the comment status to %s'), $reporter, $new_status ), 'status-' . $new_status );
630}
631
632add_action( 'transition_comment_status', 'akismet_transition_comment_status', 10, 3 );
633
634// Total spam in queue
635// get_option( 'akismet_spam_count' ) is the total caught ever
636function akismet_spam_count( $type = false ) {
637	global $wpdb;
638
639	if ( !$type ) { // total
640		$count = wp_cache_get( 'akismet_spam_count', 'widget' );
641		if ( false === $count ) {
642			if ( function_exists('wp_count_comments') ) {
643				$count = wp_count_comments();
644				$count = $count->spam;
645			} else {
646				$count = (int) $wpdb->get_var("SELECT COUNT(comment_ID) FROM $wpdb->comments WHERE comment_approved = 'spam'");
647			}
648			wp_cache_set( 'akismet_spam_count', $count, 'widget', 3600 );
649		}
650		return $count;
651	} elseif ( 'comments' == $type || 'comment' == $type ) { // comments
652		$type = '';
653	} else { // pingback, trackback, ...
654		$type  = $wpdb->escape( $type );
655	}
656
657	return (int) $wpdb->get_var("SELECT COUNT(comment_ID) FROM $wpdb->comments WHERE comment_approved = 'spam' AND comment_type='$type'");
658}
659
660
661function akismet_recheck_queue() {
662	global $wpdb, $akismet_api_host, $akismet_api_port;
663
664	if ( ! ( isset( $_GET['recheckqueue'] ) || ( isset( $_REQUEST['action'] ) && 'akismet_recheck_queue' == $_REQUEST['action'] ) ) )
665		return;
666		
667	$moderation = $wpdb->get_results( "SELECT * FROM $wpdb->comments WHERE comment_approved = '0'", ARRAY_A );
668	foreach ( (array) $moderation as $c ) {
669		$c['user_ip']    = $c['comment_author_IP'];
670		$c['user_agent'] = $c['comment_agent'];
671		$c['referrer']   = '';
672		$c['blog']       = get_bloginfo('url');
673		$c['blog_lang']  = get_locale();
674		$c['blog_charset'] = get_option('blog_charset');
675		$c['permalink']  = get_permalink($c['comment_post_ID']);
676
677		$c['user_role'] = '';
678		if ( isset( $c['user_ID'] ) )
679			$c['user_role']  = akismet_get_user_roles($c['user_ID']);
680
681		if ( akismet_test_mode() )
682			$c['is_test'] = 'true';
683
684		$id = (int) $c['comment_ID'];
685
686		$query_string = '';
687		foreach ( $c as $key => $data )
688		$query_string .= $key . '=' . urlencode( stripslashes($data) ) . '&';
689
690		$response = akismet_http_post($query_string, $akismet_api_host, '/1.1/comment-check', $akismet_api_port);
691		if ( 'true' == $response[1] ) {
692			wp_set_comment_status($c['comment_ID'], 'spam');
693			update_comment_meta( $c['comment_ID'], 'akismet_result', 'true' );
694			akismet_update_comment_history( $c['comment_ID'], __('Akismet re-checked and caught this comment as spam'), 'check-spam' );
695		
696		} elseif ( 'false' == $response[1] ) {
697			update_comment_meta( $c['comment_ID'], 'akismet_result', 'false' );
698			akismet_update_comment_history( $c['comment_ID'], __('Akismet re-checked and cleared this comment'), 'check-ham' );
699		// abnormal result: error
700		} else {
701			update_comment_meta( $c['comment_ID'], 'akismet_result', 'error' );
702			akismet_update_comment_history( $c['comment_ID'], sprintf( __('Akismet was unable to re-check this comment (response: %s)'), $response[1]), 'check-error' );
703		}
704
705	}
706	wp_safe_redirect( $_SERVER['HTTP_REFERER'] );
707	exit;
708}
709
710add_action('admin_action_akismet_recheck_queue', 'akismet_recheck_queue');
711
712// Adds an 'x' link next to author URLs, clicking will remove the author URL and show an undo link
713function akismet_remove_comment_author_url() {
714    if ( !empty($_POST['id'] ) && check_admin_referer( 'comment_author_url_nonce' ) ) {
715        global $wpdb;
716        $comment = get_comment( intval($_POST['id']), ARRAY_A );
717        if (current_user_can('edit_comment', $comment['comment_ID'])) {
718            $comment['comment_author_url'] = '';
719            do_action( 'comment_remove_author_url' );
720            print(wp_update_comment( $comment ));
721            die();
722        }
723    }
724}
725
726add_action('wp_ajax_comment_author_deurl', 'akismet_remove_comment_author_url');
727
728function akismet_add_comment_author_url() {
729    if ( !empty( $_POST['id'] ) && !empty( $_POST['url'] ) && check_admin_referer( 'comment_author_url_nonce' ) ) {
730        global $wpdb;
731        $comment = get_comment( intval($_POST['id']), ARRAY_A );
732        if (current_user_can('edit_comment', $comment['comment_ID'])) {
733            $comment['comment_author_url'] = esc_url($_POST['url']);
734            do_action( 'comment_add_author_url' );
735            print(wp_update_comment( $comment ));
736            die();
737        }
738    }
739}
740
741add_action('wp_ajax_comment_author_reurl', 'akismet_add_comment_author_url');
742
743// Check connectivity between the WordPress blog and Akismet's servers.
744// 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).
745function akismet_check_server_connectivity() {
746	global $akismet_api_host, $akismet_api_port, $wpcom_api_key;
747	
748	$test_host = 'rest.akismet.com';
749	
750	// Some web hosts may disable one or both functions
751	if ( !function_exists('fsockopen') || !function_exists('gethostbynamel') )
752		return array();
753	
754	$ips = gethostbynamel($test_host);
755	if ( !$ips || !is_array($ips) || !count($ips) )
756		return array();
757		
758	$servers = array();
759	foreach ( $ips as $ip ) {
760		$response = akismet_verify_key( akismet_get_key(), $ip );
761		// even if the key is invalid, at least we know we have connectivity
762		if ( $response == 'valid' || $response == 'invalid' )
763			$servers[$ip] = true;
764		else
765			$servers[$ip] = false;
766	}
767
768	return $servers;
769}
770
771// Check the server connectivity and store the results in an option.
772// Cached results will be used if not older than the specified timeout in seconds; use $cache_timeout = 0 to force an update.
773// Returns the same associative array as akismet_check_server_connectivity()
774function akismet_get_server_connectivity( $cache_timeout = 86400 ) {
775	$servers = get_option('akismet_available_servers');
776	if ( (time() - get_option('akismet_connectivity_time') < $cache_timeout) && $servers !== false )
777		return $servers;
778	
779	// There's a race condition here but the effect is harmless.
780	$servers = akismet_check_server_connectivity();
781	update_option('akismet_available_servers', $servers);
782	update_option('akismet_connectivity_time', time());
783	return $servers;
784}
785
786// Returns true if server connectivity was OK at the last check, false if there was a problem that needs to be fixed.
787function akismet_server_connectivity_ok() {
788	// skip the check on WPMU because the status page is hidden
789	global $wpcom_api_key;
790	if ( $wpcom_api_key )
791		return true;
792	$servers = akismet_get_server_connectivity();
793	return !( empty($servers) || !count($servers) || count( array_filter($servers) ) < count($servers) );
794}
795
796function akismet_admin_menu() {
797	if ( class_exists( 'Jetpack' ) ) {
798		add_action( 'jetpack_admin_menu', 'akismet_load_menu' );
799	} else {
800		akismet_load_menu();
801	}
802}
803
804function akismet_load_menu() {
805	if ( class_exists( 'Jetpack' ) ) {
806		add_submenu_page( 'jetpack', __( 'Akismet Configuration' ), __( 'Akismet Configuration' ), 'manage_options', 'akismet-key-config', 'akismet_conf' );
807		add_submenu_page( 'jetpack', __( 'Akismet Stats' ), __( 'Akismet Stats' ), 'manage_options', 'akismet-stats-display', 'akismet_stats_display' );
808	} else {
809		add_submenu_page('plugins.php', __('Akismet Configuration'), __('Akismet Configuration'), 'manage_options', 'akismet-key-config', 'akismet_conf');
810		add_submenu_page('index.php', __('Akismet Stats'), __('Akismet Stats'), 'manage_options', 'akismet-stats-display', 'akismet_stats_display');
811	}
812}