cap->create_posts ) ) { $quick_draft_title = sprintf( '%1$s %2$s', __( 'Quick Draft' ), __( 'Drafts' ) ); wp_add_dashboard_widget( 'dashboard_quick_press', $quick_draft_title, 'wp_dashboard_quick_press' ); } // WordPress Events and News wp_add_dashboard_widget( 'dashboard_primary', __( 'WordPress Events and News' ), 'wp_dashboard_events_news' ); if ( is_network_admin() ) { /** * Fires after core widgets for the Network Admin dashboard have been registered. * * @since 3.1.0 */ do_action( 'wp_network_dashboard_setup' ); /** * Filters the list of widgets to load for the Network Admin dashboard. * * @since 3.1.0 * * @param array $dashboard_widgets An array of dashboard widgets. */ $dashboard_widgets = apply_filters( 'wp_network_dashboard_widgets', array() ); } elseif ( is_user_admin() ) { /** * Fires after core widgets for the User Admin dashboard have been registered. * * @since 3.1.0 */ do_action( 'wp_user_dashboard_setup' ); /** * Filters the list of widgets to load for the User Admin dashboard. * * @since 3.1.0 * * @param array $dashboard_widgets An array of dashboard widgets. */ $dashboard_widgets = apply_filters( 'wp_user_dashboard_widgets', array() ); } else { /** * Fires after core widgets for the admin dashboard have been registered. * * @since 2.5.0 */ do_action( 'wp_dashboard_setup' ); /** * Filters the list of widgets to load for the admin dashboard. * * @since 2.5.0 * * @param array $dashboard_widgets An array of dashboard widgets. */ $dashboard_widgets = apply_filters( 'wp_dashboard_widgets', array() ); } foreach ( $dashboard_widgets as $widget_id ) { $name = empty( $wp_registered_widgets[$widget_id]['all_link'] ) ? $wp_registered_widgets[$widget_id]['name'] : $wp_registered_widgets[$widget_id]['name'] . " " . __('View all') . ''; wp_add_dashboard_widget( $widget_id, $name, $wp_registered_widgets[$widget_id]['callback'], $wp_registered_widget_controls[$widget_id]['callback'] ); } if ( 'POST' == $_SERVER['REQUEST_METHOD'] && isset($_POST['widget_id']) ) { check_admin_referer( 'edit-dashboard-widget_' . $_POST['widget_id'], 'dashboard-widget-nonce' ); ob_start(); // hack - but the same hack wp-admin/widgets.php uses wp_dashboard_trigger_widget_control( $_POST['widget_id'] ); ob_end_clean(); wp_redirect( remove_query_arg( 'edit' ) ); exit; } /** This action is documented in wp-admin/edit-form-advanced.php */ do_action( 'do_meta_boxes', $screen->id, 'normal', '' ); /** This action is documented in wp-admin/edit-form-advanced.php */ do_action( 'do_meta_boxes', $screen->id, 'side', '' ); } /** * Gets the community events data that needs to be passed to dashboard.js. * * @since 4.8.0 * * @return array The script data. */ function wp_get_community_events_script_data() { require_once( ABSPATH . 'wp-admin/includes/class-wp-community-events.php' ); $user_id = get_current_user_id(); $user_location = get_user_option( 'community-events-location', $user_id ); $events_client = new WP_Community_Events( $user_id, $user_location ); $script_data = array( 'nonce' => wp_create_nonce( 'community_events' ), 'cache' => $events_client->get_cached_events(), 'l10n' => array( 'enter_closest_city' => __( 'Enter your closest city to find nearby events.' ), 'error_occurred_please_try_again' => __( 'An error occured. Please try again.' ), /* * These specific examples were chosen to highlight the fact that a * state is not needed, even for cities whose name is not unique. * It would be too cumbersome to include that in the instructions * to the user, so it's left as an implication. */ /* translators: %s is the name of the city we couldn't locate. Replace the examples with cities in your locale, but test that they match the expected location before including them. Use endonyms (native locale names) whenever possible. */ 'could_not_locate_city' => __( "We couldn't locate %s. Please try another nearby city. For example: Kansas City; Springfield; Portland." ), // This one is only used with wp.a11y.speak(), so it can/should be more brief. /* translators: %s is the name of a city. */ 'city_updated' => __( 'City updated. Listing events near %s.' ), ) ); return $script_data; } /** * Adds a new dashboard widget. * * @since 2.7.0 * * @global array $wp_dashboard_control_callbacks * * @param string $widget_id Widget ID (used in the 'id' attribute for the widget). * @param string $widget_name Title of the widget. * @param callable $callback Function that fills the widget with the desired content. * The function should echo its output. * @param callable $control_callback Optional. Function that outputs controls for the widget. Default null. * @param array $callback_args Optional. Data that should be set as the $args property of the widget array * (which is the second parameter passed to your callback). Default null. */ function wp_add_dashboard_widget( $widget_id, $widget_name, $callback, $control_callback = null, $callback_args = null ) { $screen = get_current_screen(); global $wp_dashboard_control_callbacks; $private_callback_args = array( '__widget_basename' => $widget_name ); if ( is_null( $callback_args ) ) { $callback_args = $private_callback_args; } else if ( is_array( $callback_args ) ) { $callback_args = array_merge( $callback_args, $private_callback_args ); } if ( $control_callback && current_user_can( 'edit_dashboard' ) && is_callable( $control_callback ) ) { $wp_dashboard_control_callbacks[$widget_id] = $control_callback; if ( isset( $_GET['edit'] ) && $widget_id == $_GET['edit'] ) { list($url) = explode( '#', add_query_arg( 'edit', false ), 2 ); $widget_name .= ' ' . __( 'Cancel' ) . ''; $callback = '_wp_dashboard_control_callback'; } else { list($url) = explode( '#', add_query_arg( 'edit', $widget_id ), 2 ); $widget_name .= ' ' . __( 'Configure' ) . ''; } } $side_widgets = array( 'dashboard_quick_press', 'dashboard_primary' ); $location = 'normal'; if ( in_array($widget_id, $side_widgets) ) $location = 'side'; $priority = 'core'; if ( 'dashboard_browser_nag' === $widget_id ) $priority = 'high'; add_meta_box( $widget_id, $widget_name, $callback, $screen, $location, $priority, $callback_args ); } /** * Outputs controls for the current dashboard widget. * * @access private * @since 2.7.0 * * @param mixed $dashboard * @param array $meta_box */ function _wp_dashboard_control_callback( $dashboard, $meta_box ) { echo '
'; wp_dashboard_trigger_widget_control( $meta_box['id'] ); wp_nonce_field( 'edit-dashboard-widget_' . $meta_box['id'], 'dashboard-widget-nonce' ); echo ''; submit_button( __('Submit') ); echo '
'; } /** * Displays the dashboard. * * @since 2.5.0 */ function wp_dashboard() { $screen = get_current_screen(); $columns = absint( $screen->get_columns() ); $columns_css = ''; if ( $columns ) { $columns_css = " columns-$columns"; } ?>
id, 'normal', '' ); ?>
id, 'side', '' ); ?>
id, 'column3', '' ); ?>
id, 'column4', '' ); ?>
$content

