3 * WordPress Dashboard Widget Administration Screen API
6 * @subpackage Administration
10 * Registers dashboard widgets.
12 * Handles POST data, sets up filters.
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();
22 $widget_options = get_option( 'dashboard_widget_options' );
23 if ( !$widget_options || !is_array($widget_options) )
24 $widget_options = array();
26 /* Register Widgets and Controls */
28 $response = wp_check_browser_version();
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' );
35 wp_add_dashboard_widget( 'dashboard_browser_nag', __( 'Your browser is out of date!' ), 'wp_dashboard_browser_nag' );
39 if ( is_blog_admin() && current_user_can('edit_posts') )
40 wp_add_dashboard_widget( 'dashboard_right_now', __( 'Right Now' ), 'wp_dashboard_right_now' );
42 if ( is_network_admin() )
43 wp_add_dashboard_widget( 'network_dashboard_right_now', __( 'Right Now' ), 'wp_network_dashboard_right_now' );
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'] ) ) {
49 $widget_options['dashboard_recent_comments'] = array(
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' );
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') ) {
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
70 wp_add_dashboard_widget( 'dashboard_incoming_links', __( 'Incoming Links' ), 'wp_dashboard_incoming_links', 'wp_dashboard_incoming_links_control' );
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' );
78 if ( is_blog_admin() && current_user_can('edit_posts') )
79 wp_add_dashboard_widget( 'dashboard_quick_press', __( 'QuickPress' ), 'wp_dashboard_quick_press' );
82 if ( is_blog_admin() && current_user_can('edit_posts') )
83 wp_add_dashboard_widget( 'dashboard_recent_drafts', __('Recent Drafts'), 'wp_dashboard_recent_drafts' );
85 // Primary feed (Dev Blog) Widget
86 if ( !isset( $widget_options['dashboard_primary'] ) ) {
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' ) ),
98 wp_add_dashboard_widget( 'dashboard_primary', $widget_options['dashboard_primary']['title'], 'wp_dashboard_primary', 'wp_dashboard_primary_control' );
100 // Secondary Feed (Planet) Widget
101 if ( !isset( $widget_options['dashboard_secondary'] ) ) {
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' ) ),
113 wp_add_dashboard_widget( 'dashboard_secondary', $widget_options['dashboard_secondary']['title'], 'wp_dashboard_secondary', 'wp_dashboard_secondary_control' );
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() );
124 do_action( 'wp_dashboard_setup' );
125 $dashboard_widgets = apply_filters( 'wp_dashboard_widgets', array() );
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'] );
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'] );
137 wp_redirect( remove_query_arg( 'edit' ) );
142 update_option( 'dashboard_widget_options', $widget_options );
144 do_action('do_meta_boxes', $screen->id, 'normal', '');
145 do_action('do_meta_boxes', $screen->id, 'side', '');
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;
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';
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>';
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');
169 $side_widgets = array();
171 $location = 'normal';
172 if ( in_array($widget_id, $side_widgets) )
176 if ( 'dashboard_browser_nag' === $widget_id )
179 add_meta_box( $widget_id, $widget_name, $callback, $screen, $location, $priority );
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') );
191 * Displays the dashboard.
195 function wp_dashboard() {
196 $screen = get_current_screen();
197 $class = 'columns-' . get_current_screen()->get_columns();
200 <div id="dashboard-widgets" class="metabox-holder <?php echo $class; ?>">
201 <div id='postbox-container-1' class='postbox-container'>
202 <?php do_meta_boxes( $screen->id, 'normal', '' ); ?>
204 <div id='postbox-container-2' class='postbox-container'>
205 <?php do_meta_boxes( $screen->id, 'side', '' ); ?>
207 <div id='postbox-container-3' class='postbox-container'>
208 <?php do_meta_boxes( $screen->id, 'column3', '' ); ?>
210 <div id='postbox-container-4' class='postbox-container'>
211 <?php do_meta_boxes( $screen->id, 'column4', '' ); ?>
216 wp_nonce_field( 'closedpostboxes', 'closedpostboxesnonce', false );
217 wp_nonce_field( 'meta-box-order', 'meta-box-order-nonce', false );
221 /* Dashboard Widgets */
223 function wp_dashboard_right_now() {
224 global $wp_registered_sidebars;
226 $num_posts = wp_count_posts( 'post' );
227 $num_pages = wp_count_posts( 'page' );
229 $num_cats = wp_count_terms('category');
231 $num_tags = wp_count_terms('post_tag');
233 $num_comm = wp_count_comments( );
235 echo "\n\t".'<div class="table table_content">';
236 echo "\n\t".'<p class="sub">' . __('Content') . '</p>'."\n\t".'<table>';
237 echo "\n\t".'<tr class="first">';
240 $num = number_format_i18n( $num_posts->publish );
241 $text = _n( 'Post', 'Posts', intval($num_posts->publish) );
242 if ( current_user_can( 'edit_posts' ) ) {
243 $num = "<a href='edit.php'>$num</a>";
244 $text = "<a href='edit.php'>$text</a>";
246 echo '<td class="first b b-posts">' . $num . '</td>';
247 echo '<td class="t posts">' . $text . '</td>';
250 /* TODO: Show status breakdown on hover
251 if ( $can_edit_pages && !empty($num_pages->publish) ) { // how many pages is not exposed in feeds. Don't show if !current_user_can
252 $post_type_texts[] = '<a href="edit-pages.php">'.sprintf( _n( '%s page', '%s pages', $num_pages->publish ), number_format_i18n( $num_pages->publish ) ).'</a>';
254 if ( $can_edit_posts && !empty($num_posts->draft) ) {
255 $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>';
257 if ( $can_edit_posts && !empty($num_posts->future) ) {
258 $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>';
260 if ( current_user_can('publish_posts') && !empty($num_posts->pending) ) {
261 $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 ) );
268 $num = number_format_i18n( $num_pages->publish );
269 $text = _n( 'Page', 'Pages', $num_pages->publish );
270 if ( current_user_can( 'edit_pages' ) ) {
271 $num = "<a href='edit.php?post_type=page'>$num</a>";
272 $text = "<a href='edit.php?post_type=page'>$text</a>";
274 echo '<td class="first b b_pages">' . $num . '</td>';
275 echo '<td class="t pages">' . $text . '</td>';
280 $num = number_format_i18n( $num_cats );
281 $text = _n( 'Category', 'Categories', $num_cats );
282 if ( current_user_can( 'manage_categories' ) ) {
283 $num = "<a href='edit-tags.php?taxonomy=category'>$num</a>";
284 $text = "<a href='edit-tags.php?taxonomy=category'>$text</a>";
286 echo '<td class="first b b-cats">' . $num . '</td>';
287 echo '<td class="t cats">' . $text . '</td>';
292 $num = number_format_i18n( $num_tags );
293 $text = _n( 'Tag', 'Tags', $num_tags );
294 if ( current_user_can( 'manage_categories' ) ) {
295 $num = "<a href='edit-tags.php'>$num</a>";
296 $text = "<a href='edit-tags.php'>$text</a>";
298 echo '<td class="first b b-tags">' . $num . '</td>';
299 echo '<td class="t tags">' . $text . '</td>';
302 do_action('right_now_content_table_end');
303 echo "\n\t</table>\n\t</div>";
305 echo "\n\t".'<div class="table table_discussion">';
306 echo "\n\t".'<p class="sub">' . __('Discussion') . '</p>'."\n\t".'<table>';
307 echo "\n\t".'<tr class="first">';
310 $num = '<span class="total-count">' . number_format_i18n($num_comm->total_comments) . '</span>';
311 $text = _n( 'Comment', 'Comments', $num_comm->total_comments );
312 if ( current_user_can( 'moderate_comments' ) ) {
313 $num = '<a href="edit-comments.php">' . $num . '</a>';
314 $text = '<a href="edit-comments.php">' . $text . '</a>';
316 echo '<td class="b b-comments">' . $num . '</td>';
317 echo '<td class="last t comments">' . $text . '</td>';
322 $num = '<span class="approved-count">' . number_format_i18n($num_comm->approved) . '</span>';
323 $text = _nx( 'Approved', 'Approved', $num_comm->approved, 'Right Now' );
324 if ( current_user_can( 'moderate_comments' ) ) {
325 $num = "<a href='edit-comments.php?comment_status=approved'>$num</a>";
326 $text = "<a class='approved' href='edit-comments.php?comment_status=approved'>$text</a>";
328 echo '<td class="b b_approved">' . $num . '</td>';
329 echo '<td class="last t">' . $text . '</td>';
331 echo "</tr>\n\t<tr>";
334 $num = '<span class="pending-count">' . number_format_i18n($num_comm->moderated) . '</span>';
335 $text = _n( 'Pending', 'Pending', $num_comm->moderated );
336 if ( current_user_can( 'moderate_comments' ) ) {
337 $num = "<a href='edit-comments.php?comment_status=moderated'>$num</a>";
338 $text = "<a class='waiting' href='edit-comments.php?comment_status=moderated'>$text</a>";
340 echo '<td class="b b-waiting">' . $num . '</td>';
341 echo '<td class="last t">' . $text . '</td>';
343 echo "</tr>\n\t<tr>";
346 $num = number_format_i18n($num_comm->spam);
347 $text = _nx( 'Spam', 'Spam', $num_comm->spam, 'comment' );
348 if ( current_user_can( 'moderate_comments' ) ) {
349 $num = "<a href='edit-comments.php?comment_status=spam'><span class='spam-count'>$num</span></a>";
350 $text = "<a class='spam' href='edit-comments.php?comment_status=spam'>$text</a>";
352 echo '<td class="b b-spam">' . $num . '</td>';
353 echo '<td class="last t">' . $text . '</td>';
356 do_action('right_now_table_end');
357 do_action('right_now_discussion_table_end');
358 echo "\n\t</table>\n\t</div>";
360 echo "\n\t".'<div class="versions">';
361 $theme = wp_get_theme();
365 if ( $theme->errors() ) {
366 if ( ! is_multisite() || is_super_admin() )
367 echo '<span class="error-message">' . __('ERROR: The themes directory is either empty or doesn’t exist. Please check your installation.') . '</span>';
368 } elseif ( ! empty($wp_registered_sidebars) ) {
369 $sidebars_widgets = wp_get_sidebars_widgets();
371 foreach ( (array) $sidebars_widgets as $k => $v ) {
372 if ( 'wp_inactive_widgets' == $k || 'orphaned_widgets' == substr( $k, 0, 16 ) )
375 $num_widgets = $num_widgets + count($v);
377 $num = number_format_i18n( $num_widgets );
379 $switch_themes = $theme->display('Name');
380 if ( current_user_can( 'switch_themes') )
381 $switch_themes = '<a href="themes.php">' . $switch_themes . '</a>';
382 if ( current_user_can( 'edit_theme_options' ) ) {
383 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);
385 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);
388 if ( current_user_can( 'switch_themes' ) )
389 printf( __('Theme <span class="b"><a href="themes.php">%1$s</a></span>'), $theme->display('Name') );
391 printf( __('Theme <span class="b">%1$s</span>'), $theme->display('Name') );
395 // Check if search engines are blocked.
396 if ( !is_network_admin() && !is_user_admin() && current_user_can('manage_options') && '1' != get_option('blog_public') ) {
397 $title = apply_filters('privacy_on_link_title', __('Your site is asking search engines not to index its content') );
398 $content = apply_filters('privacy_on_link_text', __('Search Engines Blocked') );
400 echo "<p><a href='options-privacy.php' title='$title'>$content</a></p>";
403 update_right_now_message();
405 echo "\n\t".'<br class="clear" /></div>';
406 do_action( 'rightnow_end' );
407 do_action( 'activity_box_end' );
410 function wp_network_dashboard_right_now() {
412 if ( current_user_can('create_sites') )
413 $actions['create-site'] = '<a href="' . network_admin_url('site-new.php') . '">' . __( 'Create a New Site' ) . '</a>';
414 if ( current_user_can('create_users') )
415 $actions['create-user'] = '<a href="' . network_admin_url('user-new.php') . '">' . __( 'Create a New User' ) . '</a>';
417 $c_users = get_user_count();
418 $c_blogs = get_blog_count();
420 $user_text = sprintf( _n( '%s user', '%s users', $c_users ), number_format_i18n( $c_users ) );
421 $blog_text = sprintf( _n( '%s site', '%s sites', $c_blogs ), number_format_i18n( $c_blogs ) );
423 $sentence = sprintf( __( 'You have %1$s and %2$s.' ), $blog_text, $user_text );
426 echo '<ul class="subsubsub">';
427 foreach ( $actions as $class => $action ) {
428 $actions[ $class ] = "\t<li class='$class'>$action";
430 echo implode( " |</li>\n", $actions ) . "</li>\n";
436 <p class="youhave"><?php echo $sentence; ?></p>
437 <?php do_action( 'wpmuadminresult', '' ); ?>
439 <form action="<?php echo network_admin_url('users.php'); ?>" method="get">
441 <input type="search" name="s" value="" size="30" autocomplete="off" />
442 <?php submit_button( __( 'Search Users' ), 'button', 'submit', false, array( 'id' => 'submit_users' ) ); ?>
446 <form action="<?php echo network_admin_url('sites.php'); ?>" method="get">
448 <input type="search" name="s" value="" size="30" autocomplete="off" />
449 <?php submit_button( __( 'Search Sites' ), 'button', 'submit', false, array( 'id' => 'submit_sites' ) ); ?>
453 do_action( 'mu_rightnow_end' );
454 do_action( 'mu_activity_box_end' );
457 function wp_dashboard_quick_press() {
461 if ( 'post' === strtolower( $_SERVER['REQUEST_METHOD'] ) && isset( $_POST['action'] ) && 0 === strpos( $_POST['action'], 'post-quickpress' ) && (int) $_POST['post_ID'] ) {
462 $view = get_permalink( $_POST['post_ID'] );
463 $edit = esc_url( get_edit_post_link( $_POST['post_ID'] ) );
464 if ( 'post-quickpress-publish' == $_POST['action'] ) {
465 if ( current_user_can('publish_posts') )
466 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 );
468 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 );
470 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 );
471 $drafts_query = new WP_Query( array(
472 'post_type' => 'post',
473 'post_status' => 'draft',
474 'author' => $GLOBALS['current_user']->ID,
475 'posts_per_page' => 1,
476 'orderby' => 'modified',
480 if ( $drafts_query->posts )
481 $drafts =& $drafts_query->posts;
483 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>' );
484 $_REQUEST = array(); // hack for get_default_post_to_edit()
487 /* Check if a new auto-draft (= no new post_ID) is needed or if the old can be used */
488 $last_post_id = (int) get_user_option( 'dashboard_quick_press_last_post_id' ); // Get the last post_ID
489 if ( $last_post_id ) {
490 $post = get_post( $last_post_id );
491 if ( empty( $post ) || $post->post_status != 'auto-draft' ) { // auto-draft doesn't exists anymore
492 $post = get_default_post_to_edit('post', true);
493 update_user_option( (int) $GLOBALS['current_user']->ID, 'dashboard_quick_press_last_post_id', (int) $post->ID ); // Save post_ID
495 $post->post_title = ''; // Remove the auto draft title
498 $post = get_default_post_to_edit('post', true);
499 update_user_option( (int) $GLOBALS['current_user']->ID, 'dashboard_quick_press_last_post_id', (int) $post->ID ); // Save post_ID
502 $post_ID = (int) $post->ID;
505 <form name="post" action="<?php echo esc_url( admin_url( 'post.php' ) ); ?>" method="post" id="quick-press">
506 <h4 id="quick-post-title"><label for="title"><?php _e('Title') ?></label></h4>
507 <div class="input-text-wrap">
508 <input type="text" name="post_title" id="title" tabindex="1" autocomplete="off" value="<?php echo esc_attr( $post->post_title ); ?>" />
511 <?php if ( current_user_can( 'upload_files' ) ) : ?>
512 <div id="wp-content-wrap" class="wp-editor-wrap hide-if-no-js wp-media-buttons">
513 <?php do_action( 'media_buttons', 'content' ); ?>
517 <h4 id="content-label"><label for="content"><?php _e('Content') ?></label></h4>
518 <div class="textarea-wrap">
519 <textarea name="content" id="content" class="mceEditor" rows="3" cols="15" tabindex="2"><?php echo esc_textarea( $post->post_content ); ?></textarea>
522 <script type="text/javascript">edCanvas = document.getElementById('content');edInsertContent = null;</script>
524 <h4><label for="tags-input"><?php _e('Tags') ?></label></h4>
525 <div class="input-text-wrap">
526 <input type="text" name="tags_input" id="tags-input" tabindex="3" value="<?php echo get_tags_to_edit( $post->ID ); ?>" />
530 <input type="hidden" name="action" id="quickpost-action" value="post-quickpress-save" />
531 <input type="hidden" name="post_ID" value="<?php echo $post_ID; ?>" />
532 <input type="hidden" name="post_type" value="post" />
533 <?php wp_nonce_field('add-post'); ?>
534 <?php submit_button( __( 'Save Draft' ), 'button', 'save', false, array( 'id' => 'save-post', 'tabindex'=> 4 ) ); ?>
535 <input type="reset" value="<?php esc_attr_e( 'Reset' ); ?>" class="button" />
536 <span id="publishing-action">
537 <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'); ?>" />
538 <img class="waiting" src="<?php echo esc_url( admin_url( 'images/wpspin_light.gif' ) ); ?>" alt="" />
547 wp_dashboard_recent_drafts( $drafts );
550 function wp_dashboard_recent_drafts( $drafts = false ) {
552 $drafts_query = new WP_Query( array(
553 'post_type' => 'post',
554 'post_status' => 'draft',
555 'author' => $GLOBALS['current_user']->ID,
556 'posts_per_page' => 5,
557 'orderby' => 'modified',
560 $drafts =& $drafts_query->posts;
563 if ( $drafts && is_array( $drafts ) ) {
565 foreach ( $drafts as $draft ) {
566 $url = get_edit_post_link( $draft->ID );
567 $title = _draft_or_post_title( $draft->ID );
568 $item = "<h4><a href='$url' title='" . sprintf( __( 'Edit “%s”' ), 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>';
569 if ( $the_content = preg_split( '#\s#', strip_tags( $draft->post_content ), 11, PREG_SPLIT_NO_EMPTY ) )
570 $item .= '<p>' . join( ' ', array_slice( $the_content, 0, 10 ) ) . ( 10 < count( $the_content ) ? '…' : '' ) . '</p>';
575 <li><?php echo join( "</li>\n<li>", $list ); ?></li>
577 <p class="textright"><a href="edit.php?post_status=draft" ><?php _e('View all'); ?></a></p>
580 _e('There are no drafts at the moment');
585 * Display recent comments dashboard widget content.
589 function wp_dashboard_recent_comments() {
592 // Select all comment types and filter out spam later for better query performance.
596 $widgets = get_option( 'dashboard_widget_options' );
597 $total_items = isset( $widgets['dashboard_recent_comments'] ) && isset( $widgets['dashboard_recent_comments']['items'] )
598 ? absint( $widgets['dashboard_recent_comments']['items'] ) : 5;
600 $comments_query = array( 'number' => $total_items * 5, 'offset' => 0 );
601 if ( ! current_user_can( 'edit_posts' ) )
602 $comments_query['status'] = 'approve';
604 while ( count( $comments ) < $total_items && $possible = get_comments( $comments_query ) ) {
605 foreach ( $possible as $comment ) {
606 if ( ! current_user_can( 'read_post', $comment->comment_post_ID ) )
608 $comments[] = $comment;
609 if ( count( $comments ) == $total_items )
612 $comments_query['offset'] += $comments_query['number'];
613 $comments_query['number'] = $total_items * 10;
617 echo '<div id="the-comment-list" class="list:comment">';
618 foreach ( $comments as $comment )
619 _wp_dashboard_recent_comments_row( $comment );
622 if ( current_user_can('edit_posts') )
623 _get_list_table('WP_Comments_List_Table')->views();
625 wp_comment_reply( -1, false, 'dashboard', false );
626 wp_comment_trashnotice();
628 echo '<p>' . __( 'No comments yet.' ) . '</p>';
632 function _wp_dashboard_recent_comments_row( &$comment, $show_date = true ) {
633 $GLOBALS['comment'] =& $comment;
635 $comment_post_url = get_edit_post_link( $comment->comment_post_ID );
636 $comment_post_title = strip_tags(get_the_title( $comment->comment_post_ID ));
637 $comment_post_link = "<a href='$comment_post_url'>$comment_post_title</a>";
638 $comment_link = '<a class="comment-link" href="' . esc_url(get_comment_link()) . '">#</a>';
640 $actions_string = '';
641 if ( current_user_can( 'edit_comment', $comment->comment_ID ) ) {
642 // preorder it: Approve | Reply | Edit | Spam | Trash
644 'approve' => '', 'unapprove' => '',
648 'trash' => '', 'delete' => ''
651 $del_nonce = esc_html( '_wpnonce=' . wp_create_nonce( "delete-comment_$comment->comment_ID" ) );
652 $approve_nonce = esc_html( '_wpnonce=' . wp_create_nonce( "approve-comment_$comment->comment_ID" ) );
654 $approve_url = esc_url( "comment.php?action=approvecomment&p=$comment->comment_post_ID&c=$comment->comment_ID&$approve_nonce" );
655 $unapprove_url = esc_url( "comment.php?action=unapprovecomment&p=$comment->comment_post_ID&c=$comment->comment_ID&$approve_nonce" );
656 $spam_url = esc_url( "comment.php?action=spamcomment&p=$comment->comment_post_ID&c=$comment->comment_ID&$del_nonce" );
657 $trash_url = esc_url( "comment.php?action=trashcomment&p=$comment->comment_post_ID&c=$comment->comment_ID&$del_nonce" );
658 $delete_url = esc_url( "comment.php?action=deletecomment&p=$comment->comment_post_ID&c=$comment->comment_ID&$del_nonce" );
660 $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>';
661 $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>';
662 $actions['edit'] = "<a href='comment.php?action=editcomment&c={$comment->comment_ID}' title='" . esc_attr__('Edit comment') . "'>". __('Edit') . '</a>';
663 $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>';
664 $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>';
665 if ( !EMPTY_TRASH_DAYS )
666 $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>';
668 $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>';
670 $actions = apply_filters( 'comment_row_actions', array_filter($actions), $comment );
673 foreach ( $actions as $action => $link ) {
675 ( ( ('approve' == $action || 'unapprove' == $action) && 2 === $i ) || 1 === $i ) ? $sep = '' : $sep = ' | ';
677 // Reply and quickedit need a hide-if-no-js span
678 if ( 'reply' == $action || 'quickedit' == $action )
679 $action .= ' hide-if-no-js';
681 $actions_string .= "<span class='$action'>$sep$link</span>";
687 <div id="comment-<?php echo $comment->comment_ID; ?>" <?php comment_class( array( 'comment-item', wp_get_comment_status($comment->comment_ID) ) ); ?>>
688 <?php if ( !$comment->comment_type || 'comment' == $comment->comment_type ) : ?>
690 <?php echo get_avatar( $comment, 50 ); ?>
692 <div class="dashboard-comment-wrap">
693 <h4 class="comment-meta">
694 <?php printf( /* translators: 1: comment author, 2: post link, 3: notification if the comment is pending */__( 'From %1$s on %2$s%3$s' ),
695 '<cite class="comment-author">' . get_comment_author_link() . '</cite>', $comment_post_link.' '.$comment_link, ' <span class="approve">' . __( '[Pending]' ) . '</span>' ); ?>
700 switch ( $comment->comment_type ) :
702 $type = __( 'Pingback' );
705 $type = __( 'Trackback' );
708 $type = ucwords( $comment->comment_type );
710 $type = esc_html( $type );
712 <div class="dashboard-comment-wrap">
713 <?php /* translators: %1$s is type of comment, %2$s is link to the post */ ?>
714 <h4 class="comment-meta"><?php printf( _x( '%1$s on %2$s', 'dashboard' ), "<strong>$type</strong>", $comment_post_link." ".$comment_link ); ?></h4>
715 <p class="comment-author"><?php comment_author_link(); ?></p>
717 <?php endif; // comment_type ?>
718 <blockquote><p><?php comment_excerpt(); ?></p></blockquote>
719 <p class="row-actions"><?php echo $actions_string; ?></p>
726 * The recent comments dashboard widget control.
730 function wp_dashboard_recent_comments_control() {
731 if ( !$widget_options = get_option( 'dashboard_widget_options' ) )
732 $widget_options = array();
734 if ( !isset($widget_options['dashboard_recent_comments']) )
735 $widget_options['dashboard_recent_comments'] = array();
737 if ( 'POST' == $_SERVER['REQUEST_METHOD'] && isset($_POST['widget-recent-comments']) ) {
738 $number = absint( $_POST['widget-recent-comments']['items'] );
739 $widget_options['dashboard_recent_comments']['items'] = $number;
740 update_option( 'dashboard_widget_options', $widget_options );
743 $number = isset( $widget_options['dashboard_recent_comments']['items'] ) ? (int) $widget_options['dashboard_recent_comments']['items'] : '';
745 echo '<p><label for="comments-number">' . __('Number of comments to show:') . '</label>';
746 echo '<input id="comments-number" name="widget-recent-comments[items]" type="text" value="' . $number . '" size="3" /></p>';
749 function wp_dashboard_incoming_links() {
750 wp_dashboard_cached_rss_widget( 'dashboard_incoming_links', 'wp_dashboard_incoming_links_output' );
754 * Display incoming links dashboard widget content.
758 function wp_dashboard_incoming_links_output() {
759 $widgets = get_option( 'dashboard_widget_options' );
760 @extract( @$widgets['dashboard_incoming_links'], EXTR_SKIP );
761 $rss = fetch_feed( $url );
763 if ( is_wp_error($rss) ) {
764 if ( is_admin() || current_user_can('manage_options') ) {
766 printf(__('<strong>RSS Error</strong>: %s'), $rss->get_error_message());
772 if ( !$rss->get_item_quantity() ) {
773 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… yet. It’s okay — there is no rush.') . "</p>\n";
781 if ( !isset($items) )
784 foreach ( $rss->get_items(0, $items) as $item ) {
790 $link = esc_url( strip_tags( $item->get_link() ) );
792 $author = $item->get_author();
794 $site_link = esc_url( strip_tags( $author->get_link() ) );
796 if ( !$publisher = esc_html( strip_tags( $author->get_name() ) ) )
797 $publisher = __( 'Somebody' );
799 $publisher = __( 'Somebody' );
802 $publisher = "<a href='$site_link'>$publisher</a>";
804 $publisher = "<strong>$publisher</strong>";
806 $content = $item->get_content();
807 $content = wp_html_excerpt($content, 50) . ' ...';
810 /* translators: incoming links feed, %1$s is other person, %3$s is content */
811 $text = __( '%1$s linked here <a href="%2$s">saying</a>, "%3$s"' );
813 /* translators: incoming links feed, %1$s is other person, %3$s is content */
814 $text = __( '%1$s linked here saying, "%3$s"' );
816 if ( !empty($show_date) ) {
817 if ( !empty($show_author) || !empty($show_summary) )
818 /* translators: incoming links feed, %4$s is the date */
819 $text .= ' ' . __( 'on %4$s' );
820 $date = esc_html( strip_tags( $item->get_date() ) );
821 $date = strtotime( $date );
822 $date = gmdate( get_option( 'date_format' ), $date );
825 echo "\t<li>" . sprintf( $text, $publisher, $link, $content, $date ) . "</li>\n";
833 function wp_dashboard_incoming_links_control() {
834 wp_dashboard_rss_control( 'dashboard_incoming_links', array( 'title' => false, 'show_summary' => false, 'show_author' => false ) );
837 function wp_dashboard_primary() {
838 wp_dashboard_cached_rss_widget( 'dashboard_primary', 'wp_dashboard_rss_output' );
841 function wp_dashboard_primary_control() {
842 wp_dashboard_rss_control( 'dashboard_primary' );
846 * {@internal Missing Short Description}}
850 * @param string $widget_id
852 function wp_dashboard_rss_output( $widget_id ) {
853 $widgets = get_option( 'dashboard_widget_options' );
854 echo '<div class="rss-widget">';
855 wp_widget_rss_output( $widgets[$widget_id] );
859 function wp_dashboard_secondary() {
860 wp_dashboard_cached_rss_widget( 'dashboard_secondary', 'wp_dashboard_secondary_output' );
863 function wp_dashboard_secondary_control() {
864 wp_dashboard_rss_control( 'dashboard_secondary' );
868 * Display secondary dashboard RSS widget feed.
874 function wp_dashboard_secondary_output() {
875 $widgets = get_option( 'dashboard_widget_options' );
876 @extract( @$widgets['dashboard_secondary'], EXTR_SKIP );
877 $rss = @fetch_feed( $url );
879 if ( is_wp_error($rss) ) {
880 if ( is_admin() || current_user_can('manage_options') ) {
881 echo '<div class="rss-widget"><p>';
882 printf(__('<strong>RSS Error</strong>: %s'), $rss->get_error_message());
885 } elseif ( !$rss->get_item_quantity() ) {
890 echo '<div class="rss-widget">';
891 wp_widget_rss_output( $rss, $widgets['dashboard_secondary'] );
898 function wp_dashboard_plugins() {
899 wp_dashboard_cached_rss_widget( 'dashboard_plugins', 'wp_dashboard_plugins_output', array(
900 'http://wordpress.org/extend/plugins/rss/browse/popular/',
901 'http://wordpress.org/extend/plugins/rss/browse/new/'
906 * Display plugins most popular, newest plugins, and recently updated widget text.
910 function wp_dashboard_plugins_output() {
911 $popular = fetch_feed( 'http://wordpress.org/extend/plugins/rss/browse/popular/' );
912 $new = fetch_feed( 'http://wordpress.org/extend/plugins/rss/browse/new/' );
914 if ( false === $plugin_slugs = get_transient( 'plugin_slugs' ) ) {
915 $plugin_slugs = array_keys( get_plugins() );
916 set_transient( 'plugin_slugs', $plugin_slugs, 86400 );
919 foreach ( array( 'popular' => __('Most Popular'), 'new' => __('Newest Plugins') ) as $feed => $label ) {
920 if ( is_wp_error($$feed) || !$$feed->get_item_quantity() )
923 $items = $$feed->get_items(0, 5);
925 // Pick a random, non-installed plugin
927 // Abort this foreach loop iteration if there's no plugins left of this type
928 if ( 0 == count($items) )
931 $item_key = array_rand($items);
932 $item = $items[$item_key];
934 list($link, $frag) = explode( '#', $item->get_link() );
936 $link = esc_url($link);
937 if ( preg_match( '|/([^/]+?)/?$|', $link, $matches ) )
940 unset( $items[$item_key] );
944 // Is this random plugin's slug already installed? If so, try again.
945 reset( $plugin_slugs );
946 foreach ( $plugin_slugs as $plugin_slug ) {
947 if ( $slug == substr( $plugin_slug, 0, strlen( $slug ) ) ) {
948 unset( $items[$item_key] );
953 // If we get to this point, then the random plugin isn't installed and we can stop the while().
957 // Eliminate some common badly formed plugin descriptions
958 while ( ( null !== $item_key = array_rand($items) ) && false !== strpos( $items[$item_key]->get_description(), 'Plugin Name:' ) )
959 unset($items[$item_key]);
961 if ( !isset($items[$item_key]) )
964 // current bbPress feed item titles are: user on "topic title"
965 if ( preg_match( '/"(.*)"/s', $item->get_title(), $matches ) )
966 $title = $matches[1];
967 else // but let's make it forward compatible if things change
968 $title = $item->get_title();
969 $title = esc_html( $title );
971 $description = esc_html( strip_tags(@html_entity_decode($item->get_description(), ENT_QUOTES, get_option('blog_charset'))) );
973 $ilink = wp_nonce_url('plugin-install.php?tab=plugin-information&plugin=' . $slug, 'install-plugin_' . $slug) .
974 '&TB_iframe=true&width=600&height=800';
976 echo "<h4>$label</h4>\n";
977 echo "<h5><a href='$link'>$title</a></h5> <span>(<a href='$ilink' class='thickbox' title='$title'>" . __( 'Install' ) . "</a>)</span>\n";
978 echo "<p>$description</p>\n";
980 $$feed->__destruct();
986 * Checks to see if all of the feed url in $check_urls are cached.
988 * If $check_urls is empty, look for the rss feed url found in the dashboard
989 * widget options of $widget_id. If cached, call $callback, a function that
990 * echoes out output for this widget. If not cache, echo a "Loading..." stub
991 * which is later replaced by AJAX call (see top of /wp-admin/index.php)
995 * @param string $widget_id
996 * @param callback $callback
997 * @param array $check_urls RSS feeds
998 * @return bool False on failure. True on success.
1000 function wp_dashboard_cached_rss_widget( $widget_id, $callback, $check_urls = array() ) {
1001 $loading = '<p class="widget-loading hide-if-no-js">' . __( 'Loading…' ) . '</p><p class="hide-if-js">' . __( 'This widget requires JavaScript.' ) . '</p>';
1002 $doing_ajax = ( defined('DOING_AJAX') && DOING_AJAX );
1004 if ( empty($check_urls) ) {
1005 $widgets = get_option( 'dashboard_widget_options' );
1006 if ( empty($widgets[$widget_id]['url']) && ! $doing_ajax ) {
1010 $check_urls = array( $widgets[$widget_id]['url'] );
1013 $cache_key = 'dash_' . md5( $widget_id );
1014 if ( false !== ( $output = get_transient( $cache_key ) ) ) {
1019 if ( ! $doing_ajax ) {
1024 if ( $callback && is_callable( $callback ) ) {
1025 $args = array_slice( func_get_args(), 2 );
1026 array_unshift( $args, $widget_id );
1028 call_user_func_array( $callback, $args );
1029 set_transient( $cache_key, ob_get_flush(), 43200); // Default lifetime in cache of 12 hours (same as the feeds)
1035 /* Dashboard Widgets Controls */
1037 // Calls widget_control callback
1039 * Calls widget control callback.
1043 * @param int $widget_control_id Registered Widget ID.
1045 function wp_dashboard_trigger_widget_control( $widget_control_id = false ) {
1046 global $wp_dashboard_control_callbacks;
1048 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]) ) {
1049 call_user_func( $wp_dashboard_control_callbacks[$widget_control_id], '', array( 'id' => $widget_control_id, 'callback' => $wp_dashboard_control_callbacks[$widget_control_id] ) );
1054 * The RSS dashboard widget control.
1056 * Sets up $args to be used as input to wp_widget_rss_form(). Handles POST data
1057 * from RSS-type widgets.
1061 * @param string $widget_id
1062 * @param array $form_inputs
1064 function wp_dashboard_rss_control( $widget_id, $form_inputs = array() ) {
1065 if ( !$widget_options = get_option( 'dashboard_widget_options' ) )
1066 $widget_options = array();
1068 if ( !isset($widget_options[$widget_id]) )
1069 $widget_options[$widget_id] = array();
1071 $number = 1; // Hack to use wp_widget_rss_form()
1072 $widget_options[$widget_id]['number'] = $number;
1074 if ( 'POST' == $_SERVER['REQUEST_METHOD'] && isset($_POST['widget-rss'][$number]) ) {
1075 $_POST['widget-rss'][$number] = stripslashes_deep( $_POST['widget-rss'][$number] );
1076 $widget_options[$widget_id] = wp_widget_rss_process( $_POST['widget-rss'][$number] );
1077 // title is optional. If black, fill it if possible
1078 if ( !$widget_options[$widget_id]['title'] && isset($_POST['widget-rss'][$number]['title']) ) {
1079 $rss = fetch_feed($widget_options[$widget_id]['url']);
1080 if ( is_wp_error($rss) ) {
1081 $widget_options[$widget_id]['title'] = htmlentities(__('Unknown Feed'));
1083 $widget_options[$widget_id]['title'] = htmlentities(strip_tags($rss->get_title()));
1088 update_option( 'dashboard_widget_options', $widget_options );
1089 $cache_key = 'dash_' . md5( $widget_id );
1090 delete_transient( $cache_key );
1093 wp_widget_rss_form( $widget_options[$widget_id], $form_inputs );
1096 // Display File upload quota on dashboard
1097 function wp_dashboard_quota() {
1098 if ( !is_multisite() || !current_user_can('upload_files') || get_site_option( 'upload_space_check_disabled' ) )
1101 $quota = get_space_allowed();
1102 $used = get_dirsize( BLOGUPLOADDIR ) / 1024 / 1024;
1104 if ( $used > $quota )
1105 $percentused = '100';
1107 $percentused = ( $used / $quota ) * 100;
1108 $used_color = ( $percentused >= 70 ) ? ' spam' : '';
1109 $used = round( $used, 2 );
1110 $percentused = number_format( $percentused );
1113 <p class="sub musub"><?php _e( 'Storage Space' ); ?></p>
1114 <div class="table table_content musubtable">
1117 <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>
1118 <td class="t posts"><?php _e( 'Space Allowed' ); ?></td>
1122 <div class="table table_discussion musubtable">
1125 <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>
1126 <td class="last t comments<?php echo $used_color;?>"><?php _e( 'Space Used' );?></td>
1130 <br class="clear" />
1133 add_action( 'activity_box_end', 'wp_dashboard_quota' );
1135 // Display Browser Nag Meta Box
1136 function wp_dashboard_browser_nag() {
1138 $response = wp_check_browser_version();
1141 if ( $response['insecure'] ) {
1142 $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'] ) );
1144 $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'] ) );
1147 $browser_nag_class = '';
1148 if ( !empty( $response['img_src'] ) ) {
1149 $img_src = ( is_ssl() && ! empty( $response['img_src_ssl'] ) )? $response['img_src_ssl'] : $response['img_src'];
1151 $notice .= '<div class="alignright browser-icon"><a href="' . esc_attr($response['update_url']) . '"><img src="' . esc_attr( $img_src ) . '" alt="" /></a></div>';
1152 $browser_nag_class = ' has-browser-icon';
1154 $notice .= "<p class='browser-update-nag{$browser_nag_class}'>{$msg}</p>";
1156 $browsehappy = 'http://browsehappy.com/';
1157 $locale = get_locale();
1158 if ( 'en_US' !== $locale )
1159 $browsehappy = add_query_arg( 'locale', $locale, $browsehappy );
1161 $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'] ), esc_url( $browsehappy ) ) . '</p>';
1162 $notice .= '<p class="hide-if-no-js"><a href="" class="dismiss">' . __( 'Dismiss' ) . '</a></p>';
1163 $notice .= '<div class="clear"></div>';
1166 echo apply_filters( 'browse-happy-notice', $notice, $response );
1169 function dashboard_browser_nag_class( $classes ) {
1170 $response = wp_check_browser_version();
1172 if ( $response && $response['insecure'] )
1173 $classes[] = 'browser-insecure';
1179 * Check if the user needs a browser update
1183 * @return array|bool False on failure, array of browser data on success.
1185 function wp_check_browser_version() {
1186 if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
1189 $key = md5( $_SERVER['HTTP_USER_AGENT'] );
1191 if ( false === ($response = get_site_transient('browser_' . $key) ) ) {
1195 'body' => array( 'useragent' => $_SERVER['HTTP_USER_AGENT'] ),
1196 'user-agent' => 'WordPress/' . $wp_version . '; ' . home_url()
1199 $response = wp_remote_post( 'http://api.wordpress.org/core/browse-happy/1.0/', $options );
1201 if ( is_wp_error( $response ) || 200 != wp_remote_retrieve_response_code( $response ) )
1205 * Response should be an array with:
1206 * 'name' - string - A user friendly browser name
1207 * 'version' - string - The most recent version of the browser
1208 * 'current_version' - string - The version of the browser the user is using
1209 * 'upgrade' - boolean - Whether the browser needs an upgrade
1210 * 'insecure' - boolean - Whether the browser is deemed insecure
1211 * 'upgrade_url' - string - The url to visit to upgrade
1212 * 'img_src' - string - An image representing the browser
1213 * 'img_src_ssl' - string - An image (over SSL) representing the browser
1215 $response = maybe_unserialize( wp_remote_retrieve_body( $response ) );
1217 if ( ! is_array( $response ) )
1220 set_site_transient( 'browser_' . $key, $response, 604800 ); // cache for 1 week
1227 * Empty function usable by plugins to output empty dashboard widget (to be populated later by JS).
1229 function wp_dashboard_empty() {}
1232 * Displays a welcome panel to introduce users to WordPress.
1236 function wp_welcome_panel() {
1239 if ( ! current_user_can( 'edit_theme_options' ) )
1242 $classes = 'welcome-panel';
1244 $option = get_user_meta( get_current_user_id(), 'show_welcome_panel', true );
1245 // 0 = hide, 1 = toggled to show or single site creator, 2 = multisite site owner
1246 $hide = 0 == $option || ( 2 == $option && wp_get_current_user()->user_email != get_option( 'admin_email' ) );
1248 $classes .= ' hidden';
1250 list( $display_version ) = explode( '-', $wp_version );
1252 <div id="welcome-panel" class="<?php echo esc_attr( $classes ); ?>">
1253 <?php wp_nonce_field( 'welcome-panel-nonce', 'welcomepanelnonce', false ); ?>
1254 <a class="welcome-panel-close" href="<?php echo esc_url( admin_url( '?welcome=0' ) ); ?>"><?php _e('Dismiss'); ?></a>
1255 <div class="wp-badge"><?php printf( __( 'Version %s' ), $display_version ); ?></div>
1257 <div class="welcome-panel-content">
1258 <h3><?php _e( 'Welcome to your new WordPress site!' ); ?></h3>
1259 <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’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>
1260 <div class="welcome-panel-column-container">
1261 <div class="welcome-panel-column">
1262 <h4><span class="icon16 icon-settings"></span> <?php _e( 'Basic Settings' ); ?></h4>
1263 <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>
1265 <li><?php echo sprintf( __( '<a href="%s">Choose your privacy setting</a>' ), esc_url( admin_url('options-privacy.php') ) ); ?></li>
1266 <li><?php echo sprintf( __( '<a href="%s">Select your tagline and time zone</a>' ), esc_url( admin_url('options-general.php') ) ); ?></li>
1267 <li><?php echo sprintf( __( '<a href="%s">Turn comments on or off</a>' ), esc_url( admin_url('options-discussion.php') ) ); ?></li>
1268 <li><?php echo sprintf( __( '<a href="%s">Fill in your profile</a>' ), esc_url( admin_url('profile.php') ) ); ?></li>
1271 <div class="welcome-panel-column">
1272 <h4><span class="icon16 icon-page"></span> <?php _e( 'Add Real Content' ); ?></h4>
1273 <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>
1275 <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>
1276 <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>
1277 <li><?php echo sprintf( __( '<a href="%s">Create an About Me page</a>' ), esc_url( admin_url('edit.php?post_type=page') ) ); ?></li>
1278 <li><?php echo sprintf( __( '<a href="%s">Write your first post</a>' ), esc_url( admin_url('post-new.php') ) ); ?></li>
1281 <div class="welcome-panel-column welcome-panel-last">
1282 <h4><span class="icon16 icon-appearance"></span> <?php _e( 'Customize Your Site' ); ?></h4>
1284 $theme = wp_get_theme();
1285 if ( $theme->errors() ) :
1287 printf( __( '<a href="%s">Install a theme</a> to get started customizing your site.' ), esc_url( admin_url( 'themes.php' ) ) );
1290 $customize_links = array();
1291 if ( 'twentyeleven' == $theme->get_stylesheet() )
1292 $customize_links[] = sprintf( __( '<a href="%s">Choose light or dark</a>' ), esc_url( admin_url( 'themes.php?page=theme_options' ) ) );
1294 if ( current_theme_supports( 'custom-background' ) )
1295 $customize_links[] = sprintf( __( '<a href="%s">Set a background color</a>' ), esc_url( admin_url( 'themes.php?page=custom-background' ) ) );
1297 if ( current_theme_supports( 'custom-header' ) )
1298 $customize_links[] = sprintf( __( '<a href="%s">Select a new header image</a>' ), esc_url( admin_url( 'themes.php?page=custom-header' ) ) );
1300 if ( current_theme_supports( 'widgets' ) )
1301 $customize_links[] = sprintf( __( '<a href="%s">Add some widgets</a>' ), esc_url( admin_url( 'widgets.php' ) ) );
1303 if ( ! empty( $customize_links ) ) {
1305 printf( __( 'Use the current theme — %1$s — or <a href="%2$s">choose a new one</a>. If you stick with %1$s, here are a few ways to make your site look unique.' ), $theme->display('Name'), esc_url( admin_url( 'themes.php' ) ) );
1309 <?php foreach ( $customize_links as $customize_link ) : ?>
1310 <li><?php echo $customize_link ?></li>
1311 <?php endforeach; ?>
1316 printf( __( 'Use the current theme — %1$s — or <a href="%2$s">choose a new one</a>.' ), $theme->display('Name'), esc_url( admin_url( 'themes.php' ) ) );
1322 <p class="welcome-panel-dismiss"><?php printf( __( 'Already know what you’re doing? <a href="%s">Dismiss this message</a>.' ), esc_url( admin_url( '?welcome=0' ) ) ); ?></p>