PageRenderTime 252ms CodeModel.GetById 30ms app.highlight 110ms RepoModel.GetById 31ms app.codeStats 1ms

/wp-admin/includes/dashboard.php

https://bitbucket.org/aqge/deptandashboard
PHP | 1363 lines | 982 code | 214 blank | 167 comment | 216 complexity | 67dd8395366e4da60678cc978355917c MD5 | raw file

Large files files are truncated, but you can click here to view the full file

   1<?php
   2/**
   3 * WordPress Dashboard Widget Administration Screen API
   4 *
   5 * @package WordPress
   6 * @subpackage Administration
   7 */
   8
   9/**
  10 * Registers dashboard widgets.
  11 *
  12 * Handles POST data, sets up filters.
  13 *
  14 * @since 2.5.0
  15 */
  16function wp_dashboard_setup() {
  17	global $wp_registered_widgets, $wp_registered_widget_controls, $wp_dashboard_control_callbacks;
  18	$wp_dashboard_control_callbacks = array();
  19	$screen = get_current_screen();
  20
  21	$update = false;
  22	$widget_options = get_option( 'dashboard_widget_options' );
  23	if ( !$widget_options || !is_array($widget_options) )
  24		$widget_options = array();
  25
  26	/* Register Widgets and Controls */
  27
  28	$response = wp_check_browser_version();
  29
  30	if ( $response && $response['upgrade'] ) {
  31		add_filter( 'postbox_classes_dashboard_dashboard_browser_nag', 'dashboard_browser_nag_class' );
  32		if ( $response['insecure'] )
  33			wp_add_dashboard_widget( 'dashboard_browser_nag', __( 'You are using an insecure browser!' ), 'wp_dashboard_browser_nag' );
  34		else
  35			wp_add_dashboard_widget( 'dashboard_browser_nag', __( 'Your browser is out of date!' ), 'wp_dashboard_browser_nag' );
  36	}
  37
  38	// Right Now
  39	if ( is_blog_admin() && current_user_can('edit_posts') )
  40		wp_add_dashboard_widget( 'dashboard_right_now', __( 'Right Now' ), 'wp_dashboard_right_now' );
  41
  42	if ( is_network_admin() )
  43		wp_add_dashboard_widget( 'network_dashboard_right_now', __( 'Right Now' ), 'wp_network_dashboard_right_now' );
  44
  45	// Recent Comments Widget
  46	if ( is_blog_admin() && current_user_can('moderate_comments') ) {
  47		if ( !isset( $widget_options['dashboard_recent_comments'] ) || !isset( $widget_options['dashboard_recent_comments']['items'] ) ) {
  48			$update = true;
  49			$widget_options['dashboard_recent_comments'] = array(
  50				'items' => 5,
  51			);
  52		}
  53		$recent_comments_title = __( 'Recent Comments' );
  54		wp_add_dashboard_widget( 'dashboard_recent_comments', $recent_comments_title, 'wp_dashboard_recent_comments', 'wp_dashboard_recent_comments_control' );
  55	}
  56
  57	// Incoming Links Widget
  58	if ( is_blog_admin() && current_user_can('publish_posts') ) {
  59		if ( !isset( $widget_options['dashboard_incoming_links'] ) || !isset( $widget_options['dashboard_incoming_links']['home'] ) || $widget_options['dashboard_incoming_links']['home'] != get_option('home') ) {
  60			$update = true;
  61			$num_items = isset($widget_options['dashboard_incoming_links']['items']) ? $widget_options['dashboard_incoming_links']['items'] : 10;
  62			$widget_options['dashboard_incoming_links'] = array(
  63				'home' => get_option('home'),
  64				'link' => apply_filters( 'dashboard_incoming_links_link', 'http://blogsearch.google.com/blogsearch?scoring=d&partner=wordpress&q=link:' . trailingslashit( get_option('home') ) ),
  65				'url' => isset($widget_options['dashboard_incoming_links']['url']) ? apply_filters( 'dashboard_incoming_links_feed', $widget_options['dashboard_incoming_links']['url'] ) : apply_filters( 'dashboard_incoming_links_feed', 'http://blogsearch.google.com/blogsearch_feeds?scoring=d&ie=utf-8&num=' . $num_items . '&output=rss&partner=wordpress&q=link:' . trailingslashit( get_option('home') ) ),
  66				'items' => $num_items,
  67				'show_date' => isset($widget_options['dashboard_incoming_links']['show_date']) ? $widget_options['dashboard_incoming_links']['show_date'] : false
  68			);
  69		}
  70		wp_add_dashboard_widget( 'dashboard_incoming_links', __( 'Incoming Links' ), 'wp_dashboard_incoming_links', 'wp_dashboard_incoming_links_control' );
  71	}
  72
  73	// WP Plugins Widget
  74	if ( ( ! is_multisite() && is_blog_admin() && current_user_can( 'install_plugins' ) ) || ( is_network_admin() && current_user_can( 'manage_network_plugins' ) && current_user_can( 'install_plugins' ) ) )
  75		wp_add_dashboard_widget( 'dashboard_plugins', __( 'Plugins' ), 'wp_dashboard_plugins' );
  76
  77	// QuickPress Widget
  78	if ( is_blog_admin() && current_user_can('edit_posts') )
  79		wp_add_dashboard_widget( 'dashboard_quick_press', __( 'QuickPress' ), 'wp_dashboard_quick_press' );
  80
  81	// Recent Drafts
  82	if ( is_blog_admin() && current_user_can('edit_posts') )
  83		wp_add_dashboard_widget( 'dashboard_recent_drafts', __('Recent Drafts'), 'wp_dashboard_recent_drafts' );
  84
  85	// Primary feed (Dev Blog) Widget
  86	if ( !isset( $widget_options['dashboard_primary'] ) ) {
  87		$update = true;
  88		$widget_options['dashboard_primary'] = array(
  89			'link' => apply_filters( 'dashboard_primary_link',  __( 'http://wordpress.org/news/' ) ),
  90			'url' => apply_filters( 'dashboard_primary_feed',  __( 'http://wordpress.org/news/feed/' ) ),
  91			'title' => apply_filters( 'dashboard_primary_title', __( 'WordPress Blog' ) ),
  92			'items' => 2,
  93			'show_summary' => 1,
  94			'show_author' => 0,
  95			'show_date' => 1,
  96		);
  97	}
  98	wp_add_dashboard_widget( 'dashboard_primary', $widget_options['dashboard_primary']['title'], 'wp_dashboard_primary', 'wp_dashboard_primary_control' );
  99
 100	// Secondary Feed (Planet) Widget
 101	if ( !isset( $widget_options['dashboard_secondary'] ) ) {
 102		$update = true;
 103		$widget_options['dashboard_secondary'] = array(
 104			'link' => apply_filters( 'dashboard_secondary_link',  __( 'http://planet.wordpress.org/' ) ),
 105			'url' => apply_filters( 'dashboard_secondary_feed',  __( 'http://planet.wordpress.org/feed/' ) ),
 106			'title' => apply_filters( 'dashboard_secondary_title', __( 'Other WordPress News' ) ),
 107			'items' => 5,
 108			'show_summary' => 0,
 109			'show_author' => 0,
 110			'show_date' => 0,
 111		);
 112	}
 113	wp_add_dashboard_widget( 'dashboard_secondary', $widget_options['dashboard_secondary']['title'], 'wp_dashboard_secondary', 'wp_dashboard_secondary_control' );
 114
 115	// Hook to register new widgets
 116	// Filter widget order
 117	if ( is_network_admin() ) {
 118		do_action( 'wp_network_dashboard_setup' );
 119		$dashboard_widgets = apply_filters( 'wp_network_dashboard_widgets', array() );
 120	} elseif ( is_user_admin() ) {
 121		do_action( 'wp_user_dashboard_setup' );
 122		$dashboard_widgets = apply_filters( 'wp_user_dashboard_widgets', array() );
 123	} else {
 124		do_action( 'wp_dashboard_setup' );
 125		$dashboard_widgets = apply_filters( 'wp_dashboard_widgets', array() );
 126	}
 127
 128	foreach ( $dashboard_widgets as $widget_id ) {
 129		$name = empty( $wp_registered_widgets[$widget_id]['all_link'] ) ? $wp_registered_widgets[$widget_id]['name'] : $wp_registered_widgets[$widget_id]['name'] . " <a href='{$wp_registered_widgets[$widget_id]['all_link']}' class='edit-box open-box'>" . __('View all') . '</a>';
 130		wp_add_dashboard_widget( $widget_id, $name, $wp_registered_widgets[$widget_id]['callback'], $wp_registered_widget_controls[$widget_id]['callback'] );
 131	}
 132
 133	if ( 'POST' == $_SERVER['REQUEST_METHOD'] && isset($_POST['widget_id']) ) {
 134		ob_start(); // hack - but the same hack wp-admin/widgets.php uses
 135		wp_dashboard_trigger_widget_control( $_POST['widget_id'] );
 136		ob_end_clean();
 137		wp_redirect( remove_query_arg( 'edit' ) );
 138		exit;
 139	}
 140
 141	if ( $update )
 142		update_option( 'dashboard_widget_options', $widget_options );
 143
 144	do_action('do_meta_boxes', $screen->id, 'normal', '');
 145	do_action('do_meta_boxes', $screen->id, 'side', '');
 146}
 147
 148function wp_add_dashboard_widget( $widget_id, $widget_name, $callback, $control_callback = null ) {
 149	$screen = get_current_screen();
 150	global $wp_dashboard_control_callbacks;
 151
 152	if ( $control_callback && current_user_can( 'edit_dashboard' ) && is_callable( $control_callback ) ) {
 153		$wp_dashboard_control_callbacks[$widget_id] = $control_callback;
 154		if ( isset( $_GET['edit'] ) && $widget_id == $_GET['edit'] ) {
 155			list($url) = explode( '#', add_query_arg( 'edit', false ), 2 );
 156			$widget_name .= ' <span class="postbox-title-action"><a href="' . esc_url( $url ) . '">' . __( 'Cancel' ) . '</a></span>';
 157			$callback = '_wp_dashboard_control_callback';
 158		} else {
 159			list($url) = explode( '#', add_query_arg( 'edit', $widget_id ), 2 );
 160			$widget_name .= ' <span class="postbox-title-action"><a href="' . esc_url( "$url#$widget_id" ) . '" class="edit-box open-box">' . __( 'Configure' ) . '</a></span>';
 161		}
 162	}
 163
 164	if ( is_blog_admin () )
 165		$side_widgets = array('dashboard_quick_press', 'dashboard_recent_drafts', 'dashboard_primary', 'dashboard_secondary');
 166	else if (is_network_admin() )
 167		$side_widgets = array('dashboard_primary', 'dashboard_secondary');
 168	else
 169		$side_widgets = array();
 170
 171	$location = 'normal';
 172	if ( in_array($widget_id, $side_widgets) )
 173		$location = 'side';
 174
 175	$priority = 'core';
 176	if ( 'dashboard_browser_nag' === $widget_id )
 177		$priority = 'high';
 178
 179	add_meta_box( $widget_id, $widget_name, $callback, $screen, $location, $priority );
 180}
 181
 182function _wp_dashboard_control_callback( $dashboard, $meta_box ) {
 183	echo '<form action="" method="post" class="dashboard-widget-control-form">';
 184	wp_dashboard_trigger_widget_control( $meta_box['id'] );
 185	echo '<input type="hidden" name="widget_id" value="' . esc_attr($meta_box['id']) . '" />';
 186	submit_button( __('Submit') );
 187	echo '</form>';
 188}
 189
 190/**
 191 * Displays the dashboard.
 192 *
 193 * @since 2.5.0
 194 */
 195function wp_dashboard() {
 196	global $screen_layout_columns;
 197
 198	$screen = get_current_screen();
 199
 200	$hide2 = $hide3 = $hide4 = '';
 201	switch ( $screen_layout_columns ) {
 202		case 4:
 203			$width = 'width:25%;';
 204			break;
 205		case 3:
 206			$width = 'width:33.333333%;';
 207			$hide4 = 'display:none;';
 208			break;
 209		case 2:
 210			$width = 'width:50%;';
 211			$hide3 = $hide4 = 'display:none;';
 212			break;
 213		default:
 214			$width = 'width:100%;';
 215			$hide2 = $hide3 = $hide4 = 'display:none;';
 216	}
 217?>
 218<div id="dashboard-widgets" class="metabox-holder">
 219<?php
 220	echo "\t<div id='postbox-container-1' class='postbox-container' style='$width'>\n";
 221	do_meta_boxes( $screen->id, 'normal', '' );
 222
 223	echo "\t</div><div id='postbox-container-2' class='postbox-container' style='{$hide2}$width'>\n";
 224	do_meta_boxes( $screen->id, 'side', '' );
 225
 226	echo "\t</div><div id='postbox-container-3' class='postbox-container' style='{$hide3}$width'>\n";
 227	do_meta_boxes( $screen->id, 'column3', '' );
 228
 229	echo "\t</div><div id='postbox-container-4' class='postbox-container' style='{$hide4}$width'>\n";
 230	do_meta_boxes( $screen->id, 'column4', '' );
 231?>
 232</div></div>
 233
 234<form style="display:none" method="get" action="">
 235	<p>
 236<?php
 237	wp_nonce_field( 'closedpostboxes', 'closedpostboxesnonce', false );
 238	wp_nonce_field( 'meta-box-order', 'meta-box-order-nonce', false );
 239?>
 240	</p>
 241</form>
 242
 243<?php
 244}
 245
 246/* Dashboard Widgets */
 247
 248function wp_dashboard_right_now() {
 249	global $wp_registered_sidebars;
 250
 251	$num_posts = wp_count_posts( 'post' );
 252	$num_pages = wp_count_posts( 'page' );
 253
 254	$num_cats  = wp_count_terms('category');
 255
 256	$num_tags = wp_count_terms('post_tag');
 257
 258	$num_comm = wp_count_comments( );
 259
 260	echo "\n\t".'<div class="table table_content">';
 261	echo "\n\t".'<p class="sub">' . __('Content') . '</p>'."\n\t".'<table>';
 262	echo "\n\t".'<tr class="first">';
 263
 264	// Posts
 265	$num = number_format_i18n( $num_posts->publish );
 266	$text = _n( 'Post', 'Posts', intval($num_posts->publish) );
 267	if ( current_user_can( 'edit_posts' ) ) {
 268		$num = "<a href='edit.php'>$num</a>";
 269		$text = "<a href='edit.php'>$text</a>";
 270	}
 271	echo '<td class="first b b-posts">' . $num . '</td>';
 272	echo '<td class="t posts">' . $text . '</td>';
 273
 274	echo '</tr><tr>';
 275	/* TODO: Show status breakdown on hover
 276	if ( $can_edit_pages && !empty($num_pages->publish) ) { // how many pages is not exposed in feeds.  Don't show if !current_user_can
 277		$post_type_texts[] = '<a href="edit-pages.php">'.sprintf( _n( '%s page', '%s pages', $num_pages->publish ), number_format_i18n( $num_pages->publish ) ).'</a>';
 278	}
 279	if ( $can_edit_posts && !empty($num_posts->draft) ) {
 280		$post_type_texts[] = '<a href="edit.php?post_status=draft">'.sprintf( _n( '%s draft', '%s drafts', $num_posts->draft ), number_format_i18n( $num_posts->draft ) ).'</a>';
 281	}
 282	if ( $can_edit_posts && !empty($num_posts->future) ) {
 283		$post_type_texts[] = '<a href="edit.php?post_status=future">'.sprintf( _n( '%s scheduled post', '%s scheduled posts', $num_posts->future ), number_format_i18n( $num_posts->future ) ).'</a>';
 284	}
 285	if ( current_user_can('publish_posts') && !empty($num_posts->pending) ) {
 286		$pending_text = sprintf( _n( 'There is <a href="%1$s">%2$s post</a> pending your review.', 'There are <a href="%1$s">%2$s posts</a> pending your review.', $num_posts->pending ), 'edit.php?post_status=pending', number_format_i18n( $num_posts->pending ) );
 287	} else {
 288		$pending_text = '';
 289	}
 290	*/
 291
 292	// Pages
 293	$num = number_format_i18n( $num_pages->publish );
 294	$text = _n( 'Page', 'Pages', $num_pages->publish );
 295	if ( current_user_can( 'edit_pages' ) ) {
 296		$num = "<a href='edit.php?post_type=page'>$num</a>";
 297		$text = "<a href='edit.php?post_type=page'>$text</a>";
 298	}
 299	echo '<td class="first b b_pages">' . $num . '</td>';
 300	echo '<td class="t pages">' . $text . '</td>';
 301
 302	echo '</tr><tr>';
 303
 304	// Categories
 305	$num = number_format_i18n( $num_cats );
 306	$text = _n( 'Category', 'Categories', $num_cats );
 307	if ( current_user_can( 'manage_categories' ) ) {
 308		$num = "<a href='edit-tags.php?taxonomy=category'>$num</a>";
 309		$text = "<a href='edit-tags.php?taxonomy=category'>$text</a>";
 310	}
 311	echo '<td class="first b b-cats">' . $num . '</td>';
 312	echo '<td class="t cats">' . $text . '</td>';
 313
 314	echo '</tr><tr>';
 315
 316	// Tags
 317	$num = number_format_i18n( $num_tags );
 318	$text = _n( 'Tag', 'Tags', $num_tags );
 319	if ( current_user_can( 'manage_categories' ) ) {
 320		$num = "<a href='edit-tags.php'>$num</a>";
 321		$text = "<a href='edit-tags.php'>$text</a>";
 322	}
 323	echo '<td class="first b b-tags">' . $num . '</td>';
 324	echo '<td class="t tags">' . $text . '</td>';
 325
 326	echo "</tr>";
 327	do_action('right_now_content_table_end');
 328	echo "\n\t</table>\n\t</div>";
 329
 330
 331	echo "\n\t".'<div class="table table_discussion">';
 332	echo "\n\t".'<p class="sub">' . __('Discussion') . '</p>'."\n\t".'<table>';
 333	echo "\n\t".'<tr class="first">';
 334
 335	// Total Comments
 336	$num = '<span class="total-count">' . number_format_i18n($num_comm->total_comments) . '</span>';
 337	$text = _n( 'Comment', 'Comments', $num_comm->total_comments );
 338	if ( current_user_can( 'moderate_comments' ) ) {
 339		$num = '<a href="edit-comments.php">' . $num . '</a>';
 340		$text = '<a href="edit-comments.php">' . $text . '</a>';
 341	}
 342	echo '<td class="b b-comments">' . $num . '</td>';
 343	echo '<td class="last t comments">' . $text . '</td>';
 344
 345	echo '</tr><tr>';
 346
 347	// Approved Comments
 348	$num = '<span class="approved-count">' . number_format_i18n($num_comm->approved) . '</span>';
 349	$text = _nx( 'Approved', 'Approved', $num_comm->approved, 'Right Now' );
 350	if ( current_user_can( 'moderate_comments' ) ) {
 351		$num = "<a href='edit-comments.php?comment_status=approved'>$num</a>";
 352		$text = "<a class='approved' href='edit-comments.php?comment_status=approved'>$text</a>";
 353	}
 354	echo '<td class="b b_approved">' . $num . '</td>';
 355	echo '<td class="last t">' . $text . '</td>';
 356
 357	echo "</tr>\n\t<tr>";
 358
 359	// Pending Comments
 360	$num = '<span class="pending-count">' . number_format_i18n($num_comm->moderated) . '</span>';
 361	$text = _n( 'Pending', 'Pending', $num_comm->moderated );
 362	if ( current_user_can( 'moderate_comments' ) ) {
 363		$num = "<a href='edit-comments.php?comment_status=moderated'>$num</a>";
 364		$text = "<a class='waiting' href='edit-comments.php?comment_status=moderated'>$text</a>";
 365	}
 366	echo '<td class="b b-waiting">' . $num . '</td>';
 367	echo '<td class="last t">' . $text . '</td>';
 368
 369	echo "</tr>\n\t<tr>";
 370
 371	// Spam Comments
 372	$num = number_format_i18n($num_comm->spam);
 373	$text = _nx( 'Spam', 'Spam', $num_comm->spam, 'comment' );
 374	if ( current_user_can( 'moderate_comments' ) ) {
 375		$num = "<a href='edit-comments.php?comment_status=spam'><span class='spam-count'>$num</span></a>";
 376		$text = "<a class='spam' href='edit-comments.php?comment_status=spam'>$text</a>";
 377	}
 378	echo '<td class="b b-spam">' . $num . '</td>';
 379	echo '<td class="last t">' . $text . '</td>';
 380
 381	echo "</tr>";
 382	do_action('right_now_table_end');
 383	do_action('right_now_discussion_table_end');
 384	echo "\n\t</table>\n\t</div>";
 385
 386	echo "\n\t".'<div class="versions">';
 387	$ct = current_theme_info();
 388
 389	echo "\n\t<p>";
 390
 391	if ( empty( $ct->stylesheet_dir ) ) {
 392		if ( ! is_multisite() || is_super_admin() )
 393			echo '<span class="error-message">' . __('ERROR: The themes directory is either empty or doesn&#8217;t exist. Please check your installation.') . '</span>';
 394	} elseif ( ! empty($wp_registered_sidebars) ) {
 395		$sidebars_widgets = wp_get_sidebars_widgets();
 396		$num_widgets = 0;
 397		foreach ( (array) $sidebars_widgets as $k => $v ) {
 398			if ( 'wp_inactive_widgets' == $k || 'orphaned_widgets' == substr( $k, 0, 16 ) )
 399				continue;
 400			if ( is_array($v) )
 401				$num_widgets = $num_widgets + count($v);
 402		}
 403		$num = number_format_i18n( $num_widgets );
 404
 405		$switch_themes = $ct->title;
 406		if ( current_user_can( 'switch_themes') )
 407			$switch_themes = '<a href="themes.php">' . $switch_themes . '</a>';
 408		if ( current_user_can( 'edit_theme_options' ) ) {
 409			printf(_n('Theme <span class="b">%1$s</span> with <span class="b"><a href="widgets.php">%2$s Widget</a></span>', 'Theme <span class="b">%1$s</span> with <span class="b"><a href="widgets.php">%2$s Widgets</a></span>', $num_widgets), $switch_themes, $num);
 410		} else {
 411			printf(_n('Theme <span class="b">%1$s</span> with <span class="b">%2$s Widget</span>', 'Theme <span class="b">%1$s</span> with <span class="b">%2$s Widgets</span>', $num_widgets), $switch_themes, $num);
 412		}
 413	} else {
 414		if ( current_user_can( 'switch_themes' ) )
 415			printf( __('Theme <span class="b"><a href="themes.php">%1$s</a></span>'), $ct->title );
 416		else
 417			printf( __('Theme <span class="b">%1$s</span>'), $ct->title );
 418	}
 419	echo '</p>';
 420
 421	// Check if search engines are blocked.
 422	if ( !is_network_admin() && !is_user_admin() && current_user_can('manage_options') && '1' != get_option('blog_public') ) {
 423		$title = apply_filters('privacy_on_link_title', __('Your site is asking search engines not to index its content') );
 424		$content = apply_filters('privacy_on_link_text', __('Search Engines Blocked') );
 425
 426		echo "<p><a href='options-privacy.php' title='$title'>$content</a></p>";
 427	}
 428
 429	update_right_now_message();
 430
 431	echo "\n\t".'<br class="clear" /></div>';
 432	do_action( 'rightnow_end' );
 433	do_action( 'activity_box_end' );
 434}
 435
 436function wp_network_dashboard_right_now() {
 437	$actions = array();
 438	if ( current_user_can('create_sites') )
 439		$actions['create-site'] = '<a href="' . network_admin_url('site-new.php') . '">' . __( 'Create a New Site' ) . '</a>';
 440	if ( current_user_can('create_users') )
 441		$actions['create-user'] = '<a href="' . network_admin_url('user-new.php') . '">' . __( 'Create a New User' ) . '</a>';
 442
 443	$c_users = get_user_count();
 444	$c_blogs = get_blog_count();
 445
 446	$user_text = sprintf( _n( '%s user', '%s users', $c_users ), number_format_i18n( $c_users ) );
 447	$blog_text = sprintf( _n( '%s site', '%s sites', $c_blogs ), number_format_i18n( $c_blogs ) );
 448
 449	$sentence = sprintf( __( 'You have %1$s and %2$s.' ), $blog_text, $user_text );
 450
 451	if ( $actions ) {
 452		echo '<ul class="subsubsub">';
 453		foreach ( $actions as $class => $action ) {
 454			 $actions[ $class ] = "\t<li class='$class'>$action";
 455		}
 456		echo implode( " |</li>\n", $actions ) . "</li>\n";
 457		echo '</ul>';
 458	}
 459?>
 460	<br class="clear" />
 461
 462	<p class="youhave"><?php echo $sentence; ?></p>
 463	<?php do_action( 'wpmuadminresult', '' ); ?>
 464
 465	<form name="searchform" action="<?php echo network_admin_url('users.php'); ?>" method="get">
 466		<p>
 467			<input type="text" name="s" value="" size="17" />
 468			<?php submit_button( __( 'Search Users' ), 'button', 'submit', false, array( 'id' => 'submit_users' ) ); ?>
 469		</p>
 470	</form>
 471
 472	<form name="searchform" action="<?php echo network_admin_url('sites.php'); ?>" method="get">
 473		<p>
 474			<input type="text" name="s" value="" size="17" />
 475			<?php submit_button( __( 'Search Sites' ), 'button', 'submit', false, array( 'id' => 'submit_sites' ) ); ?>
 476		</p>
 477	</form>
 478<?php
 479	do_action( 'mu_rightnow_end' );
 480	do_action( 'mu_activity_box_end' );
 481}
 482
 483function wp_dashboard_quick_press() {
 484	global $post_ID;
 485
 486	$drafts = false;
 487	if ( 'post' === strtolower( $_SERVER['REQUEST_METHOD'] ) && isset( $_POST['action'] ) && 0 === strpos( $_POST['action'], 'post-quickpress' ) && (int) $_POST['post_ID'] ) {
 488		$view = get_permalink( $_POST['post_ID'] );
 489		$edit = esc_url( get_edit_post_link( $_POST['post_ID'] ) );
 490		if ( 'post-quickpress-publish' == $_POST['action'] ) {
 491			if ( current_user_can('publish_posts') )
 492				printf( '<div class="updated"><p>' . __( 'Post published. <a href="%s">View post</a> | <a href="%s">Edit post</a>' ) . '</p></div>', esc_url( $view ), $edit );
 493			else
 494				printf( '<div class="updated"><p>' . __( 'Post submitted. <a href="%s">Preview post</a> | <a href="%s">Edit post</a>' ) . '</p></div>', esc_url( add_query_arg( 'preview', 1, $view ) ), $edit );
 495		} else {
 496			printf( '<div class="updated"><p>' . __( 'Draft saved. <a href="%s">Preview post</a> | <a href="%s">Edit post</a>' ) . '</p></div>', esc_url( add_query_arg( 'preview', 1, $view ) ), $edit );
 497			$drafts_query = new WP_Query( array(
 498				'post_type' => 'post',
 499				'post_status' => 'draft',
 500				'author' => $GLOBALS['current_user']->ID,
 501				'posts_per_page' => 1,
 502				'orderby' => 'modified',
 503				'order' => 'DESC'
 504			) );
 505
 506			if ( $drafts_query->posts )
 507				$drafts =& $drafts_query->posts;
 508		}
 509		printf('<p class="textright">' . __('You can also try %s, easy blogging from anywhere on the Web.') . '</p>', '<a href="' . esc_url( admin_url( 'tools.php' ) ) . '">' . __('Press This') . '</a>' );
 510		$_REQUEST = array(); // hack for get_default_post_to_edit()
 511	}
 512
 513	/* Check if a new auto-draft (= no new post_ID) is needed or if the old can be used */
 514	$last_post_id = (int) get_user_option( 'dashboard_quick_press_last_post_id' ); // Get the last post_ID
 515	if ( $last_post_id ) {
 516		$post = get_post( $last_post_id );
 517		if ( empty( $post ) || $post->post_status != 'auto-draft' ) { // auto-draft doesn't exists anymore
 518			$post = get_default_post_to_edit('post', true);
 519			update_user_option( (int) $GLOBALS['current_user']->ID, 'dashboard_quick_press_last_post_id', (int) $post->ID ); // Save post_ID
 520		} else {
 521			$post->post_title = ''; // Remove the auto draft title
 522		}
 523	} else {
 524		$post = get_default_post_to_edit('post', true);
 525		update_user_option( (int) $GLOBALS['current_user']->ID, 'dashboard_quick_press_last_post_id', (int) $post->ID ); // Save post_ID
 526	}
 527
 528	$post_ID = (int) $post->ID;
 529?>
 530
 531	<form name="post" action="<?php echo esc_url( admin_url( 'post.php' ) ); ?>" method="post" id="quick-press">
 532		<h4 id="quick-post-title"><label for="title"><?php _e('Title') ?></label></h4>
 533		<div class="input-text-wrap">
 534			<input type="text" name="post_title" id="title" tabindex="1" autocomplete="off" value="<?php echo esc_attr( $post->post_title ); ?>" />
 535		</div>
 536
 537		<?php if ( current_user_can( 'upload_files' ) ) : ?>
 538		<div id="wp-content-wrap" class="wp-editor-wrap hide-if-no-js wp-media-buttons">
 539			<?php do_action( 'media_buttons', 'content' ); ?>
 540		</div>
 541		<?php endif; ?>
 542
 543		<h4 id="content-label"><label for="content"><?php _e('Content') ?></label></h4>
 544		<div class="textarea-wrap">
 545			<textarea name="content" id="content" class="mceEditor" rows="3" cols="15" tabindex="2"><?php echo esc_textarea( $post->post_content ); ?></textarea>
 546		</div>
 547
 548		<script type="text/javascript">edCanvas = document.getElementById('content');edInsertContent = null;</script>
 549
 550		<h4><label for="tags-input"><?php _e('Tags') ?></label></h4>
 551		<div class="input-text-wrap">
 552			<input type="text" name="tags_input" id="tags-input" tabindex="3" value="<?php echo get_tags_to_edit( $post->ID ); ?>" />
 553		</div>
 554
 555		<p class="submit">
 556			<input type="hidden" name="action" id="quickpost-action" value="post-quickpress-save" />
 557			<input type="hidden" name="post_ID" value="<?php echo $post_ID; ?>" />
 558			<input type="hidden" name="post_type" value="post" />
 559			<?php wp_nonce_field('add-post'); ?>
 560			<?php submit_button( __( 'Save Draft' ), 'button', 'save', false, array( 'id' => 'save-post', 'tabindex'=> 4 ) ); ?>
 561			<input type="reset" value="<?php esc_attr_e( 'Reset' ); ?>" class="button" />
 562			<span id="publishing-action">
 563				<input type="submit" name="publish" id="publish" accesskey="p" tabindex="5" class="button-primary" value="<?php current_user_can('publish_posts') ? esc_attr_e('Publish') : esc_attr_e('Submit for Review'); ?>" />
 564				<img class="waiting" src="<?php echo esc_url( admin_url( 'images/wpspin_light.gif' ) ); ?>" alt="" />
 565			</span>
 566			<br class="clear" />
 567		</p>
 568
 569	</form>
 570
 571<?php
 572	if ( $drafts )
 573		wp_dashboard_recent_drafts( $drafts );
 574}
 575
 576function wp_dashboard_recent_drafts( $drafts = false ) {
 577	if ( !$drafts ) {
 578		$drafts_query = new WP_Query( array(
 579			'post_type' => 'post',
 580			'post_status' => 'draft',
 581			'author' => $GLOBALS['current_user']->ID,
 582			'posts_per_page' => 5,
 583			'orderby' => 'modified',
 584			'order' => 'DESC'
 585		) );
 586		$drafts =& $drafts_query->posts;
 587	}
 588
 589	if ( $drafts && is_array( $drafts ) ) {
 590		$list = array();
 591		foreach ( $drafts as $draft ) {
 592			$url = get_edit_post_link( $draft->ID );
 593			$title = _draft_or_post_title( $draft->ID );
 594			$item = "<h4><a href='$url' title='" . sprintf( __( 'Edit &#8220;%s&#8221;' ), esc_attr( $title ) ) . "'>" . esc_html($title) . "</a> <abbr title='" . get_the_time(__('Y/m/d g:i:s A'), $draft) . "'>" . get_the_time( get_option( 'date_format' ), $draft ) . '</abbr></h4>';
 595			if ( $the_content = preg_split( '#\s#', strip_tags( $draft->post_content ), 11, PREG_SPLIT_NO_EMPTY ) )
 596				$item .= '<p>' . join( ' ', array_slice( $the_content, 0, 10 ) ) . ( 10 < count( $the_content ) ? '&hellip;' : '' ) . '</p>';
 597			$list[] = $item;
 598		}
 599?>
 600	<ul>
 601		<li><?php echo join( "</li>\n<li>", $list ); ?></li>
 602	</ul>
 603	<p class="textright"><a href="edit.php?post_status=draft" ><?php _e('View all'); ?></a></p>
 604<?php
 605	} else {
 606		_e('There are no drafts at the moment');
 607	}
 608}
 609
 610/**
 611 * Display recent comments dashboard widget content.
 612 *
 613 * @since 2.5.0
 614 */
 615function wp_dashboard_recent_comments() {
 616	global $wpdb;
 617
 618	if ( current_user_can('edit_posts') )
 619		$allowed_states = array('0', '1');
 620	else
 621		$allowed_states = array('1');
 622
 623	// Select all comment types and filter out spam later for better query performance.
 624	$comments = array();
 625	$start = 0;
 626
 627	$widgets = get_option( 'dashboard_widget_options' );
 628	$total_items = isset( $widgets['dashboard_recent_comments'] ) && isset( $widgets['dashboard_recent_comments']['items'] )
 629		? absint( $widgets['dashboard_recent_comments']['items'] ) : 5;
 630
 631	while ( count( $comments ) < $total_items && $possible = $wpdb->get_results( "SELECT * FROM $wpdb->comments c LEFT JOIN $wpdb->posts p ON c.comment_post_ID = p.ID WHERE p.post_status != 'trash' ORDER BY c.comment_date_gmt DESC LIMIT $start, 50" ) ) {
 632
 633		foreach ( $possible as $comment ) {
 634			if ( count( $comments ) >= $total_items )
 635				break;
 636			if ( in_array( $comment->comment_approved, $allowed_states ) && current_user_can( 'read_post', $comment->comment_post_ID ) )
 637				$comments[] = $comment;
 638		}
 639
 640		$start = $start + 50;
 641	}
 642
 643	if ( $comments ) :
 644?>
 645
 646		<div id="the-comment-list" class="list:comment">
 647<?php
 648		foreach ( $comments as $comment )
 649			_wp_dashboard_recent_comments_row( $comment );
 650?>
 651
 652		</div>
 653
 654<?php
 655		if ( current_user_can('edit_posts') ) { ?>
 656			<?php _get_list_table('WP_Comments_List_Table')->views(); ?>
 657<?php	}
 658
 659		wp_comment_reply( -1, false, 'dashboard', false );
 660		wp_comment_trashnotice();
 661
 662	else :
 663?>
 664
 665	<p><?php _e( 'No comments yet.' ); ?></p>
 666
 667<?php
 668	endif; // $comments;
 669}
 670
 671function _wp_dashboard_recent_comments_row( &$comment, $show_date = true ) {
 672	$GLOBALS['comment'] =& $comment;
 673
 674	$comment_post_url = get_edit_post_link( $comment->comment_post_ID );
 675	$comment_post_title = strip_tags(get_the_title( $comment->comment_post_ID ));
 676	$comment_post_link = "<a href='$comment_post_url'>$comment_post_title</a>";
 677	$comment_link = '<a class="comment-link" href="' . esc_url(get_comment_link()) . '">#</a>';
 678
 679	$actions_string = '';
 680	if ( current_user_can( 'edit_comment', $comment->comment_ID ) ) {
 681		// preorder it: Approve | Reply | Edit | Spam | Trash
 682		$actions = array(
 683			'approve' => '', 'unapprove' => '',
 684			'reply' => '',
 685			'edit' => '',
 686			'spam' => '',
 687			'trash' => '', 'delete' => ''
 688		);
 689
 690		$del_nonce = esc_html( '_wpnonce=' . wp_create_nonce( "delete-comment_$comment->comment_ID" ) );
 691		$approve_nonce = esc_html( '_wpnonce=' . wp_create_nonce( "approve-comment_$comment->comment_ID" ) );
 692
 693		$approve_url = esc_url( "comment.php?action=approvecomment&p=$comment->comment_post_ID&c=$comment->comment_ID&$approve_nonce" );
 694		$unapprove_url = esc_url( "comment.php?action=unapprovecomment&p=$comment->comment_post_ID&c=$comment->comment_ID&$approve_nonce" );
 695		$spam_url = esc_url( "comment.php?action=spamcomment&p=$comment->comment_post_ID&c=$comment->comment_ID&$del_nonce" );
 696		$trash_url = esc_url( "comment.php?action=trashcomment&p=$comment->comment_post_ID&c=$comment->comment_ID&$del_nonce" );
 697		$delete_url = esc_url( "comment.php?action=deletecomment&p=$comment->comment_post_ID&c=$comment->comment_ID&$del_nonce" );
 698
 699		$actions['approve'] = "<a href='$approve_url' class='dim:the-comment-list:comment-$comment->comment_ID:unapproved:e7e7d3:e7e7d3:new=approved vim-a' title='" . esc_attr__( 'Approve this comment' ) . "'>" . __( 'Approve' ) . '</a>';
 700		$actions['unapprove'] = "<a href='$unapprove_url' class='dim:the-comment-list:comment-$comment->comment_ID:unapproved:e7e7d3:e7e7d3:new=unapproved vim-u' title='" . esc_attr__( 'Unapprove this comment' ) . "'>" . __( 'Unapprove' ) . '</a>';
 701		$actions['edit'] = "<a href='comment.php?action=editcomment&amp;c={$comment->comment_ID}' title='" . esc_attr__('Edit comment') . "'>". __('Edit') . '</a>';
 702		$actions['reply'] = '<a onclick="commentReply.open(\''.$comment->comment_ID.'\',\''.$comment->comment_post_ID.'\');return false;" class="vim-r hide-if-no-js" title="'.esc_attr__('Reply to this comment').'" href="#">' . __('Reply') . '</a>';
 703		$actions['spam'] = "<a href='$spam_url' class='delete:the-comment-list:comment-$comment->comment_ID::spam=1 vim-s vim-destructive' title='" . esc_attr__( 'Mark this comment as spam' ) . "'>" . /* translators: mark as spam link */  _x( 'Spam', 'verb' ) . '</a>';
 704		if ( !EMPTY_TRASH_DAYS )
 705			$actions['delete'] = "<a href='$delete_url' class='delete:the-comment-list:comment-$comment->comment_ID::trash=1 delete vim-d vim-destructive'>" . __('Delete Permanently') . '</a>';
 706		else
 707			$actions['trash'] = "<a href='$trash_url' class='delete:the-comment-list:comment-$comment->comment_ID::trash=1 delete vim-d vim-destructive' title='" . esc_attr__( 'Move this comment to the trash' ) . "'>" . _x('Trash', 'verb') . '</a>';
 708
 709		$actions = apply_filters( 'comment_row_actions', array_filter($actions), $comment );
 710
 711		$i = 0;
 712		foreach ( $actions as $action => $link ) {
 713			++$i;
 714			( ( ('approve' == $action || 'unapprove' == $action) && 2 === $i ) || 1 === $i ) ? $sep = '' : $sep = ' | ';
 715
 716			// Reply and quickedit need a hide-if-no-js span
 717			if ( 'reply' == $action || 'quickedit' == $action )
 718				$action .= ' hide-if-no-js';
 719
 720			$actions_string .= "<span class='$action'>$sep$link</span>";
 721		}
 722	}
 723
 724?>
 725
 726		<div id="comment-<?php echo $comment->comment_ID; ?>" <?php comment_class( array( 'comment-item', wp_get_comment_status($comment->comment_ID) ) ); ?>>
 727			<?php if ( !$comment->comment_type || 'comment' == $comment->comment_type ) : ?>
 728
 729			<?php echo get_avatar( $comment, 50 ); ?>
 730
 731			<div class="dashboard-comment-wrap">
 732			<h4 class="comment-meta">
 733				<?php printf( /* translators: 1: comment author, 2: post link, 3: notification if the comment is pending */__( 'From %1$s on %2$s%3$s' ),
 734					'<cite class="comment-author">' . get_comment_author_link() . '</cite>', $comment_post_link.' '.$comment_link, ' <span class="approve">' . __( '[Pending]' ) . '</span>' ); ?>
 735			</h4>
 736
 737			<?php
 738			else :
 739				switch ( $comment->comment_type ) :
 740				case 'pingback' :
 741					$type = __( 'Pingback' );
 742					break;
 743				case 'trackback' :
 744					$type = __( 'Trackback' );
 745					break;
 746				default :
 747					$type = ucwords( $comment->comment_type );
 748				endswitch;
 749				$type = esc_html( $type );
 750			?>
 751			<div class="dashboard-comment-wrap">
 752			<?php /* translators: %1$s is type of comment, %2$s is link to the post */ ?>
 753			<h4 class="comment-meta"><?php printf( _x( '%1$s on %2$s', 'dashboard' ), "<strong>$type</strong>", $comment_post_link." ".$comment_link ); ?></h4>
 754			<p class="comment-author"><?php comment_author_link(); ?></p>
 755
 756			<?php endif; // comment_type ?>
 757			<blockquote><p><?php comment_excerpt(); ?></p></blockquote>
 758			<p class="row-actions"><?php echo $actions_string; ?></p>
 759			</div>
 760		</div>
 761<?php
 762}
 763
 764/**
 765 * The recent comments dashboard widget control.
 766 *
 767 * @since 3.0.0
 768 */
 769function wp_dashboard_recent_comments_control() {
 770	if ( !$widget_options = get_option( 'dashboard_widget_options' ) )
 771		$widget_options = array();
 772
 773	if ( !isset($widget_options['dashboard_recent_comments']) )
 774		$widget_options['dashboard_recent_comments'] = array();
 775
 776	if ( 'POST' == $_SERVER['REQUEST_METHOD'] && isset($_POST['widget-recent-comments']) ) {
 777		$number = absint( $_POST['widget-recent-comments']['items'] );
 778		$widget_options['dashboard_recent_comments']['items'] = $number;
 779		update_option( 'dashboard_widget_options', $widget_options );
 780	}
 781
 782	$number = isset( $widget_options['dashboard_recent_comments']['items'] ) ? (int) $widget_options['dashboard_recent_comments']['items'] : '';
 783
 784	echo '<p><label for="comments-number">' . __('Number of comments to show:') . '</label>';
 785	echo '<input id="comments-number" name="widget-recent-comments[items]" type="text" value="' . $number . '" size="3" /></p>';
 786}
 787
 788function wp_dashboard_incoming_links() {
 789	wp_dashboard_cached_rss_widget( 'dashboard_incoming_links', 'wp_dashboard_incoming_links_output' );
 790}
 791
 792/**
 793 * Display incoming links dashboard widget content.
 794 *
 795 * @since 2.5.0
 796 */
 797function wp_dashboard_incoming_links_output() {
 798	$widgets = get_option( 'dashboard_widget_options' );
 799	@extract( @$widgets['dashboard_incoming_links'], EXTR_SKIP );
 800	$rss = fetch_feed( $url );
 801
 802	if ( is_wp_error($rss) ) {
 803		if ( is_admin() || current_user_can('manage_options') ) {
 804			echo '<p>';
 805			printf(__('<strong>RSS Error</strong>: %s'), $rss->get_error_message());
 806			echo '</p>';
 807		}
 808		return;
 809	}
 810
 811	if ( !$rss->get_item_quantity() ) {
 812		echo '<p>' . __('This dashboard widget queries <a href="http://blogsearch.google.com/">Google Blog Search</a> so that when another blog links to your site it will show up here. It has found no incoming links&hellip; yet. It&#8217;s okay &#8212; there is no rush.') . "</p>\n";
 813		$rss->__destruct();
 814		unset($rss);
 815		return;
 816	}
 817
 818	echo "<ul>\n";
 819
 820	if ( !isset($items) )
 821		$items = 10;
 822
 823	foreach ( $rss->get_items(0, $items) as $item ) {
 824		$publisher = '';
 825		$site_link = '';
 826		$link = '';
 827		$content = '';
 828		$date = '';
 829		$link = esc_url( strip_tags( $item->get_link() ) );
 830
 831		$author = $item->get_author();
 832		if ( $author ) {
 833			$site_link = esc_url( strip_tags( $author->get_link() ) );
 834
 835			if ( !$publisher = esc_html( strip_tags( $author->get_name() ) ) )
 836				$publisher = __( 'Somebody' );
 837		} else {
 838		  $publisher = __( 'Somebody' );
 839		}
 840		if ( $site_link )
 841			$publisher = "<a href='$site_link'>$publisher</a>";
 842		else
 843			$publisher = "<strong>$publisher</strong>";
 844
 845		$content = $item->get_content();
 846		$content = wp_html_excerpt($content, 50) . ' ...';
 847
 848		if ( $link )
 849			/* translators: incoming links feed, %1$s is other person, %3$s is content */
 850			$text = __( '%1$s linked here <a href="%2$s">saying</a>, "%3$s"' );
 851		else
 852			/* translators: incoming links feed, %1$s is other person, %3$s is content */
 853			$text = __( '%1$s linked here saying, "%3$s"' );
 854
 855		if ( !empty($show_date) ) {
 856			if ( !empty($show_author) || !empty($show_summary) )
 857				/* translators: incoming links feed, %4$s is the date */
 858				$text .= ' ' . __( 'on %4$s' );
 859			$date = esc_html( strip_tags( $item->get_date() ) );
 860			$date = strtotime( $date );
 861			$date = gmdate( get_option( 'date_format' ), $date );
 862		}
 863
 864		echo "\t<li>" . sprintf( $text, $publisher, $link, $content, $date ) . "</li>\n";
 865	}
 866
 867	echo "</ul>\n";
 868	$rss->__destruct();
 869	unset($rss);
 870}
 871
 872function wp_dashboard_incoming_links_control() {
 873	wp_dashboard_rss_control( 'dashboard_incoming_links', array( 'title' => false, 'show_summary' => false, 'show_author' => false ) );
 874}
 875
 876function wp_dashboard_primary() {
 877	wp_dashboard_cached_rss_widget( 'dashboard_primary', 'wp_dashboard_rss_output' );
 878}
 879
 880function wp_dashboard_primary_control() {
 881	wp_dashboard_rss_control( 'dashboard_primary' );
 882}
 883
 884/**
 885 * {@internal Missing Short Description}}
 886 *
 887 * @since 2.5.0
 888 *
 889 * @param string $widget_id
 890 */
 891function wp_dashboard_rss_output( $widget_id ) {
 892	$widgets = get_option( 'dashboard_widget_options' );
 893	echo '<div class="rss-widget">';
 894	wp_widget_rss_output( $widgets[$widget_id] );
 895	echo "</div>";
 896}
 897
 898function wp_dashboard_secondary() {
 899	wp_dashboard_cached_rss_widget( 'dashboard_secondary', 'wp_dashboard_secondary_output' );
 900}
 901
 902function wp_dashboard_secondary_control() {
 903	wp_dashboard_rss_control( 'dashboard_secondary' );
 904}
 905
 906/**
 907 * Display secondary dashboard RSS widget feed.
 908 *
 909 * @since 2.5.0
 910 *
 911 * @return unknown
 912 */
 913function wp_dashboard_secondary_output() {
 914	$widgets = get_option( 'dashboard_widget_options' );
 915	@extract( @$widgets['dashboard_secondary'], EXTR_SKIP );
 916	$rss = @fetch_feed( $url );
 917
 918	if ( is_wp_error($rss) ) {
 919		if ( is_admin() || current_user_can('manage_options') ) {
 920			echo '<div class="rss-widget"><p>';
 921			printf(__('<strong>RSS Error</strong>: %s'), $rss->get_error_message());
 922			echo '</p></div>';
 923		}
 924	} elseif ( !$rss->get_item_quantity() ) {
 925		$rss->__destruct();
 926		unset($rss);
 927		return false;
 928	} else {
 929		echo '<div class="rss-widget">';
 930		wp_widget_rss_output( $rss, $widgets['dashboard_secondary'] );
 931		echo '</div>';
 932		$rss->__destruct();
 933		unset($rss);
 934	}
 935}
 936
 937function wp_dashboard_plugins() {
 938	wp_dashboard_cached_rss_widget( 'dashboard_plugins', 'wp_dashboard_plugins_output', array(
 939		'http://wordpress.org/extend/plugins/rss/browse/popular/',
 940		'http://wordpress.org/extend/plugins/rss/browse/new/',
 941		'http://wordpress.org/extend/plugins/rss/browse/updated/'
 942	) );
 943}
 944
 945/**
 946 * Display plugins most popular, newest plugins, and recently updated widget text.
 947 *
 948 * @since 2.5.0
 949 */
 950function wp_dashboard_plugins_output() {
 951	$popular = fetch_feed( 'http://wordpress.org/extend/plugins/rss/browse/popular/' );
 952	$new     = fetch_feed( 'http://wordpress.org/extend/plugins/rss/browse/new/' );
 953	$updated = fetch_feed( 'http://wordpress.org/extend/plugins/rss/browse/updated/' );
 954
 955	if ( false === $plugin_slugs = get_transient( 'plugin_slugs' ) ) {
 956		$plugin_slugs = array_keys( get_plugins() );
 957		set_transient( 'plugin_slugs', $plugin_slugs, 86400 );
 958	}
 959
 960	foreach ( array( 'popular' => __('Most Popular'), 'new' => __('Newest Plugins'), 'updated' => __('Recently Updated') ) as $feed => $label ) {
 961		if ( is_wp_error($$feed) || !$$feed->get_item_quantity() )
 962			continue;
 963
 964		$items = $$feed->get_items(0, 5);
 965
 966		// Pick a random, non-installed plugin
 967		while ( true ) {
 968			// Abort this foreach loop iteration if there's no plugins left of this type
 969			if ( 0 == count($items) )
 970				continue 2;
 971
 972			$item_key = array_rand($items);
 973			$item = $items[$item_key];
 974
 975			list($link, $frag) = explode( '#', $item->get_link() );
 976
 977			$link = esc_url($link);
 978			if ( preg_match( '|/([^/]+?)/?$|', $link, $matches ) )
 979				$slug = $matches[1];
 980			else {
 981				unset( $items[$item_key] );
 982				continue;
 983			}
 984
 985			// Is this random plugin's slug already installed? If so, try again.
 986			reset( $plugin_slugs );
 987			foreach ( $plugin_slugs as $plugin_slug ) {
 988				if ( $slug == substr( $plugin_slug, 0, strlen( $slug ) ) ) {
 989					unset( $items[$item_key] );
 990					continue 2;
 991				}
 992			}
 993
 994			// If we get to this point, then the random plugin isn't installed and we can stop the while().
 995			break;
 996		}
 997
 998		// Eliminate some common badly formed plugin descriptions
 999		while ( ( null !== $item_key = array_rand($items) ) && false !== strpos( $items[$item_key]->get_description(), 'Plugin Name:' ) )
1000			unset($items[$item_key]);
1001
1002		if ( !isset($items[$item_key]) )
1003			continue;
1004
1005		// current bbPress feed item titles are: user on "topic title"
1006		if ( preg_match( '/&quot;(.*)&quot;/s', $item->get_title(), $matches ) )
1007			$title = $matches[1];
1008		else // but let's make it forward compatible if things change
1009			$title = $item->get_title();
1010		$title = esc_html( $title );
1011
1012		$description = esc_html( strip_tags(@html_entity_decode($item->get_description(), ENT_QUOTES, get_option('blog_charset'))) );
1013
1014		$ilink = wp_nonce_url('plugin-install.php?tab=plugin-information&plugin=' . $slug, 'install-plugin_' . $slug) .
1015							'&amp;TB_iframe=true&amp;width=600&amp;height=800';
1016
1017		echo "<h4>$label</h4>\n";
1018		echo "<h5><a href='$link'>$title</a></h5>&nbsp;<span>(<a href='$ilink' class='thickbox' title='$title'>" . __( 'Install' ) . "</a>)</span>\n";
1019		echo "<p>$description</p>\n";
1020
1021		$$feed->__destruct();
1022		unset($$feed);
1023	}
1024}
1025
1026/**
1027 * Checks to see if all of the feed url in $check_urls are cached.
1028 *
1029 * If $check_urls is empty, look for the rss feed url found in the dashboard
1030 * widget options of $widget_id. If cached, call $callback, a function that
1031 * echoes out output for this widget. If not cache, echo a "Loading..." stub
1032 * which is later replaced by AJAX call (see top of /wp-admin/index.php)
1033 *
1034 * @since 2.5.0
1035 *
1036 * @param string $widget_id
1037 * @param callback $callback
1038 * @param array $check_urls RSS feeds
1039 * @return bool False on failure. True on success.
1040 */
1041function wp_dashboard_cached_rss_widget( $widget_id, $callback, $check_urls = array() ) {
1042	$loading = '<p class="widget-loading hide-if-no-js">' . __( 'Loading&#8230;' ) . '</p><p class="hide-if-js">' . __( 'This widget requires JavaScript.' ) . '</p>';
1043	$doing_ajax = ( defined('DOING_AJAX') && DOING_AJAX );
1044
1045	if ( empty($check_urls) ) {
1046		$widgets = get_option( 'dashboard_widget_options' );
1047		if ( empty($widgets[$widget_id]['url']) && ! $doing_ajax ) {
1048			echo $loading;
1049			return false;
1050		}
1051		$check_urls = array( $widgets[$widget_id]['url'] );
1052	}
1053
1054	$cache_key = 'dash_' . md5( $widget_id );
1055	if ( false !== ( $output = get_transient( $cache_key ) ) ) {
1056		echo $output;
1057		return true;
1058	}
1059
1060	if ( ! $doing_ajax ) {
1061		echo $loading;
1062		return false;
1063	}
1064
1065	if ( $callback && is_callable( $callback ) ) {
1066		$args = array_slice( func_get_args(), 2 );
1067		array_unshift( $args, $widget_id );
1068		ob_start();
1069		call_user_func_array( $callback, $args );
1070		set_transient( $cache_key, ob_get_flush(), 43200); // Default lifetime in cache of 12 hours (same as the feeds)
1071	}
1072
1073	return true;
1074}
1075
1076/* Dashboard Widgets Controls */
1077
1078// Calls widget_control callback
1079/**
1080 * Calls widget control callback.
1081 *
1082 * @since 2.5.0
1083 *
1084 * @param int $widget_control_id Registered Widget ID.
1085 */
1086function wp_dashboard_trigger_widget_control( $widget_control_id = false ) {
1087	global $wp_dashboard_control_callbacks;
1088
1089	if ( is_scalar($widget_control_id) && $widget_control_id && isset($wp_dashboard_control_callbacks[$widget_control_id]) && is_callable($wp_dashboard_control_callbacks[$widget_control_id]) ) {
1090		call_user_func( $wp_dashboard_control_callbacks[$widget_control_id], '', array( 'id' => $widget_control_id, 'callback' => $wp_dashboard_control_callbacks[$widget_control_id] ) );
1091	}
1092}
1093
1094/**
1095 * The RSS dashboard widget control.
1096 *
1097 * Sets up $args to be used as input to wp_widget_rss_form(). Handles POST data
1098 * from RSS-type widgets.
1099 *
1100 * @since 2.5.0
1101 *
1102 * @param string $widget_id
1103 * @param array $form_inputs
1104 */
1105function wp_dashboard_rss_control( $widget_id, $form_inputs = array() ) {
1106	if ( !$widget_options = get_option( 'dashboard_widget_options' ) )
1107		$widget_options = array();
1108
1109	if ( !isset($widget_options[$widget_id]) )
1110		$widget_options[$widget_id] = array();
1111
1112	$number = 1; // Hack to use wp_widget_rss_form()
1113	$widget_options[$widget_id]['number'] = $number;
1114
1115	if ( 'POST' == $_SERVER['REQUEST_METHOD'] && isset($_POST['widget-rss'][$number]) ) {
1116		$_POST['widget-rss'][$number] = stripslashes_deep( $_POST['widget-rss'][$number] );
1117		$widget_options[$widget_id] = wp_widget_rss_process( $_POST['widget-rss'][$number] );
1118		// title is optional.  If black, fill it if possible
1119		if ( !$widget_options[$widget_id]['title'] && isset($_POST['widget-rss'][$number]['title']) ) {
1120			$rss = fetch_feed($widget_options[$widget_id]['url']);
1121			if ( is_wp_error($rss) ) {
1122				$widget_options[$widget_id]['title'] = htmlentities(__('Unknown Feed'));
1123			} else {
1124				$widget_options[$widget_id]['title'] = htmlentities(strip_tags($rss->get_title()));
1125				$rss->__destruct();
1126				unset($rss);
1127			}
1128		}
1129		update_option( 'dashboard_widget_options', $widget_options );
1130		$cache_key = 'dash_' . md5( $widget_id );
1131		delete_transient( $cache_key );
1132	}
1133
1134	wp_widget_rss_form( $widget_options[$widget_id], $form_inputs );
1135}
1136
1137// Display File upload quota on dashboard
1138function wp_dashboard_quota() {
1139	if ( !is_multisite() || !current_user_can('upload_files') || get_site_option( 'upload_space_check_disabled' ) )
1140		return true;
1141
1142	$quota = get_space_allowed();
1143	$used = get_dirsize( BLOGUPLOADDIR ) / 1024 / 1024;
1144
1145	if ( $used > $quota )
1146		$percentused = '100';
1147	else
1148		$percentused = ( $used / $quota ) * 100;
1149	$used_color = ( $percentused >= 70 ) ? ' spam' : '';
1150	$used = round( $used, 2 );
1151	$percentused = number_format( $percentused );
1152
1153	?>
1154	<p class="sub musub"><?php _e( 'Storage Space' ); ?></p>
1155	<div class="table table_content musubtable">
1156	<table>
1157		<tr class="first">
1158			<td class="first b b-posts"><?php printf( __( '<a href="%1$s" title="Manage Uploads" class="musublink">%2$sMB</a>' ), esc_url( admin_url( 'upload.php' ) ), $quota ); ?></td>
1159			<td class="t posts"><?php _e( 'Space Allowed' ); ?></td>
1160		</tr>
1161	</table>
1162	</div>
1163	<div class="table table_discussion musubtable">
1164	<table>
1165		<tr class="first">
1166			<td class="b b-comments"><?php printf( __( '<a href="%1$s" title="Manage Uploads" class="musublink">%2$sMB (%3$s%%)</a>' ), esc_url( admin_url( 'upload.php' ) ), $used, $percentused ); ?></td>
1167			<td class="last t comments<?php echo $used_color;?>"><?php _e( 'Space Used' );?></td>
1168		</tr>
1169	</table>
1170	</div>
1171	<br class="clear" />
1172	<?php
1173}
1174add_action( 'activity_box_end', 'wp_dashboard_quota' );
1175
1176// Display Browser Nag Meta Box
1177function wp_dashboard_browser_nag() {
1178	$notice = '';
1179	$response = wp_check_browser_version();
1180
1181	if ( $response ) {
1182		if ( $response['insecure'] ) {
1183			$msg = sprintf( __( "It looks like you're using an insecure version of <a href='%s'>%s</a>. Using an outdated browser makes your computer unsafe. For the best WordPress experience, please update your browser." ), esc_attr( $response['update_url'] ), esc_html( $response['name'] ) );
1184		} else {
1185			$msg = sprintf( __( "It looks like you're using an old version of <a href='%s'>%s</a>. For the best WordPress experience, please update your browser." ), esc_attr( $response['update_url'] ), esc_html( $response['name'] ) );
1186		}
1187
1188		$browser_nag_class = '';
1189		if ( !empty( $response['img_src'] ) ) {
1190			$img_src = ( is_ssl() && ! empty( $response['img_src_ssl'] ) )? $response['img_src_ssl'] : $response['img_src'];
1191
1192			$notice .= '<div class="alignright browser-icon"><a href="' . esc_attr($response['update_url']) . '"><img src="' . esc_attr( $img_src ) . '" alt="" /></a></div>';
1193			$browser_nag_class = ' has-browser-icon';
1194		}
1195		$notice .= "<p class='browser-update-nag{$browser_nag_class}'>{$msg}</p>";
1196		$notice .= '<p>' . sprintf( __( '<a href="%1$s" class="update-browser-link">Update %2$s</a> or learn how to <a href="%3$s" class="browse-happy-link">browse happy</a>' ), esc_attr( $response['update_url'] ), esc_html( $response['name'] ), 'http://browsehappy.com/' ) . '</p>';
1197		$notice .= '<p class="hide-if-no-js"><a href="" class="dismiss">' . __( 'Dismiss' ) . '</a></p>';
1198		$notice .= '<div class="clear"></div>';
1199	}
1200
1201	echo apply_filters( 'browse-happy-notice', $notice, $response );
1202}
1203
1204function dashboard_browser_nag_class( $classes ) {
1205	$response = wp_check_browser_version();
1206
1207	if ( $response && $response['insecure'] )
1208		$classes[] = 'browser-insecure';
1209
1210	return $classes;
1211}
1212
1213/**
1214 * Check if the user needs a browser update
1215 *
1216 * @since 3.2.0
1217 *
1218 * @return array|bool False on failure, array of browser data on success.
1219 */
1220function wp_check_browser_version() {
1221	if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
1222		return false;
1223
1224	$key = md5( $_SERVER['HTTP_USER_AGENT'] );
1225
1226	if ( false === ($response = get_site_transient('browser_' . $key) ) ) {
1227		global $wp_version;
1228
1229		$options = array(
1230			'body'			=> array( 'useragent' => $_SERVER['HTTP_USER_AGENT'] ),
1231			'user-agent'	=> 'WordPress/' . $wp_version . '; ' . get_bloginfo( 'url' )
1232		);
1233
1234		$response = wp_remote_post( 'http://api.wordpress.org/core/browse-happy/1.0/', $options );
1235
1236		if ( is_wp_error( $response ) || 200 != wp_remote_retrieve_response_code( $response ) )
1237			return false;
1238
1239		/**
1240		 * Response should be an array with:
1241		 *  'name' - string - A user friendly browser name
1242		 *  'version' - string - The most recent version of the browser
1243		 *  'current_version' - string - The version of the browser the user is using
1244		 *  'upgrade' - boolean - Whether the browser needs an upgrade
1245		 *  'insecure' - boolean - Whether the browser is deemed insecure
1246		 *  'upgrade_url' - string - The url to visit to upgrade
1247		 *  'img_src' - string - An image representing the browser
1248		 *  'img_src_ssl' - string - An image (over SSL) representing the browser
1249		 */
1250		$response = unserialize( wp_remote_retrieve_body( $response ) );
1251
1252		if ( ! $response )
1253			return false;
1254
1255		set_site_transient( 'browser_' . $key, $response, 604800 ); // cache for 1 week
1256	}
1257
1258	return $response;
1259}
1260
1261/**
1262 * Empty function usable by plugins to output empty dashboard widget (to be populated later by JS).
1263 */
1264function wp_dashboard_empty() {}
1265
1266/**
1267 * Displays a welcome panel to introduce users to WordPress.
1268 *
1269 * @since 3.3
1270 */
1271function wp_welcome_panel() {
1272	global $wp_version;
1273
1274	if ( ! current_user_can( 'edit_theme_options' ) )
1275		return;
1276
1277	$classes = 'welcome-panel';
1278
1279	$option = get_user_meta( get_current_user_id(), 'show_welcome_panel', true );
1280	// 0 = hide, 1 = toggled to show or single site creator, 2 = multisite site owner
1281	$hide = 0 == $option || ( 2 == $option && wp_get_current_user()->user_email != get_option( 'admin_email' ) );
1282	if ( $hide )
1283		$classes .= ' hidd…

Large files files are truncated, but you can click here to view the full file