"; } ?>
' . __( 'Create a New Site' ) . ''; if ( current_user_can('create_users') ) $actions['create-user'] = '' . __( 'Create a New User' ) . ''; $c_users = get_user_count(); $c_blogs = get_blog_count(); /* translators: 1: Number of users on the network */ $user_text = sprintf( _n( '%s user', '%s users', $c_users ), number_format_i18n( $c_users ) ); /* translators: 1: Number of sites on the network */ $blog_text = sprintf( _n( '%s site', '%s sites', $c_blogs ), number_format_i18n( $c_blogs ) ); /* translators: 1: Text indicating the number of sites on the network, 2: Text indicating the number of users on the network */ $sentence = sprintf( __( 'You have %1$s and %2$s.' ), $blog_text, $user_text ); if ( $actions ) { echo ''; } ?>

'submit_users' ) ); ?>

'submit_sites' ) ); ?>

post_status != 'auto-draft' ) { // auto-draft doesn't exists anymore $post = get_default_post_to_edit( 'post', true ); update_user_option( get_current_user_id(), 'dashboard_quick_press_last_post_id', (int) $post->ID ); // Save post_ID } else { $post->post_title = ''; // Remove the auto draft title } } else { $post = get_default_post_to_edit( 'post' , true); $user_id = get_current_user_id(); // Don't create an option if this is a super admin who does not belong to this site. if ( in_array( get_current_blog_id(), array_keys( get_blogs_of_user( $user_id ) ) ) ) update_user_option( $user_id, 'dashboard_quick_press_last_post_id', (int) $post->ID ); // Save post_ID } $post_ID = (int) $post->ID; ?>

'save-post' ) ); ?>

