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 global $screen_layout_columns;
198 $screen = get_current_screen();
200 $hide2 = $hide3 = $hide4 = '';
201 switch ( $screen_layout_columns ) {
203 $width = 'width:25%;';
206 $width = 'width:33.333333%;';
207 $hide4 = 'display:none;';
210 $width = 'width:50%;';
211 $hide3 = $hide4 = 'display:none;';
214 $width = 'width:100%;';
215 $hide2 = $hide3 = $hide4 = 'display:none;';
218 <div id="dashboard-widgets" class="metabox-holder">
220 echo "\t<div id='postbox-container-1' class='postbox-container' style='$width'>\n";
221 do_meta_boxes( $screen->id, 'normal', '' );
223 echo "\t</div><div id='postbox-container-2' class='postbox-container' style='{$hide2}$width'>\n";
224 do_meta_boxes( $screen->id, 'side', '' );
226 echo "\t</div><div id='postbox-container-3' class='postbox-container' style='{$hide3}$width'>\n";
227 do_meta_boxes( $screen->id, 'column3', '' );
229 echo "\t</div><div id='postbox-container-4' class='postbox-container' style='{$hide4}$width'>\n";
230 do_meta_boxes( $screen->id, 'column4', '' );
234 <form style="display:none" method="get" action="">
237 wp_nonce_field( 'closedpostboxes', 'closedpostboxesnonce', false );
238 wp_nonce_field( 'meta-box-order', 'meta-box-order-nonce', false );
246 /* Dashboard Widgets */
248 function wp_dashboard_right_now() {
249 global $wp_registered_sidebars;
251 $num_posts = wp_count_posts( 'post' );
252 $num_pages = wp_count_posts( 'page' );
254 $num_cats = wp_count_terms('category');
256 $num_tags = wp_count_terms('post_tag');
258 $num_comm = wp_count_comments( );
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">';
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>";
271 echo '<td class="first b b-posts">' . $num . '</td>';
272 echo '<td class="t posts">' . $text . '</td>';
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>';
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>';
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>';
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 ) );
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>";
299 echo '<td class="first b b_pages">' . $num . '</td>';
300 echo '<td class="t pages">' . $text . '</td>';
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>";
311 echo '<td class="first b b-cats">' . $num . '</td>';
312 echo '<td class="t cats">' . $text . '</td>';
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>";
323 echo '<td class="first b b-tags">' . $num . '</td>';
324 echo '<td class="t tags">' . $text . '</td>';
327 do_action('right_now_content_table_end');
328 echo "\n\t</table>\n\t</div>";
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">';
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>';
342 echo '<td class="b b-comments">' . $num . '</td>';
343 echo '<td class="last t comments">' . $text . '</td>';
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>";
354 echo '<td class="b b_approved">' . $num . '</td>';
355 echo '<td class="last t">' . $text . '</td>';
357 echo "</tr>\n\t<tr>";
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>";
366 echo '<td class="b b-waiting">' . $num . '</td>';
367 echo '<td class="last t">' . $text . '</td>';
369 echo "</tr>\n\t<tr>";
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>";
378 echo '<td class="b b-spam">' . $num . '</td>';
379 echo '<td class="last t">' . $text . '</td>';
382 do_action('right_now_table_end');
383 do_action('right_now_discussion_table_end');
384 echo "\n\t</table>\n\t</div>";
386 echo "\n\t".'<div class="versions">';
387 $ct = current_theme_info();
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’t exist. Please check your installation.') . '</span>';
394 } elseif ( ! empty($wp_registered_sidebars) ) {
395 $sidebars_widgets = wp_get_sidebars_widgets();
397 foreach ( (array) $sidebars_widgets as $k => $v ) {
398 if ( 'wp_inactive_widgets' == $k || 'orphaned_widgets' == substr( $k, 0, 16 ) )
401 $num_widgets = $num_widgets + count($v);
403 $num = number_format_i18n( $num_widgets );
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);
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);
414 if ( current_user_can( 'switch_themes' ) )
415 printf( __('Theme <span class="b"><a href="themes.php">%1$s</a></span>'), $ct->title );
417 printf( __('Theme <span class="b">%1$s</span>'), $ct->title );
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') );
426 echo "<p><a href='options-privacy.php' title='$title'>$content</a></p>";
429 update_right_now_message();
431 echo "\n\t".'<br class="clear" /></div>';
432 do_action( 'rightnow_end' );
433 do_action( 'activity_box_end' );
436 function wp_network_dashboard_right_now() {
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>';
443 $c_users = get_user_count();
444 $c_blogs = get_blog_count();
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 ) );
449 $sentence = sprintf( __( 'You have %1$s and %2$s.' ), $blog_text, $user_text );
452 echo '<ul class="subsubsub">';
453 foreach ( $actions as $class => $action ) {
454 $actions[ $class ] = "\t<li class='$class'>$action";
456 echo implode( " |</li>\n", $actions ) . "</li>\n";
462 <p class="youhave"><?php echo $sentence; ?></p>
463 <?php do_action( 'wpmuadminresult', '' ); ?>
465 <form name="searchform" action="<?php echo network_admin_url('users.php'); ?>" method="get">
467 <input type="text" name="s" value="" size="17" />
468 <?php submit_button( __( 'Search Users' ), 'button', 'submit', false, array( 'id' => 'submit_users' ) ); ?>
472 <form name="searchform" action="<?php echo network_admin_url('sites.php'); ?>" method="get">
474 <input type="text" name="s" value="" size="17" />
475 <?php submit_button( __( 'Search Sites' ), 'button', 'submit', false, array( 'id' => 'submit_sites' ) ); ?>
479 do_action( 'mu_rightnow_end' );
480 do_action( 'mu_activity_box_end' );
483 function wp_dashboard_quick_press() {
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 );
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 );
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',
506 if ( $drafts_query->posts )
507 $drafts =& $drafts_query->posts;
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()
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
521 $post->post_title = ''; // Remove the auto draft title
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
528 $post_ID = (int) $post->ID;
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 ); ?>" />
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' ); ?>
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>
548 <script type="text/javascript">edCanvas = document.getElementById('content');edInsertContent = null;</script>
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 ); ?>" />
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="" />
573 wp_dashboard_recent_drafts( $drafts );
576 function wp_dashboard_recent_drafts( $drafts = false ) {
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',
586 $drafts =& $drafts_query->posts;
589 if ( $drafts && is_array( $drafts ) ) {
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 “%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>';
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 ) ? '…' : '' ) . '</p>';
601 <li><?php echo join( "</li>\n<li>", $list ); ?></li>
603 <p class="textright"><a href="edit.php?post_status=draft" ><?php _e('View all'); ?></a></p>
606 _e('There are no drafts at the moment');
611 * Display recent comments dashboard widget content.
615 function wp_dashboard_recent_comments() {
618 if ( current_user_can('edit_posts') )
619 $allowed_states = array('0', '1');
621 $allowed_states = array('1');
623 // Select all comment types and filter out spam later for better query performance.
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;
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" ) ) {
633 foreach ( $possible as $comment ) {
634 if ( count( $comments ) >= $total_items )
636 if ( in_array( $comment->comment_approved, $allowed_states ) && current_user_can( 'read_post', $comment->comment_post_ID ) )
637 $comments[] = $comment;
640 $start = $start + 50;
646 <div id="the-comment-list" class="list:comment">
648 foreach ( $comments as $comment )
649 _wp_dashboard_recent_comments_row( $comment );
655 if ( current_user_can('edit_posts') ) { ?>
656 <?php _get_list_table('WP_Comments_List_Table')->views(); ?>
659 wp_comment_reply( -1, false, 'dashboard', false );
660 wp_comment_trashnotice();
665 <p><?php _e( 'No comments yet.' ); ?></p>
671 function _wp_dashboard_recent_comments_row( &$comment, $show_date = true ) {
672 $GLOBALS['comment'] =& $comment;
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>';
679 $actions_string = '';
680 if ( current_user_can( 'edit_comment', $comment->comment_ID ) ) {
681 // preorder it: Approve | Reply | Edit | Spam | Trash
683 'approve' => '', 'unapprove' => '',
687 'trash' => '', 'delete' => ''
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" ) );
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" );
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&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>';
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>';
709 $actions = apply_filters( 'comment_row_actions', array_filter($actions), $comment );
712 foreach ( $actions as $action => $link ) {
714 ( ( ('approve' == $action || 'unapprove' == $action) && 2 === $i ) || 1 === $i ) ? $sep = '' : $sep = ' | ';
716 // Reply and quickedit need a hide-if-no-js span
717 if ( 'reply' == $action || 'quickedit' == $action )
718 $action .= ' hide-if-no-js';
720 $actions_string .= "<span class='$action'>$sep$link</span>";
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 ) : ?>
729 <?php echo get_avatar( $comment, 50 ); ?>
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>' ); ?>
739 switch ( $comment->comment_type ) :
741 $type = __( 'Pingback' );
744 $type = __( 'Trackback' );
747 $type = ucwords( $comment->comment_type );
749 $type = esc_html( $type );
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>
756 <?php endif; // comment_type ?>
757 <blockquote><p><?php comment_excerpt(); ?></p></blockquote>
758 <p class="row-actions"><?php echo $actions_string; ?></p>
765 * The recent comments dashboard widget control.
769 function wp_dashboard_recent_comments_control() {
770 if ( !$widget_options = get_option( 'dashboard_widget_options' ) )
771 $widget_options = array();
773 if ( !isset($widget_options['dashboard_recent_comments']) )
774 $widget_options['dashboard_recent_comments'] = array();
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 );
782 $number = isset( $widget_options['dashboard_recent_comments']['items'] ) ? (int) $widget_options['dashboard_recent_comments']['items'] : '';
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>';
788 function wp_dashboard_incoming_links() {
789 wp_dashboard_cached_rss_widget( 'dashboard_incoming_links', 'wp_dashboard_incoming_links_output' );
793 * Display incoming links dashboard widget content.
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 );
802 if ( is_wp_error($rss) ) {
803 if ( is_admin() || current_user_can('manage_options') ) {
805 printf(__('<strong>RSS Error</strong>: %s'), $rss->get_error_message());
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… yet. It’s okay — there is no rush.') . "</p>\n";
820 if ( !isset($items) )
823 foreach ( $rss->get_items(0, $items) as $item ) {
829 $link = esc_url( strip_tags( $item->get_link() ) );
831 $author = $item->get_author();
833 $site_link = esc_url( strip_tags( $author->get_link() ) );
835 if ( !$publisher = esc_html( strip_tags( $author->get_name() ) ) )
836 $publisher = __( 'Somebody' );
838 $publisher = __( 'Somebody' );
841 $publisher = "<a href='$site_link'>$publisher</a>";
843 $publisher = "<strong>$publisher</strong>";
845 $content = $item->get_content();
846 $content = wp_html_excerpt($content, 50) . ' ...';
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"' );
852 /* translators: incoming links feed, %1$s is other person, %3$s is content */
853 $text = __( '%1$s linked here saying, "%3$s"' );
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 );
864 echo "\t<li>" . sprintf( $text, $publisher, $link, $content, $date ) . "</li>\n";
872 function wp_dashboard_incoming_links_control() {
873 wp_dashboard_rss_control( 'dashboard_incoming_links', array( 'title' => false, 'show_summary' => false, 'show_author' => false ) );
876 function wp_dashboard_primary() {
877 wp_dashboard_cached_rss_widget( 'dashboard_primary', 'wp_dashboard_rss_output' );
880 function wp_dashboard_primary_control() {
881 wp_dashboard_rss_control( 'dashboard_primary' );
885 * {@internal Missing Short Description}}
889 * @param string $widget_id
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] );
898 function wp_dashboard_secondary() {
899 wp_dashboard_cached_rss_widget( 'dashboard_secondary', 'wp_dashboard_secondary_output' );
902 function wp_dashboard_secondary_control() {
903 wp_dashboard_rss_control( 'dashboard_secondary' );
907 * Display secondary dashboard RSS widget feed.
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 );
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());
924 } elseif ( !$rss->get_item_quantity() ) {
929 echo '<div class="rss-widget">';
930 wp_widget_rss_output( $rss, $widgets['dashboard_secondary'] );
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/'
946 * Display plugins most popular, newest plugins, and recently updated widget text.
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/' );
955 if ( false === $plugin_slugs = get_transient( 'plugin_slugs' ) ) {
956 $plugin_slugs = array_keys( get_plugins() );
957 set_transient( 'plugin_slugs', $plugin_slugs, 86400 );
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() )
964 $items = $$feed->get_items(0, 5);
966 // Pick a random, non-installed plugin
968 // Abort this foreach loop iteration if there's no plugins left of this type
969 if ( 0 == count($items) )
972 $item_key = array_rand($items);
973 $item = $items[$item_key];
975 list($link, $frag) = explode( '#', $item->get_link() );
977 $link = esc_url($link);
978 if ( preg_match( '|/([^/]+?)/?$|', $link, $matches ) )
981 unset( $items[$item_key] );
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] );
994 // If we get to this point, then the random plugin isn't installed and we can stop the while().
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]);
1002 if ( !isset($items[$item_key]) )
1005 // current bbPress feed item titles are: user on "topic title"
1006 if ( preg_match( '/"(.*)"/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 );
1012 $description = esc_html( strip_tags(@html_entity_decode($item->get_description(), ENT_QUOTES, get_option('blog_charset'))) );
1014 $ilink = wp_nonce_url('plugin-install.php?tab=plugin-information&plugin=' . $slug, 'install-plugin_' . $slug) .
1015 '&TB_iframe=true&width=600&height=800';
1017 echo "<h4>$label</h4>\n";
1018 echo "<h5><a href='$link'>$title</a></h5> <span>(<a href='$ilink' class='thickbox' title='$title'>" . __( 'Install' ) . "</a>)</span>\n";
1019 echo "<p>$description</p>\n";
1021 $$feed->__destruct();
1027 * Checks to see if all of the feed url in $check_urls are cached.
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)
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.
1041 function wp_dashboard_cached_rss_widget( $widget_id, $callback, $check_urls = array() ) {
1042 $loading = '<p class="widget-loading hide-if-no-js">' . __( 'Loading…' ) . '</p><p class="hide-if-js">' . __( 'This widget requires JavaScript.' ) . '</p>';
1043 $doing_ajax = ( defined('DOING_AJAX') && DOING_AJAX );
1045 if ( empty($check_urls) ) {
1046 $widgets = get_option( 'dashboard_widget_options' );
1047 if ( empty($widgets[$widget_id]['url']) && ! $doing_ajax ) {
1051 $check_urls = array( $widgets[$widget_id]['url'] );
1054 $cache_key = 'dash_' . md5( $widget_id );
1055 if ( false !== ( $output = get_transient( $cache_key ) ) ) {
1060 if ( ! $doing_ajax ) {
1065 if ( $callback && is_callable( $callback ) ) {
1066 $args = array_slice( func_get_args(), 2 );
1067 array_unshift( $args, $widget_id );
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)
1076 /* Dashboard Widgets Controls */
1078 // Calls widget_control callback
1080 * Calls widget control callback.
1084 * @param int $widget_control_id Registered Widget ID.
1086 function wp_dashboard_trigger_widget_control( $widget_control_id = false ) {
1087 global $wp_dashboard_control_callbacks;
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] ) );
1095 * The RSS dashboard widget control.
1097 * Sets up $args to be used as input to wp_widget_rss_form(). Handles POST data
1098 * from RSS-type widgets.
1102 * @param string $widget_id
1103 * @param array $form_inputs
1105 function wp_dashboard_rss_control( $widget_id, $form_inputs = array() ) {
1106 if ( !$widget_options = get_option( 'dashboard_widget_options' ) )
1107 $widget_options = array();
1109 if ( !isset($widget_options[$widget_id]) )
1110 $widget_options[$widget_id] = array();
1112 $number = 1; // Hack to use wp_widget_rss_form()
1113 $widget_options[$widget_id]['number'] = $number;
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'));
1124 $widget_options[$widget_id]['title'] = htmlentities(strip_tags($rss->get_title()));
1129 update_option( 'dashboard_widget_options', $widget_options );
1130 $cache_key = 'dash_' . md5( $widget_id );
1131 delete_transient( $cache_key );
1134 wp_widget_rss_form( $widget_options[$widget_id], $form_inputs );
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' ) )
1142 $quota = get_space_allowed();
1143 $used = get_dirsize( BLOGUPLOADDIR ) / 1024 / 1024;
1145 if ( $used > $quota )
1146 $percentused = '100';
1148 $percentused = ( $used / $quota ) * 100;
1149 $used_color = ( $percentused >= 70 ) ? ' spam' : '';
1150 $used = round( $used, 2 );
1151 $percentused = number_format( $percentused );
1154 <p class="sub musub"><?php _e( 'Storage Space' ); ?></p>
1155 <div class="table table_content musubtable">
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>
1163 <div class="table table_discussion musubtable">
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>
1171 <br class="clear" />
1174 add_action( 'activity_box_end', 'wp_dashboard_quota' );
1176 // Display Browser Nag Meta Box
1177 function wp_dashboard_browser_nag() {
1179 $response = wp_check_browser_version();
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'] ) );
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'] ) );
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'];
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';
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>';
1201 echo apply_filters( 'browse-happy-notice', $notice, $response );
1204 function dashboard_browser_nag_class( $classes ) {
1205 $response = wp_check_browser_version();
1207 if ( $response && $response['insecure'] )
1208 $classes[] = 'browser-insecure';
1214 * Check if the user needs a browser update
1218 * @return array|bool False on failure, array of browser data on success.
1220 function wp_check_browser_version() {
1221 if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
1224 $key = md5( $_SERVER['HTTP_USER_AGENT'] );
1226 if ( false === ($response = get_site_transient('browser_' . $key) ) ) {
1230 'body' => array( 'useragent' => $_SERVER['HTTP_USER_AGENT'] ),
1231 'user-agent' => 'WordPress/' . $wp_version . '; ' . get_bloginfo( 'url' )
1234 $response = wp_remote_post( 'http://api.wordpress.org/core/browse-happy/1.0/', $options );
1236 if ( is_wp_error( $response ) || 200 != wp_remote_retrieve_response_code( $response ) )
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
1250 $response = unserialize( wp_remote_retrieve_body( $response ) );
1255 set_site_transient( 'browser_' . $key, $response, 604800 ); // cache for 1 week
1262 * Empty function usable by plugins to output empty dashboard widget (to be populated later by JS).
1264 function wp_dashboard_empty() {}
1267 * Displays a welcome panel to introduce users to WordPress.
1271 function wp_welcome_panel() {
1274 if ( ! current_user_can( 'edit_theme_options' ) )
1277 $classes = 'welcome-panel';
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' ) );
1283 $classes .= ' hidden';
1285 list( $display_version ) = explode( '-', $wp_version );
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>
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’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>
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>
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>
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>
1316 <div class="welcome-panel-column welcome-panel-last">
1317 <h4><span class="icon16 icon-appearance"></span> <?php _e( 'Customize Your Site' ); ?></h4>
1319 $ct = current_theme_info();
1320 if ( empty ( $ct->stylesheet_dir ) ) :
1322 printf( __( '<a href="%s">Install a theme</a> to get started customizing your site.' ), esc_url( admin_url( 'themes.php' ) ) );
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' ) ) );
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' ) ) );
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' ) ) );
1335 if ( current_theme_supports( 'widgets' ) )
1336 $customize_links[] = sprintf( __( '<a href="%s">Add some widgets</a>' ), esc_url( admin_url( 'widgets.php' ) ) );
1338 if ( ! empty( $customize_links ) ) {
1340 printf( __( 'Use the current theme — %1$s — 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 );
1344 <?php foreach ( $customize_links as $customize_link ) : ?>
1345 <li><?php echo $customize_link ?></li>
1346 <?php endforeach; ?>
1351 printf( __( 'Use the current theme — %1$s — or <a href="%2$s">choose a new one</a>.' ), $ct->title, esc_url( admin_url( 'themes.php' ) ) );
1357 <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>