]> scripts.mit.edu Git - autoinstalls/wordpress.git/blob - wp-admin/includes/dashboard.php
80be66bd8e66e1175e99b32e61a9d9db5946b5aa
[autoinstalls/wordpress.git] / wp-admin / includes / dashboard.php
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  */
16 function 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
148 function 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
182 function _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  */
195 function 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
248 function 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 )
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
436 function 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
483 function 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
576 function 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  */
615 function 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
671 function _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  */
769 function 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
788 function 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  */
797 function 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
872 function wp_dashboard_incoming_links_control() {
873         wp_dashboard_rss_control( 'dashboard_incoming_links', array( 'title' => false, 'show_summary' => false, 'show_author' => false ) );
874 }
875
876 function wp_dashboard_primary() {
877         wp_dashboard_cached_rss_widget( 'dashboard_primary', 'wp_dashboard_rss_output' );
878 }
879
880 function 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  */
891 function 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
898 function wp_dashboard_secondary() {
899         wp_dashboard_cached_rss_widget( 'dashboard_secondary', 'wp_dashboard_secondary_output' );
900 }
901
902 function 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  */
913 function 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
937 function 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  */
950 function 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  */
1041 function 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  */
1086 function 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  */
1105 function 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
1138 function 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 }
1174 add_action( 'activity_box_end', 'wp_dashboard_quota' );
1175
1176 // Display Browser Nag Meta Box
1177 function 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
1204 function 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  */
1220 function 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  */
1264 function wp_dashboard_empty() {}
1265
1266 /**
1267  * Displays a welcome panel to introduce users to WordPress.
1268  *
1269  * @since 3.3
1270  */
1271 function 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 .= ' hidden';
1284
1285         list( $display_version ) = explode( '-', $wp_version );
1286         ?>
1287         <div id="welcome-panel" class="<?php echo esc_attr( $classes ); ?>">
1288         <?php wp_nonce_field( 'welcome-panel-nonce', 'welcomepanelnonce', false ); ?>
1289         <a class="welcome-panel-close" href="<?php echo esc_url( admin_url( '?welcome=0' ) ); ?>"><?php _e('Dismiss'); ?></a>
1290         <div class="wp-badge"><?php printf( __( 'Version %s' ), $display_version ); ?></div>
1291
1292         <div class="welcome-panel-content">
1293         <h3><?php _e( 'Welcome to your new WordPress site! ' ); ?></h3>
1294         <p class="about-description"><?php _e( 'If you need help getting started, check out our documentation on <a href="http://codex.wordpress.org/First_Steps_With_WordPress">First Steps with WordPress</a>. If you&#8217;d rather dive right in, here are a few things most people do first when they set up a new WordPress site. If you need help, use the Help tabs in the upper right corner to get information on how to use your current screen and where to go for more assistance.' ); ?></p>
1295         <div class="welcome-panel-column-container">
1296         <div class="welcome-panel-column">
1297                 <h4><span class="icon16 icon-settings"></span> <?php _e( 'Basic Settings' ); ?></h4>
1298                 <p><?php _e( 'Here are a few easy things you can do to get your feet wet. Make sure to click Save on each Settings screen.' ); ?></p>
1299                 <ul>
1300                 <li><?php echo sprintf( __( '<a href="%s">Choose your privacy setting</a>' ), esc_url( admin_url('options-privacy.php') ) ); ?></li>
1301                 <li><?php echo sprintf( __( '<a href="%s">Select your tagline and time zone</a>' ), esc_url( admin_url('options-general.php') ) ); ?></li>
1302                 <li><?php echo sprintf( __( '<a href="%s">Turn comments on or off</a>' ), esc_url( admin_url('options-discussion.php') ) ); ?></li>
1303                 <li><?php echo sprintf( __( '<a href="%s">Fill in your profile</a>' ), esc_url( admin_url('profile.php') ) ); ?></li>
1304                 </ul>
1305         </div>
1306         <div class="welcome-panel-column">
1307                 <h4><span class="icon16 icon-page"></span> <?php _e( 'Add Real Content' ); ?></h4>
1308                 <p><?php _e( 'Check out the sample page & post editors to see how it all works, then delete the default content and write your own!' ); ?></p>
1309                 <ul>
1310                 <li><?php echo sprintf( __( 'View the <a href="%1$s">sample page</a> and <a href="%2$s">post</a>' ), esc_url( get_permalink( 2 ) ), esc_url( get_permalink( 1 ) ) ); ?></li>
1311                 <li><?php echo sprintf( __( 'Delete the <a href="%1$s">sample page</a> and <a href="%2$s">post</a>' ), esc_url( admin_url('edit.php?post_type=page') ), esc_url( admin_url('edit.php') ) ); ?></li>
1312                 <li><?php echo sprintf( __( '<a href="%s">Create an About Me page</a>' ), esc_url( admin_url('edit.php?post_type=page') ) ); ?></li>
1313                 <li><?php echo sprintf( __( '<a href="%s">Write your first post</a>' ), esc_url( admin_url('post-new.php') ) ); ?></li>
1314                 </ul>
1315         </div>
1316         <div class="welcome-panel-column welcome-panel-last">
1317                 <h4><span class="icon16 icon-appearance"></span> <?php _e( 'Customize Your Site' ); ?></h4>
1318                 <?php
1319                 $ct = current_theme_info();
1320                 if ( empty ( $ct->stylesheet_dir ) ) :
1321                         echo '<p>';
1322                         printf( __( '<a href="%s">Install a theme</a> to get started customizing your site.' ), esc_url( admin_url( 'themes.php' ) ) );
1323                         echo '</p>';
1324                 else:
1325                         $customize_links = array();
1326                         if ( 'twentyeleven' == $ct->stylesheet )
1327                                 $customize_links[] = sprintf( __( '<a href="%s">Choose light or dark</a>' ), esc_url( admin_url( 'themes.php?page=theme_options' ) ) );
1328
1329                         if ( current_theme_supports( 'custom-background' ) )
1330                                 $customize_links[] = sprintf( __( '<a href="%s">Set a background color</a>' ), esc_url( admin_url( 'themes.php?page=custom-background' ) ) );
1331
1332                         if ( current_theme_supports( 'custom-header' ) )
1333                                 $customize_links[] = sprintf( __( '<a href="%s">Select a new header image</a>' ), esc_url( admin_url( 'themes.php?page=custom-header' ) ) );
1334
1335                         if ( current_theme_supports( 'widgets' ) )
1336                                 $customize_links[] = sprintf( __( '<a href="%s">Add some widgets</a>' ), esc_url( admin_url( 'widgets.php' ) ) );
1337
1338                         if ( ! empty( $customize_links ) ) {
1339                                 echo '<p>';
1340                                 printf( __( 'Use the current theme &mdash; %1$s &mdash; or <a href="%2$s">choose a new one</a>. If you stick with %3$s, here are a few ways to make your site look unique.' ), $ct->title, esc_url( admin_url( 'themes.php' ) ), $ct->title );
1341                                 echo '</p>';
1342                         ?>
1343                         <ul>
1344                                 <?php foreach ( $customize_links as $customize_link ) : ?>
1345                                 <li><?php echo $customize_link ?></li>
1346                                 <?php endforeach; ?>
1347                         </ul>
1348                         <?php
1349                         } else {
1350                                 echo '<p>';
1351                                 printf( __( 'Use the current theme &mdash; %1$s &mdash; or <a href="%2$s">choose a new one</a>.' ), $ct->title, esc_url( admin_url( 'themes.php' ) ) );
1352                                 echo '</p>';
1353                         }
1354                 endif; ?>
1355         </div>
1356         </div>
1357         <p class="welcome-panel-dismiss"><?php printf( __( 'Already know what you&#8217;re doing? <a href="%s">Dismiss this message</a>.' ), esc_url( admin_url( '?welcome=0' ) ) ); ?></p>
1358         </div>
1359         </div>
1360         <?php
1361 }
1362
1363 ?>