'post', 'post_status' => 'draft', 'author' => get_current_user_id(), 'posts_per_page' => 4, 'orderby' => 'modified', 'order' => 'DESC' ); /** * Filters the post query arguments for the 'Recent Drafts' dashboard widget. * * @since 4.4.0 * * @param array $query_args The query arguments for the 'Recent Drafts' dashboard widget. */ $query_args = apply_filters( 'dashboard_recent_drafts_query_args', $query_args ); $drafts = get_posts( $query_args ); if ( ! $drafts ) { return; } } echo '
'; if ( count( $drafts ) > 3 ) { echo '

' . _x( 'View all', 'drafts' ) . "

\n"; } echo '

' . __( 'Drafts' ) . "

\n\n
"; } /** * Outputs a row for the Recent Comments widget. * * @access private * @since 2.7.0 * * @global WP_Comment $comment * * @param WP_Comment $comment The current comment. * @param bool $show_date Optional. Whether to display the date. */ function _wp_dashboard_recent_comments_row( &$comment, $show_date = true ) { $GLOBALS['comment'] = clone $comment; if ( $comment->comment_post_ID > 0 ) { $comment_post_title = _draft_or_post_title( $comment->comment_post_ID ); $comment_post_url = get_the_permalink( $comment->comment_post_ID ); $comment_post_link = "$comment_post_title"; } else { $comment_post_link = ''; } $actions_string = ''; if ( current_user_can( 'edit_comment', $comment->comment_ID ) ) { // Pre-order it: Approve | Reply | Edit | Spam | Trash. $actions = array( 'approve' => '', 'unapprove' => '', 'reply' => '', 'edit' => '', 'spam' => '', 'trash' => '', 'delete' => '', 'view' => '', ); $del_nonce = esc_html( '_wpnonce=' . wp_create_nonce( "delete-comment_$comment->comment_ID" ) ); $approve_nonce = esc_html( '_wpnonce=' . wp_create_nonce( "approve-comment_$comment->comment_ID" ) ); $approve_url = esc_url( "comment.php?action=approvecomment&p=$comment->comment_post_ID&c=$comment->comment_ID&$approve_nonce" ); $unapprove_url = esc_url( "comment.php?action=unapprovecomment&p=$comment->comment_post_ID&c=$comment->comment_ID&$approve_nonce" ); $spam_url = esc_url( "comment.php?action=spamcomment&p=$comment->comment_post_ID&c=$comment->comment_ID&$del_nonce" ); $trash_url = esc_url( "comment.php?action=trashcomment&p=$comment->comment_post_ID&c=$comment->comment_ID&$del_nonce" ); $delete_url = esc_url( "comment.php?action=deletecomment&p=$comment->comment_post_ID&c=$comment->comment_ID&$del_nonce" ); $actions['approve'] = "" . __( 'Approve' ) . ''; $actions['unapprove'] = "" . __( 'Unapprove' ) . ''; $actions['edit'] = "". __( 'Edit' ) . ''; $actions['reply'] = '' . __( 'Reply' ) . ''; $actions['spam'] = "" . /* translators: mark as spam link */ _x( 'Spam', 'verb' ) . ''; if ( ! EMPTY_TRASH_DAYS ) { $actions['delete'] = "" . __( 'Delete Permanently' ) . ''; } else { $actions['trash'] = "" . _x( 'Trash', 'verb' ) . ''; } $actions['view'] = '' . __( 'View' ) . ''; /** * Filters the action links displayed for each comment in the 'Recent Comments' * dashboard widget. * * @since 2.6.0 * * @param array $actions An array of comment actions. Default actions include: * 'Approve', 'Unapprove', 'Edit', 'Reply', 'Spam', * 'Delete', and 'Trash'. * @param WP_Comment $comment The comment object. */ $actions = apply_filters( 'comment_row_actions', array_filter($actions), $comment ); $i = 0; foreach ( $actions as $action => $link ) { ++$i; ( ( ('approve' == $action || 'unapprove' == $action) && 2 === $i ) || 1 === $i ) ? $sep = '' : $sep = ' | '; // Reply and quickedit need a hide-if-no-js span if ( 'reply' == $action || 'quickedit' == $action ) { $action .= ' hide-if-no-js'; } if ( 'view' === $action && '1' !== $comment->comment_approved ) { $action .= ' hidden'; } $actions_string .= "$sep$link"; } } ?>
  • > comment_type || 'comment' == $comment->comment_type ) : ?>

    ' . get_comment_author_link( $comment ) . '', $comment_post_link, '' . __( '[Pending]' ) . '' ); } else { printf( /* translators: 1: comment author, 2: notification if the comment is pending */ __( 'From %1$s %2$s' ), '' . get_comment_author_link( $comment ) . '', '' . __( '[Pending]' ) . '' ); } ?>

    comment_type ) { case 'pingback' : $type = __( 'Pingback' ); break; case 'trackback' : $type = __( 'Trackback' ); break; default : $type = ucwords( $comment->comment_type ); } $type = esc_html( $type ); ?>

    $type", $comment_post_link, '' . __( '[Pending]' ) . '' ); } else { printf( /* translators: 1: type of comment, 2: notification if the comment is pending */ _x( '%1$s %2$s', 'dashboard' ), "$type", '' . __( '[Pending]' ) . '' ); } ?>

  • '; $future_posts = wp_dashboard_recent_posts( array( 'max' => 5, 'status' => 'future', 'order' => 'ASC', 'title' => __( 'Publishing Soon' ), 'id' => 'future-posts', ) ); $recent_posts = wp_dashboard_recent_posts( array( 'max' => 5, 'status' => 'publish', 'order' => 'DESC', 'title' => __( 'Recently Published' ), 'id' => 'published-posts', ) ); $recent_comments = wp_dashboard_recent_comments(); if ( !$future_posts && !$recent_posts && !$recent_comments ) { echo '
    '; echo ''; echo '

    ' . __( 'No activity yet!' ) . '

    '; echo '
    '; } echo ''; } /** * Generates Publishing Soon and Recently Published sections. * * @since 3.8.0 * * @param array $args { * An array of query and display arguments. * * @type int $max Number of posts to display. * @type string $status Post status. * @type string $order Designates ascending ('ASC') or descending ('DESC') order. * @type string $title Section title. * @type string $id The container id. * } * @return bool False if no posts were found. True otherwise. */ function wp_dashboard_recent_posts( $args ) { $query_args = array( 'post_type' => 'post', 'post_status' => $args['status'], 'orderby' => 'date', 'order' => $args['order'], 'posts_per_page' => intval( $args['max'] ), 'no_found_rows' => true, 'cache_results' => false, 'perm' => ( 'future' === $args['status'] ) ? 'editable' : 'readable', ); /** * Filters the query arguments used for the Recent Posts widget. * * @since 4.2.0 * * @param array $query_args The arguments passed to WP_Query to produce the list of posts. */ $query_args = apply_filters( 'dashboard_recent_posts_query_args', $query_args ); $posts = new WP_Query( $query_args ); if ( $posts->have_posts() ) { echo '
    '; echo '

    ' . $args['title'] . '

    '; echo ''; echo '
    '; } else { return false; } wp_reset_postdata(); return true; } /** * Show Comments section. * * @since 3.8.0 * * @param int $total_items Optional. Number of comments to query. Default 5. * @return bool False if no comments were found. True otherwise. */ function wp_dashboard_recent_comments( $total_items = 5 ) { // Select all comment types and filter out spam later for better query performance. $comments = array(); $comments_query = array( 'number' => $total_items * 5, 'offset' => 0 ); if ( ! current_user_can( 'edit_posts' ) ) $comments_query['status'] = 'approve'; while ( count( $comments ) < $total_items && $possible = get_comments( $comments_query ) ) { if ( ! is_array( $possible ) ) { break; } foreach ( $possible as $comment ) { if ( ! current_user_can( 'read_post', $comment->comment_post_ID ) ) continue; $comments[] = $comment; if ( count( $comments ) == $total_items ) break 2; } $comments_query['offset'] += $comments_query['number']; $comments_query['number'] = $total_items * 10; } if ( $comments ) { echo '
    '; echo '

    ' . __( 'Recent Comments' ) . '

    '; echo ''; if ( current_user_can( 'edit_posts' ) ) { echo '

    ' . __( 'View more comments' ) . '

    '; _get_list_table( 'WP_Comments_List_Table' )->views(); } wp_comment_reply( -1, false, 'dashboard', false ); wp_comment_trashnotice(); echo '
    '; } else { return false; } return true; } /** * Display generic dashboard RSS widget feed. * * @since 2.5.0 * * @param string $widget_id */ function wp_dashboard_rss_output( $widget_id ) { $widgets = get_option( 'dashboard_widget_options' ); echo '
    '; wp_widget_rss_output( $widgets[ $widget_id ] ); echo "
    "; } /** * Checks to see if all of the feed url in $check_urls are cached. * * If $check_urls is empty, look for the rss feed url found in the dashboard * widget options of $widget_id. If cached, call $callback, a function that * echoes out output for this widget. If not cache, echo a "Loading..." stub * which is later replaced by Ajax call (see top of /wp-admin/index.php) * * @since 2.5.0 * * @param string $widget_id * @param callable $callback * @param array $check_urls RSS feeds * @return bool False on failure. True on success. */ function wp_dashboard_cached_rss_widget( $widget_id, $callback, $check_urls = array() ) { $loading = '

    ' . __( 'Loading…' ) . '

    ' . __( 'This widget requires JavaScript.' ) . '

    '; $doing_ajax = wp_doing_ajax(); if ( empty($check_urls) ) { $widgets = get_option( 'dashboard_widget_options' ); if ( empty($widgets[$widget_id]['url']) && ! $doing_ajax ) { echo $loading; return false; } $check_urls = array( $widgets[$widget_id]['url'] ); } $locale = get_locale(); $cache_key = 'dash_' . md5( $widget_id . '_' . $locale ); if ( false !== ( $output = get_transient( $cache_key ) ) ) { echo $output; return true; } if ( ! $doing_ajax ) { echo $loading; return false; } if ( $callback && is_callable( $callback ) ) { $args = array_slice( func_get_args(), 3 ); array_unshift( $args, $widget_id, $check_urls ); ob_start(); call_user_func_array( $callback, $args ); set_transient( $cache_key, ob_get_flush(), 12 * HOUR_IN_SECONDS ); // Default lifetime in cache of 12 hours (same as the feeds) } return true; } // // Dashboard Widgets Controls // /** * Calls widget control callback. * * @since 2.5.0 * * @global array $wp_dashboard_control_callbacks * * @param int $widget_control_id Registered Widget ID. */ function wp_dashboard_trigger_widget_control( $widget_control_id = false ) { global $wp_dashboard_control_callbacks; 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]) ) { call_user_func( $wp_dashboard_control_callbacks[$widget_control_id], '', array( 'id' => $widget_control_id, 'callback' => $wp_dashboard_control_callbacks[$widget_control_id] ) ); } } /** * The RSS dashboard widget control. * * Sets up $args to be used as input to wp_widget_rss_form(). Handles POST data * from RSS-type widgets. * * @since 2.5.0 * * @param string $widget_id * @param array $form_inputs */ function wp_dashboard_rss_control( $widget_id, $form_inputs = array() ) { if ( !$widget_options = get_option( 'dashboard_widget_options' ) ) $widget_options = array(); if ( !isset($widget_options[$widget_id]) ) $widget_options[$widget_id] = array(); $number = 1; // Hack to use wp_widget_rss_form() $widget_options[$widget_id]['number'] = $number; if ( 'POST' == $_SERVER['REQUEST_METHOD'] && isset($_POST['widget-rss'][$number]) ) { $_POST['widget-rss'][$number] = wp_unslash( $_POST['widget-rss'][$number] ); $widget_options[$widget_id] = wp_widget_rss_process( $_POST['widget-rss'][$number] ); $widget_options[$widget_id]['number'] = $number; // Title is optional. If black, fill it if possible. if ( !$widget_options[$widget_id]['title'] && isset($_POST['widget-rss'][$number]['title']) ) { $rss = fetch_feed($widget_options[$widget_id]['url']); if ( is_wp_error($rss) ) { $widget_options[$widget_id]['title'] = htmlentities(__('Unknown Feed')); } else { $widget_options[$widget_id]['title'] = htmlentities(strip_tags($rss->get_title())); $rss->__destruct(); unset($rss); } } update_option( 'dashboard_widget_options', $widget_options ); $cache_key = 'dash_' . md5( $widget_id ); delete_transient( $cache_key ); } wp_widget_rss_form( $widget_options[$widget_id], $form_inputs ); } /** * Renders the Events and News dashboard widget. * * @since 4.8.0 */ function wp_dashboard_events_news() { wp_print_community_events_markup(); ?>

    array( /** * Filters the primary link URL for the 'WordPress News' dashboard widget. * * @since 2.5.0 * * @param string $link The widget's primary link URL. */ 'link' => apply_filters( 'dashboard_primary_link', __( 'https://wordpress.org/news/' ) ), /** * Filters the primary feed URL for the 'WordPress News' dashboard widget. * * @since 2.3.0 * * @param string $url The widget's primary feed URL. */ 'url' => apply_filters( 'dashboard_primary_feed', __( 'http://wordpress.org/news/feed/' ) ), /** * Filters the primary link title for the 'WordPress News' dashboard widget. * * @since 2.3.0 * * @param string $title Title attribute for the widget's primary link. */ 'title' => apply_filters( 'dashboard_primary_title', __( 'WordPress Blog' ) ), 'items' => 1, 'show_summary' => 0, 'show_author' => 0, 'show_date' => 0, ), 'planet' => array( /** * Filters the secondary link URL for the 'WordPress News' dashboard widget. * * @since 2.3.0 * * @param string $link The widget's secondary link URL. */ 'link' => apply_filters( 'dashboard_secondary_link', __( 'https://planet.wordpress.org/' ) ), /** * Filters the secondary feed URL for the 'WordPress News' dashboard widget. * * @since 2.3.0 * * @param string $url The widget's secondary feed URL. */ 'url' => apply_filters( 'dashboard_secondary_feed', __( 'https://planet.wordpress.org/feed/' ) ), /** * Filters the secondary link title for the 'WordPress News' dashboard widget. * * @since 2.3.0 * * @param string $title Title attribute for the widget's secondary link. */ 'title' => apply_filters( 'dashboard_secondary_title', __( 'Other WordPress News' ) ), /** * Filters the number of secondary link items for the 'WordPress News' dashboard widget. * * @since 4.4.0 * * @param string $items How many items to show in the secondary feed. */ 'items' => apply_filters( 'dashboard_secondary_items', 3 ), 'show_summary' => 0, 'show_author' => 0, 'show_date' => 0, ) ); wp_dashboard_cached_rss_widget( 'dashboard_primary', 'wp_dashboard_primary_output', $feeds ); } /** * Display the WordPress news feeds. * * @since 3.8.0 * @since 4.8.0 Removed popular plugins feed. * * @param string $widget_id Widget ID. * @param array $feeds Array of RSS feeds. */ function wp_dashboard_primary_output( $widget_id, $feeds ) { foreach ( $feeds as $type => $args ) { $args['type'] = $type; echo '
    '; wp_widget_rss_output( $args['url'], $args ); echo "
    "; } } /** * Display file upload quota on dashboard. * * Runs on the {@see 'activity_box_end'} hook in wp_dashboard_right_now(). * * @since 3.0.0 * * @return bool|null True if not multisite, user can't upload files, or the space check option is disabled. */ function wp_dashboard_quota() { if ( !is_multisite() || !current_user_can( 'upload_files' ) || get_site_option( 'upload_space_check_disabled' ) ) return true; $quota = get_space_allowed(); $used = get_space_used(); if ( $used > $quota ) $percentused = '100'; else $percentused = ( $used / $quota ) * 100; $used_class = ( $percentused >= 70 ) ? ' warning' : ''; $used = round( $used, 2 ); $percentused = number_format( $percentused ); ?>

    %s', esc_url( $response['update_url'] ), esc_html( $response['name'] ) ) ); } else { /* translators: %s: browser name and link */ $msg = sprintf( __( "It looks like you're using an old version of %s. For the best WordPress experience, please update your browser." ), sprintf( '%s', esc_url( $response['update_url'] ), esc_html( $response['name'] ) ) ); } $browser_nag_class = ''; if ( !empty( $response['img_src'] ) ) { $img_src = ( is_ssl() && ! empty( $response['img_src_ssl'] ) )? $response['img_src_ssl'] : $response['img_src']; $notice .= '
    '; $browser_nag_class = ' has-browser-icon'; } $notice .= "

    {$msg}

    "; $browsehappy = 'http://browsehappy.com/'; $locale = get_user_locale(); if ( 'en_US' !== $locale ) $browsehappy = add_query_arg( 'locale', $locale, $browsehappy ); $notice .= '

    ' . sprintf( __( 'Update %2$s or learn how to browse happy' ), esc_attr( $response['update_url'] ), esc_html( $response['name'] ), esc_url( $browsehappy ) ) . '

    '; $notice .= '

    ' . __( 'Dismiss' ) . '

    '; $notice .= '
    '; } /** * Filters the notice output for the 'Browse Happy' nag meta box. * * @since 3.2.0 * * @param string $notice The notice content. * @param array $response An array containing web browser information. */ echo apply_filters( 'browse-happy-notice', $notice, $response ); } /** * @since 3.2.0 * * @param array $classes * @return array */ function dashboard_browser_nag_class( $classes ) { $response = wp_check_browser_version(); if ( $response && $response['insecure'] ) $classes[] = 'browser-insecure'; return $classes; } /** * Check if the user needs a browser update * * @since 3.2.0 * * @return array|bool False on failure, array of browser data on success. */ function wp_check_browser_version() { if ( empty( $_SERVER['HTTP_USER_AGENT'] ) ) return false; $key = md5( $_SERVER['HTTP_USER_AGENT'] ); if ( false === ($response = get_site_transient('browser_' . $key) ) ) { $options = array( 'body' => array( 'useragent' => $_SERVER['HTTP_USER_AGENT'] ), 'user-agent' => 'WordPress/' . get_bloginfo( 'version' ) . '; ' . home_url() ); $response = wp_remote_post( 'http://api.wordpress.org/core/browse-happy/1.1/', $options ); if ( is_wp_error( $response ) || 200 != wp_remote_retrieve_response_code( $response ) ) return false; /** * Response should be an array with: * 'name' - string - A user friendly browser name * 'version' - string - The version of the browser the user is using * 'current_version' - string - The most recent version of the browser * 'upgrade' - boolean - Whether the browser needs an upgrade * 'insecure' - boolean - Whether the browser is deemed insecure * 'upgrade_url' - string - The url to visit to upgrade * 'img_src' - string - An image representing the browser * 'img_src_ssl' - string - An image (over SSL) representing the browser */ $response = json_decode( wp_remote_retrieve_body( $response ), true ); if ( ! is_array( $response ) ) return false; set_site_transient( 'browser_' . $key, $response, WEEK_IN_SECONDS ); } return $response; } /** * Empty function usable by plugins to output empty dashboard widget (to be populated later by JS). */ function wp_dashboard_empty() {} /** * Displays a welcome panel to introduce users to WordPress. * * @since 3.3.0 */ function wp_welcome_panel() { ?>

    true ) ) ) > 1 ) ) : ?>

    change your theme completely' ), admin_url( 'themes.php' ) ); ?>

    • ' . __( 'Edit your front page' ) . '', get_edit_post_link( get_option( 'page_on_front' ) ) ); ?>
    • ' . __( 'Add additional pages' ) . '', admin_url( 'post-new.php?post_type=page' ) ); ?>
    • ' . __( 'Edit your front page' ) . '', get_edit_post_link( get_option( 'page_on_front' ) ) ); ?>
    • ' . __( 'Add additional pages' ) . '', admin_url( 'post-new.php?post_type=page' ) ); ?>
    • ' . __( 'Add a blog post' ) . '', admin_url( 'post-new.php' ) ); ?>
    • ' . __( 'Write your first blog post' ) . '', admin_url( 'post-new.php' ) ); ?>
    • ' . __( 'Add an About page' ) . '', admin_url( 'post-new.php?post_type=page' ) ); ?>
    • ' . __( 'View your site' ) . '', home_url( '/' ) ); ?>

    • widgets or menus' ), admin_url( 'widgets.php' ), admin_url( 'nav-menus.php' ) ); } elseif ( current_theme_supports( 'widgets' ) ) { echo '' . __( 'Manage widgets' ) . ''; } else { echo '' . __( 'Manage menus' ) . ''; } ?>
    • ' . __( 'Turn comments on or off' ) . '', admin_url( 'options-discussion.php' ) ); ?>
    • ' . __( 'Learn more about getting started' ) . '', __( 'https://codex.wordpress.org/First_Steps_With_WordPress' ) ); ?>