wp/wp-admin/includes/dashboard.php
changeset 18 be944660c56a
parent 16 a86126ab1dd4
child 19 3d72ae0968f4
equal deleted inserted replaced
17:34716fd837a4 18:be944660c56a
    13  *
    13  *
    14  * @since 2.5.0
    14  * @since 2.5.0
    15  *
    15  *
    16  * @global array $wp_registered_widgets
    16  * @global array $wp_registered_widgets
    17  * @global array $wp_registered_widget_controls
    17  * @global array $wp_registered_widget_controls
    18  * @global array $wp_dashboard_control_callbacks
    18  * @global callable[] $wp_dashboard_control_callbacks
    19  */
    19  */
    20 function wp_dashboard_setup() {
    20 function wp_dashboard_setup() {
    21 	global $wp_registered_widgets, $wp_registered_widget_controls, $wp_dashboard_control_callbacks;
    21 	global $wp_registered_widgets, $wp_registered_widget_controls, $wp_dashboard_control_callbacks;
       
    22 
    22 	$wp_dashboard_control_callbacks = array();
    23 	$wp_dashboard_control_callbacks = array();
    23 	$screen                         = get_current_screen();
    24 	$screen                         = get_current_screen();
    24 
    25 
    25 	/* Register Widgets and Controls */
    26 	/* Register Widgets and Controls */
    26 
    27 
    27 	$response = wp_check_browser_version();
    28 	$response = wp_check_browser_version();
    28 
    29 
    29 	if ( $response && $response['upgrade'] ) {
    30 	if ( $response && $response['upgrade'] ) {
    30 		add_filter( 'postbox_classes_dashboard_dashboard_browser_nag', 'dashboard_browser_nag_class' );
    31 		add_filter( 'postbox_classes_dashboard_dashboard_browser_nag', 'dashboard_browser_nag_class' );
       
    32 
    31 		if ( $response['insecure'] ) {
    33 		if ( $response['insecure'] ) {
    32 			wp_add_dashboard_widget( 'dashboard_browser_nag', __( 'You are using an insecure browser!' ), 'wp_dashboard_browser_nag' );
    34 			wp_add_dashboard_widget( 'dashboard_browser_nag', __( 'You are using an insecure browser!' ), 'wp_dashboard_browser_nag' );
    33 		} else {
    35 		} else {
    34 			wp_add_dashboard_widget( 'dashboard_browser_nag', __( 'Your browser is out of date!' ), 'wp_dashboard_browser_nag' );
    36 			wp_add_dashboard_widget( 'dashboard_browser_nag', __( 'Your browser is out of date!' ), 'wp_dashboard_browser_nag' );
    35 		}
    37 		}
    36 	}
    38 	}
    37 
    39 
    38 	// PHP Version.
    40 	// PHP Version.
    39 	$response = wp_check_php_version();
    41 	$response = wp_check_php_version();
    40 	if ( $response && isset( $response['is_acceptable'] ) && ! $response['is_acceptable'] && current_user_can( 'update_php' ) ) {
    42 
       
    43 	if ( $response && isset( $response['is_acceptable'] ) && ! $response['is_acceptable']
       
    44 		&& current_user_can( 'update_php' )
       
    45 	) {
    41 		add_filter( 'postbox_classes_dashboard_dashboard_php_nag', 'dashboard_php_nag_class' );
    46 		add_filter( 'postbox_classes_dashboard_dashboard_php_nag', 'dashboard_php_nag_class' );
    42 		wp_add_dashboard_widget( 'dashboard_php_nag', __( 'PHP Update Required' ), 'wp_dashboard_php_nag' );
    47 
       
    48 		wp_add_dashboard_widget( 'dashboard_php_nag', __( 'PHP Update Recommended' ), 'wp_dashboard_php_nag' );
    43 	}
    49 	}
    44 
    50 
    45 	// Site Health.
    51 	// Site Health.
    46 	if ( current_user_can( 'view_site_health_checks' ) && ! is_network_admin() ) {
    52 	if ( current_user_can( 'view_site_health_checks' ) && ! is_network_admin() ) {
    47 		if ( ! class_exists( 'WP_Site_Health' ) ) {
    53 		if ( ! class_exists( 'WP_Site_Health' ) ) {
   155 
   161 
   156 /**
   162 /**
   157  * Adds a new dashboard widget.
   163  * Adds a new dashboard widget.
   158  *
   164  *
   159  * @since 2.7.0
   165  * @since 2.7.0
   160  *
   166  * @since 5.6.0 The `$context` and `$priority` parameters were added.
   161  * @global array $wp_dashboard_control_callbacks
   167  *
       
   168  * @global callable[] $wp_dashboard_control_callbacks
   162  *
   169  *
   163  * @param string   $widget_id        Widget ID  (used in the 'id' attribute for the widget).
   170  * @param string   $widget_id        Widget ID  (used in the 'id' attribute for the widget).
   164  * @param string   $widget_name      Title of the widget.
   171  * @param string   $widget_name      Title of the widget.
   165  * @param callable $callback         Function that fills the widget with the desired content.
   172  * @param callable $callback         Function that fills the widget with the desired content.
   166  *                                   The function should echo its output.
   173  *                                   The function should echo its output.
   167  * @param callable $control_callback Optional. Function that outputs controls for the widget. Default null.
   174  * @param callable $control_callback Optional. Function that outputs controls for the widget. Default null.
   168  * @param array    $callback_args    Optional. Data that should be set as the $args property of the widget array
   175  * @param array    $callback_args    Optional. Data that should be set as the $args property of the widget array
   169  *                                   (which is the second parameter passed to your callback). Default null.
   176  *                                   (which is the second parameter passed to your callback). Default null.
   170  */
   177  * @param string   $context          Optional. The context within the screen where the box should display.
   171 function wp_add_dashboard_widget( $widget_id, $widget_name, $callback, $control_callback = null, $callback_args = null ) {
   178  *                                   Accepts 'normal', 'side', 'column3', or 'column4'. Default 'normal'.
       
   179  * @param string   $priority         Optional. The priority within the context where the box should show.
       
   180  *                                   Accepts 'high', 'core', 'default', or 'low'. Default 'core'.
       
   181  */
       
   182 function wp_add_dashboard_widget( $widget_id, $widget_name, $callback, $control_callback = null, $callback_args = null, $context = 'normal', $priority = 'core' ) {
       
   183 	global $wp_dashboard_control_callbacks;
       
   184 
   172 	$screen = get_current_screen();
   185 	$screen = get_current_screen();
   173 	global $wp_dashboard_control_callbacks;
       
   174 
   186 
   175 	$private_callback_args = array( '__widget_basename' => $widget_name );
   187 	$private_callback_args = array( '__widget_basename' => $widget_name );
   176 
   188 
   177 	if ( is_null( $callback_args ) ) {
   189 	if ( is_null( $callback_args ) ) {
   178 		$callback_args = $private_callback_args;
   190 		$callback_args = $private_callback_args;
   179 	} elseif ( is_array( $callback_args ) ) {
   191 	} elseif ( is_array( $callback_args ) ) {
   180 		$callback_args = array_merge( $callback_args, $private_callback_args );
   192 		$callback_args = array_merge( $callback_args, $private_callback_args );
   181 	}
   193 	}
   182 
   194 
   183 	if ( $control_callback && current_user_can( 'edit_dashboard' ) && is_callable( $control_callback ) ) {
   195 	if ( $control_callback && is_callable( $control_callback ) && current_user_can( 'edit_dashboard' ) ) {
   184 		$wp_dashboard_control_callbacks[ $widget_id ] = $control_callback;
   196 		$wp_dashboard_control_callbacks[ $widget_id ] = $control_callback;
   185 		if ( isset( $_GET['edit'] ) && $widget_id == $_GET['edit'] ) {
   197 
       
   198 		if ( isset( $_GET['edit'] ) && $widget_id === $_GET['edit'] ) {
   186 			list($url)    = explode( '#', add_query_arg( 'edit', false ), 2 );
   199 			list($url)    = explode( '#', add_query_arg( 'edit', false ), 2 );
   187 			$widget_name .= ' <span class="postbox-title-action"><a href="' . esc_url( $url ) . '">' . __( 'Cancel' ) . '</a></span>';
   200 			$widget_name .= ' <span class="postbox-title-action"><a href="' . esc_url( $url ) . '">' . __( 'Cancel' ) . '</a></span>';
   188 			$callback     = '_wp_dashboard_control_callback';
   201 			$callback     = '_wp_dashboard_control_callback';
   189 		} else {
   202 		} else {
   190 			list($url)    = explode( '#', add_query_arg( 'edit', $widget_id ), 2 );
   203 			list($url)    = explode( '#', add_query_arg( 'edit', $widget_id ), 2 );
   192 		}
   205 		}
   193 	}
   206 	}
   194 
   207 
   195 	$side_widgets = array( 'dashboard_quick_press', 'dashboard_primary' );
   208 	$side_widgets = array( 'dashboard_quick_press', 'dashboard_primary' );
   196 
   209 
   197 	$location = 'normal';
       
   198 	if ( in_array( $widget_id, $side_widgets, true ) ) {
   210 	if ( in_array( $widget_id, $side_widgets, true ) ) {
   199 		$location = 'side';
   211 		$context = 'side';
   200 	}
   212 	}
   201 
   213 
   202 	$high_priority_widgets = array( 'dashboard_browser_nag', 'dashboard_php_nag' );
   214 	$high_priority_widgets = array( 'dashboard_browser_nag', 'dashboard_php_nag' );
   203 
   215 
   204 	$priority = 'core';
       
   205 	if ( in_array( $widget_id, $high_priority_widgets, true ) ) {
   216 	if ( in_array( $widget_id, $high_priority_widgets, true ) ) {
   206 		$priority = 'high';
   217 		$priority = 'high';
   207 	}
   218 	}
   208 
   219 
   209 	add_meta_box( $widget_id, $widget_name, $callback, $screen, $location, $priority, $callback_args );
   220 	if ( empty( $context ) ) {
       
   221 		$context = 'normal';
       
   222 	}
       
   223 
       
   224 	if ( empty( $priority ) ) {
       
   225 		$priority = 'core';
       
   226 	}
       
   227 
       
   228 	add_meta_box( $widget_id, $widget_name, $callback, $screen, $context, $priority, $callback_args );
   210 }
   229 }
   211 
   230 
   212 /**
   231 /**
   213  * Outputs controls for the current dashboard widget.
   232  * Outputs controls for the current dashboard widget.
   214  *
   233  *
   234  */
   253  */
   235 function wp_dashboard() {
   254 function wp_dashboard() {
   236 	$screen      = get_current_screen();
   255 	$screen      = get_current_screen();
   237 	$columns     = absint( $screen->get_columns() );
   256 	$columns     = absint( $screen->get_columns() );
   238 	$columns_css = '';
   257 	$columns_css = '';
       
   258 
   239 	if ( $columns ) {
   259 	if ( $columns ) {
   240 		$columns_css = " columns-$columns";
   260 		$columns_css = " columns-$columns";
   241 	}
   261 	}
   242 
       
   243 	?>
   262 	?>
   244 <div id="dashboard-widgets" class="metabox-holder<?php echo $columns_css; ?>">
   263 <div id="dashboard-widgets" class="metabox-holder<?php echo $columns_css; ?>">
   245 	<div id="postbox-container-1" class="postbox-container">
   264 	<div id="postbox-container-1" class="postbox-container">
   246 	<?php do_meta_boxes( $screen->id, 'normal', '' ); ?>
   265 	<?php do_meta_boxes( $screen->id, 'normal', '' ); ?>
   247 	</div>
   266 	</div>
   279 	<ul>
   298 	<ul>
   280 	<?php
   299 	<?php
   281 	// Posts and Pages.
   300 	// Posts and Pages.
   282 	foreach ( array( 'post', 'page' ) as $post_type ) {
   301 	foreach ( array( 'post', 'page' ) as $post_type ) {
   283 		$num_posts = wp_count_posts( $post_type );
   302 		$num_posts = wp_count_posts( $post_type );
       
   303 
   284 		if ( $num_posts && $num_posts->publish ) {
   304 		if ( $num_posts && $num_posts->publish ) {
   285 			if ( 'post' === $post_type ) {
   305 			if ( 'post' === $post_type ) {
   286 				/* translators: %s: Number of posts. */
   306 				/* translators: %s: Number of posts. */
   287 				$text = _n( '%s Post', '%s Posts', $num_posts->publish );
   307 				$text = _n( '%s Post', '%s Posts', $num_posts->publish );
   288 			} else {
   308 			} else {
   289 				/* translators: %s: Number of pages. */
   309 				/* translators: %s: Number of pages. */
   290 				$text = _n( '%s Page', '%s Pages', $num_posts->publish );
   310 				$text = _n( '%s Page', '%s Pages', $num_posts->publish );
   291 			}
   311 			}
       
   312 
   292 			$text             = sprintf( $text, number_format_i18n( $num_posts->publish ) );
   313 			$text             = sprintf( $text, number_format_i18n( $num_posts->publish ) );
   293 			$post_type_object = get_post_type_object( $post_type );
   314 			$post_type_object = get_post_type_object( $post_type );
       
   315 
   294 			if ( $post_type_object && current_user_can( $post_type_object->cap->edit_posts ) ) {
   316 			if ( $post_type_object && current_user_can( $post_type_object->cap->edit_posts ) ) {
   295 				printf( '<li class="%1$s-count"><a href="edit.php?post_type=%1$s">%2$s</a></li>', $post_type, $text );
   317 				printf( '<li class="%1$s-count"><a href="edit.php?post_type=%1$s">%2$s</a></li>', $post_type, $text );
   296 			} else {
   318 			} else {
   297 				printf( '<li class="%1$s-count"><span>%2$s</span></li>', $post_type, $text );
   319 				printf( '<li class="%1$s-count"><span>%2$s</span></li>', $post_type, $text );
   298 			}
   320 			}
   299 		}
   321 		}
   300 	}
   322 	}
       
   323 
   301 	// Comments.
   324 	// Comments.
   302 	$num_comm = wp_count_comments();
   325 	$num_comm = wp_count_comments();
       
   326 
   303 	if ( $num_comm && ( $num_comm->approved || $num_comm->moderated ) ) {
   327 	if ( $num_comm && ( $num_comm->approved || $num_comm->moderated ) ) {
   304 		/* translators: %s: Number of comments. */
   328 		/* translators: %s: Number of comments. */
   305 		$text = sprintf( _n( '%s Comment', '%s Comments', $num_comm->approved ), number_format_i18n( $num_comm->approved ) );
   329 		$text = sprintf( _n( '%s Comment', '%s Comments', $num_comm->approved ), number_format_i18n( $num_comm->approved ) );
   306 		?>
   330 		?>
   307 		<li class="comment-count"><a href="edit-comments.php"><?php echo $text; ?></a></li>
   331 		<li class="comment-count">
       
   332 			<a href="edit-comments.php"><?php echo $text; ?></a>
       
   333 		</li>
   308 		<?php
   334 		<?php
   309 		$moderated_comments_count_i18n = number_format_i18n( $num_comm->moderated );
   335 		$moderated_comments_count_i18n = number_format_i18n( $num_comm->moderated );
   310 		/* translators: %s: Number of comments. */
   336 		/* translators: %s: Number of comments. */
   311 		$text = sprintf( _n( '%s Comment in moderation', '%s Comments in moderation', $num_comm->moderated ), $moderated_comments_count_i18n );
   337 		$text = sprintf( _n( '%s Comment in moderation', '%s Comments in moderation', $num_comm->moderated ), $moderated_comments_count_i18n );
   312 		?>
   338 		?>
   313 		<li class="comment-mod-count
   339 		<li class="comment-mod-count<?php echo ! $num_comm->moderated ? ' hidden' : ''; ?>">
   314 		<?php
   340 			<a href="edit-comments.php?comment_status=moderated" class="comments-in-moderation-text"><?php echo $text; ?></a>
   315 		if ( ! $num_comm->moderated ) {
   341 		</li>
   316 			echo ' hidden';
       
   317 		}
       
   318 		?>
       
   319 		"><a href="edit-comments.php?comment_status=moderated" class="comments-in-moderation-text"><?php echo $text; ?></a></li>
       
   320 		<?php
   342 		<?php
   321 	}
   343 	}
   322 
   344 
   323 	/**
   345 	/**
   324 	 * Filters the array of extra elements to list in the 'At a Glance'
   346 	 * Filters the array of extra elements to list in the 'At a Glance'
   341 	</ul>
   363 	</ul>
   342 	<?php
   364 	<?php
   343 	update_right_now_message();
   365 	update_right_now_message();
   344 
   366 
   345 	// Check if search engines are asked not to index this site.
   367 	// Check if search engines are asked not to index this site.
   346 	if ( ! is_network_admin() && ! is_user_admin() && current_user_can( 'manage_options' ) && '0' == get_option( 'blog_public' ) ) {
   368 	if ( ! is_network_admin() && ! is_user_admin()
       
   369 		&& current_user_can( 'manage_options' ) && ! get_option( 'blog_public' )
       
   370 	) {
   347 
   371 
   348 		/**
   372 		/**
   349 		 * Filters the link title attribute for the 'Search engines discouraged'
   373 		 * Filters the link title attribute for the 'Search engines discouraged'
   350 		 * message displayed in the 'At a Glance' dashboard widget.
   374 		 * message displayed in the 'At a Glance' dashboard widget.
   351 		 *
   375 		 *
   366 		 *
   390 		 *
   367 		 * @since 3.0.0
   391 		 * @since 3.0.0
   368 		 *
   392 		 *
   369 		 * @param string $content Default text.
   393 		 * @param string $content Default text.
   370 		 */
   394 		 */
   371 		$content    = apply_filters( 'privacy_on_link_text', __( 'Search engines discouraged' ) );
   395 		$content = apply_filters( 'privacy_on_link_text', __( 'Search engines discouraged' ) );
       
   396 
   372 		$title_attr = '' === $title ? '' : " title='$title'";
   397 		$title_attr = '' === $title ? '' : " title='$title'";
   373 
   398 
   374 		echo "<p class='search-engines-info'><a href='options-reading.php'$title_attr>$content</a></p>";
   399 		echo "<p class='search-engines-info'><a href='options-reading.php'$title_attr>$content</a></p>";
   375 	}
   400 	}
   376 	?>
   401 	?>
   414 /**
   439 /**
   415  * @since 3.1.0
   440  * @since 3.1.0
   416  */
   441  */
   417 function wp_network_dashboard_right_now() {
   442 function wp_network_dashboard_right_now() {
   418 	$actions = array();
   443 	$actions = array();
       
   444 
   419 	if ( current_user_can( 'create_sites' ) ) {
   445 	if ( current_user_can( 'create_sites' ) ) {
   420 		$actions['create-site'] = '<a href="' . network_admin_url( 'site-new.php' ) . '">' . __( 'Create a New Site' ) . '</a>';
   446 		$actions['create-site'] = '<a href="' . network_admin_url( 'site-new.php' ) . '">' . __( 'Create a New Site' ) . '</a>';
   421 	}
   447 	}
   422 	if ( current_user_can( 'create_users' ) ) {
   448 	if ( current_user_can( 'create_users' ) ) {
   423 		$actions['create-user'] = '<a href="' . network_admin_url( 'user-new.php' ) . '">' . __( 'Create a New User' ) . '</a>';
   449 		$actions['create-user'] = '<a href="' . network_admin_url( 'user-new.php' ) . '">' . __( 'Create a New User' ) . '</a>';
   456 		 * @since MU (3.0.0)
   482 		 * @since MU (3.0.0)
   457 		 */
   483 		 */
   458 		do_action( 'wpmuadminresult' );
   484 		do_action( 'wpmuadminresult' );
   459 	?>
   485 	?>
   460 
   486 
   461 	<form action="<?php echo network_admin_url( 'users.php' ); ?>" method="get">
   487 	<form action="<?php echo esc_url( network_admin_url( 'users.php' ) ); ?>" method="get">
   462 		<p>
   488 		<p>
   463 			<label class="screen-reader-text" for="search-users"><?php _e( 'Search Users' ); ?></label>
   489 			<label class="screen-reader-text" for="search-users"><?php _e( 'Search Users' ); ?></label>
   464 			<input type="search" name="s" value="" size="30" autocomplete="off" id="search-users"/>
   490 			<input type="search" name="s" value="" size="30" autocomplete="off" id="search-users" />
   465 			<?php submit_button( __( 'Search Users' ), '', false, false, array( 'id' => 'submit_users' ) ); ?>
   491 			<?php submit_button( __( 'Search Users' ), '', false, false, array( 'id' => 'submit_users' ) ); ?>
   466 		</p>
   492 		</p>
   467 	</form>
   493 	</form>
   468 
   494 
   469 	<form action="<?php echo network_admin_url( 'sites.php' ); ?>" method="get">
   495 	<form action="<?php echo esc_url( network_admin_url( 'sites.php' ) ); ?>" method="get">
   470 		<p>
   496 		<p>
   471 			<label class="screen-reader-text" for="search-sites"><?php _e( 'Search Sites' ); ?></label>
   497 			<label class="screen-reader-text" for="search-sites"><?php _e( 'Search Sites' ); ?></label>
   472 			<input type="search" name="s" value="" size="30" autocomplete="off" id="search-sites"/>
   498 			<input type="search" name="s" value="" size="30" autocomplete="off" id="search-sites" />
   473 			<?php submit_button( __( 'Search Sites' ), '', false, false, array( 'id' => 'submit_sites' ) ); ?>
   499 			<?php submit_button( __( 'Search Sites' ), '', false, false, array( 'id' => 'submit_sites' ) ); ?>
   474 		</p>
   500 		</p>
   475 	</form>
   501 	</form>
   476 	<?php
   502 	<?php
   477 	/**
   503 	/**
   494  *
   520  *
   495  * @since 3.8.0
   521  * @since 3.8.0
   496  *
   522  *
   497  * @global int $post_ID
   523  * @global int $post_ID
   498  *
   524  *
   499  * @param string $error_msg Optional. Error message. Default false.
   525  * @param string|false $error_msg Optional. Error message. Default false.
   500  */
   526  */
   501 function wp_dashboard_quick_press( $error_msg = false ) {
   527 function wp_dashboard_quick_press( $error_msg = false ) {
   502 	global $post_ID;
   528 	global $post_ID;
   503 
   529 
   504 	if ( ! current_user_can( 'edit_posts' ) ) {
   530 	if ( ! current_user_can( 'edit_posts' ) ) {
   505 		return;
   531 		return;
   506 	}
   532 	}
   507 
   533 
   508 	/* Check if a new auto-draft (= no new post_ID) is needed or if the old can be used */
   534 	// Check if a new auto-draft (= no new post_ID) is needed or if the old can be used.
   509 	$last_post_id = (int) get_user_option( 'dashboard_quick_press_last_post_id' ); // Get the last post_ID.
   535 	$last_post_id = (int) get_user_option( 'dashboard_quick_press_last_post_id' ); // Get the last post_ID.
       
   536 
   510 	if ( $last_post_id ) {
   537 	if ( $last_post_id ) {
   511 		$post = get_post( $last_post_id );
   538 		$post = get_post( $last_post_id );
       
   539 
   512 		if ( empty( $post ) || 'auto-draft' !== $post->post_status ) { // auto-draft doesn't exist anymore.
   540 		if ( empty( $post ) || 'auto-draft' !== $post->post_status ) { // auto-draft doesn't exist anymore.
   513 			$post = get_default_post_to_edit( 'post', true );
   541 			$post = get_default_post_to_edit( 'post', true );
   514 			update_user_option( get_current_user_id(), 'dashboard_quick_press_last_post_id', (int) $post->ID ); // Save post_ID.
   542 			update_user_option( get_current_user_id(), 'dashboard_quick_press_last_post_id', (int) $post->ID ); // Save post_ID.
   515 		} else {
   543 		} else {
   516 			$post->post_title = ''; // Remove the auto draft title.
   544 			$post->post_title = ''; // Remove the auto draft title.
   517 		}
   545 		}
   518 	} else {
   546 	} else {
   519 		$post    = get_default_post_to_edit( 'post', true );
   547 		$post    = get_default_post_to_edit( 'post', true );
   520 		$user_id = get_current_user_id();
   548 		$user_id = get_current_user_id();
       
   549 
   521 		// Don't create an option if this is a super admin who does not belong to this site.
   550 		// Don't create an option if this is a super admin who does not belong to this site.
   522 		if ( in_array( get_current_blog_id(), array_keys( get_blogs_of_user( $user_id ) ), true ) ) {
   551 		if ( in_array( get_current_blog_id(), array_keys( get_blogs_of_user( $user_id ) ), true ) ) {
   523 			update_user_option( $user_id, 'dashboard_quick_press_last_post_id', (int) $post->ID ); // Save post_ID.
   552 			update_user_option( $user_id, 'dashboard_quick_press_last_post_id', (int) $post->ID ); // Save post_ID.
   524 		}
   553 		}
   525 	}
   554 	}
   565 /**
   594 /**
   566  * Show recent drafts of the user on the dashboard.
   595  * Show recent drafts of the user on the dashboard.
   567  *
   596  *
   568  * @since 2.7.0
   597  * @since 2.7.0
   569  *
   598  *
   570  * @param WP_Post[] $drafts Optional. Array of posts to display. Default false.
   599  * @param WP_Post[]|false $drafts Optional. Array of posts to display. Default false.
   571  */
   600  */
   572 function wp_dashboard_recent_drafts( $drafts = false ) {
   601 function wp_dashboard_recent_drafts( $drafts = false ) {
   573 	if ( ! $drafts ) {
   602 	if ( ! $drafts ) {
   574 		$query_args = array(
   603 		$query_args = array(
   575 			'post_type'      => 'post',
   604 			'post_type'      => 'post',
   594 			return;
   623 			return;
   595 		}
   624 		}
   596 	}
   625 	}
   597 
   626 
   598 	echo '<div class="drafts">';
   627 	echo '<div class="drafts">';
       
   628 
   599 	if ( count( $drafts ) > 3 ) {
   629 	if ( count( $drafts ) > 3 ) {
   600 		printf(
   630 		printf(
   601 			'<p class="view-all"><a href="%s">%s</a></p>' . "\n",
   631 			'<p class="view-all"><a href="%s">%s</a></p>' . "\n",
   602 			esc_url( admin_url( 'edit.php?post_status=draft' ) ),
   632 			esc_url( admin_url( 'edit.php?post_status=draft' ) ),
   603 			__( 'View all drafts' )
   633 			__( 'View all drafts' )
   604 		);
   634 		);
   605 	}
   635 	}
   606 	echo '<h2 class="hide-if-no-js">' . __( 'Your Recent Drafts' ) . "</h2>\n<ul>";
   636 
       
   637 	echo '<h2 class="hide-if-no-js">' . __( 'Your Recent Drafts' ) . "</h2>\n";
       
   638 	echo '<ul>';
   607 
   639 
   608 	/* translators: Maximum number of words used in a preview of a draft on the dashboard. */
   640 	/* translators: Maximum number of words used in a preview of a draft on the dashboard. */
   609 	$draft_length = intval( _x( '10', 'draft_length' ) );
   641 	$draft_length = (int) _x( '10', 'draft_length' );
   610 
   642 
   611 	$drafts = array_slice( $drafts, 0, 3 );
   643 	$drafts = array_slice( $drafts, 0, 3 );
   612 	foreach ( $drafts as $draft ) {
   644 	foreach ( $drafts as $draft ) {
   613 		$url   = get_edit_post_link( $draft->ID );
   645 		$url   = get_edit_post_link( $draft->ID );
   614 		$title = _draft_or_post_title( $draft->ID );
   646 		$title = _draft_or_post_title( $draft->ID );
       
   647 
   615 		echo "<li>\n";
   648 		echo "<li>\n";
   616 		printf(
   649 		printf(
   617 			'<div class="draft-title"><a href="%s" aria-label="%s">%s</a><time datetime="%s">%s</time></div>',
   650 			'<div class="draft-title"><a href="%s" aria-label="%s">%s</a><time datetime="%s">%s</time></div>',
   618 			esc_url( $url ),
   651 			esc_url( $url ),
   619 			/* translators: %s: Post title. */
   652 			/* translators: %s: Post title. */
   620 			esc_attr( sprintf( __( 'Edit &#8220;%s&#8221;' ), $title ) ),
   653 			esc_attr( sprintf( __( 'Edit &#8220;%s&#8221;' ), $title ) ),
   621 			esc_html( $title ),
   654 			esc_html( $title ),
   622 			get_the_time( 'c', $draft ),
   655 			get_the_time( 'c', $draft ),
   623 			get_the_time( __( 'F j, Y' ), $draft )
   656 			get_the_time( __( 'F j, Y' ), $draft )
   624 		);
   657 		);
       
   658 
   625 		$the_content = wp_trim_words( $draft->post_content, $draft_length );
   659 		$the_content = wp_trim_words( $draft->post_content, $draft_length );
       
   660 
   626 		if ( $the_content ) {
   661 		if ( $the_content ) {
   627 			echo '<p>' . $the_content . '</p>';
   662 			echo '<p>' . $the_content . '</p>';
   628 		}
   663 		}
   629 		echo "</li>\n";
   664 		echo "</li>\n";
   630 	}
   665 	}
   631 	echo "</ul>\n</div>";
   666 
       
   667 	echo "</ul>\n";
       
   668 	echo '</div>';
   632 }
   669 }
   633 
   670 
   634 /**
   671 /**
   635  * Outputs a row for the Recent Comments widget.
   672  * Outputs a row for the Recent Comments widget.
   636  *
   673  *
   644  */
   681  */
   645 function _wp_dashboard_recent_comments_row( &$comment, $show_date = true ) {
   682 function _wp_dashboard_recent_comments_row( &$comment, $show_date = true ) {
   646 	$GLOBALS['comment'] = clone $comment;
   683 	$GLOBALS['comment'] = clone $comment;
   647 
   684 
   648 	if ( $comment->comment_post_ID > 0 ) {
   685 	if ( $comment->comment_post_ID > 0 ) {
   649 
       
   650 		$comment_post_title = _draft_or_post_title( $comment->comment_post_ID );
   686 		$comment_post_title = _draft_or_post_title( $comment->comment_post_ID );
   651 		$comment_post_url   = get_the_permalink( $comment->comment_post_ID );
   687 		$comment_post_url   = get_the_permalink( $comment->comment_post_ID );
   652 		$comment_post_link  = "<a href='$comment_post_url'>$comment_post_title</a>";
   688 		$comment_post_link  = "<a href='$comment_post_url'>$comment_post_title</a>";
   653 	} else {
   689 	} else {
   654 		$comment_post_link = '';
   690 		$comment_post_link = '';
   926 	$query_args = array(
   962 	$query_args = array(
   927 		'post_type'      => 'post',
   963 		'post_type'      => 'post',
   928 		'post_status'    => $args['status'],
   964 		'post_status'    => $args['status'],
   929 		'orderby'        => 'date',
   965 		'orderby'        => 'date',
   930 		'order'          => $args['order'],
   966 		'order'          => $args['order'],
   931 		'posts_per_page' => intval( $args['max'] ),
   967 		'posts_per_page' => (int) $args['max'],
   932 		'no_found_rows'  => true,
   968 		'no_found_rows'  => true,
   933 		'cache_results'  => false,
   969 		'cache_results'  => false,
   934 		'perm'           => ( 'future' === $args['status'] ) ? 'editable' : 'readable',
   970 		'perm'           => ( 'future' === $args['status'] ) ? 'editable' : 'readable',
   935 	);
   971 	);
   936 
   972 
   940 	 * @since 4.2.0
   976 	 * @since 4.2.0
   941 	 *
   977 	 *
   942 	 * @param array $query_args The arguments passed to WP_Query to produce the list of posts.
   978 	 * @param array $query_args The arguments passed to WP_Query to produce the list of posts.
   943 	 */
   979 	 */
   944 	$query_args = apply_filters( 'dashboard_recent_posts_query_args', $query_args );
   980 	$query_args = apply_filters( 'dashboard_recent_posts_query_args', $query_args );
   945 	$posts      = new WP_Query( $query_args );
   981 
       
   982 	$posts = new WP_Query( $query_args );
   946 
   983 
   947 	if ( $posts->have_posts() ) {
   984 	if ( $posts->have_posts() ) {
   948 
   985 
   949 		echo '<div id="' . $args['id'] . '" class="activity-block">';
   986 		echo '<div id="' . $args['id'] . '" class="activity-block">';
   950 
   987 
   958 
   995 
   959 		while ( $posts->have_posts() ) {
   996 		while ( $posts->have_posts() ) {
   960 			$posts->the_post();
   997 			$posts->the_post();
   961 
   998 
   962 			$time = get_the_time( 'U' );
   999 			$time = get_the_time( 'U' );
   963 			if ( gmdate( 'Y-m-d', $time ) == $today ) {
  1000 
       
  1001 			if ( gmdate( 'Y-m-d', $time ) === $today ) {
   964 				$relative = __( 'Today' );
  1002 				$relative = __( 'Today' );
   965 			} elseif ( gmdate( 'Y-m-d', $time ) == $tomorrow ) {
  1003 			} elseif ( gmdate( 'Y-m-d', $time ) === $tomorrow ) {
   966 				$relative = __( 'Tomorrow' );
  1004 				$relative = __( 'Tomorrow' );
   967 			} elseif ( gmdate( 'Y', $time ) !== $year ) {
  1005 			} elseif ( gmdate( 'Y', $time ) !== $year ) {
   968 				/* translators: Date and time format for recent posts on the dashboard, from a different calendar year, see https://www.php.net/date */
  1006 				/* translators: Date and time format for recent posts on the dashboard, from a different calendar year, see https://www.php.net/manual/datetime.format.php */
   969 				$relative = date_i18n( __( 'M jS Y' ), $time );
  1007 				$relative = date_i18n( __( 'M jS Y' ), $time );
   970 			} else {
  1008 			} else {
   971 				/* translators: Date and time format for recent posts on the dashboard, see https://www.php.net/date */
  1009 				/* translators: Date and time format for recent posts on the dashboard, see https://www.php.net/manual/datetime.format.php */
   972 				$relative = date_i18n( __( 'M jS' ), $time );
  1010 				$relative = date_i18n( __( 'M jS' ), $time );
   973 			}
  1011 			}
   974 
  1012 
   975 			// Use the post edit link for those who can edit, the permalink otherwise.
  1013 			// Use the post edit link for those who can edit, the permalink otherwise.
   976 			$recent_post_link = current_user_can( 'edit_post', get_the_ID() ) ? get_edit_post_link() : get_permalink();
  1014 			$recent_post_link = current_user_can( 'edit_post', get_the_ID() ) ? get_edit_post_link() : get_permalink();
  1013 
  1051 
  1014 	$comments_query = array(
  1052 	$comments_query = array(
  1015 		'number' => $total_items * 5,
  1053 		'number' => $total_items * 5,
  1016 		'offset' => 0,
  1054 		'offset' => 0,
  1017 	);
  1055 	);
       
  1056 
  1018 	if ( ! current_user_can( 'edit_posts' ) ) {
  1057 	if ( ! current_user_can( 'edit_posts' ) ) {
  1019 		$comments_query['status'] = 'approve';
  1058 		$comments_query['status'] = 'approve';
  1020 	}
  1059 	}
  1021 
  1060 
  1022 	while ( count( $comments ) < $total_items && $possible = get_comments( $comments_query ) ) {
  1061 	while ( count( $comments ) < $total_items && $possible = get_comments( $comments_query ) ) {
  1023 		if ( ! is_array( $possible ) ) {
  1062 		if ( ! is_array( $possible ) ) {
  1024 			break;
  1063 			break;
  1025 		}
  1064 		}
       
  1065 
  1026 		foreach ( $possible as $comment ) {
  1066 		foreach ( $possible as $comment ) {
  1027 			if ( ! current_user_can( 'read_post', $comment->comment_post_ID ) ) {
  1067 			if ( ! current_user_can( 'read_post', $comment->comment_post_ID ) ) {
  1028 				continue;
  1068 				continue;
  1029 			}
  1069 			}
       
  1070 
  1030 			$comments[] = $comment;
  1071 			$comments[] = $comment;
  1031 			if ( count( $comments ) == $total_items ) {
  1072 
       
  1073 			if ( count( $comments ) === $total_items ) {
  1032 				break 2;
  1074 				break 2;
  1033 			}
  1075 			}
  1034 		}
  1076 		}
       
  1077 
  1035 		$comments_query['offset'] += $comments_query['number'];
  1078 		$comments_query['offset'] += $comments_query['number'];
  1036 		$comments_query['number']  = $total_items * 10;
  1079 		$comments_query['number']  = $total_items * 10;
  1037 	}
  1080 	}
  1038 
  1081 
  1039 	if ( $comments ) {
  1082 	if ( $comments ) {
  1040 		echo '<div id="latest-comments" class="activity-block">';
  1083 		echo '<div id="latest-comments" class="activity-block table-view-list">';
  1041 		echo '<h3>' . __( 'Recent Comments' ) . '</h3>';
  1084 		echo '<h3>' . __( 'Recent Comments' ) . '</h3>';
  1042 
  1085 
  1043 		echo '<ul id="the-comment-list" data-wp-lists="list:comment">';
  1086 		echo '<ul id="the-comment-list" data-wp-lists="list:comment">';
  1044 		foreach ( $comments as $comment ) {
  1087 		foreach ( $comments as $comment ) {
  1045 			_wp_dashboard_recent_comments_row( $comment );
  1088 			_wp_dashboard_recent_comments_row( $comment );
  1097 	$loading    = '<p class="widget-loading hide-if-no-js">' . __( 'Loading&hellip;' ) . '</p><div class="hide-if-js notice notice-error inline"><p>' . __( 'This widget requires JavaScript.' ) . '</p></div>';
  1140 	$loading    = '<p class="widget-loading hide-if-no-js">' . __( 'Loading&hellip;' ) . '</p><div class="hide-if-js notice notice-error inline"><p>' . __( 'This widget requires JavaScript.' ) . '</p></div>';
  1098 	$doing_ajax = wp_doing_ajax();
  1141 	$doing_ajax = wp_doing_ajax();
  1099 
  1142 
  1100 	if ( empty( $check_urls ) ) {
  1143 	if ( empty( $check_urls ) ) {
  1101 		$widgets = get_option( 'dashboard_widget_options' );
  1144 		$widgets = get_option( 'dashboard_widget_options' );
       
  1145 
  1102 		if ( empty( $widgets[ $widget_id ]['url'] ) && ! $doing_ajax ) {
  1146 		if ( empty( $widgets[ $widget_id ]['url'] ) && ! $doing_ajax ) {
  1103 			echo $loading;
  1147 			echo $loading;
  1104 			return false;
  1148 			return false;
  1105 		}
  1149 		}
       
  1150 
  1106 		$check_urls = array( $widgets[ $widget_id ]['url'] );
  1151 		$check_urls = array( $widgets[ $widget_id ]['url'] );
  1107 	}
  1152 	}
  1108 
  1153 
  1109 	$locale    = get_user_locale();
  1154 	$locale    = get_user_locale();
  1110 	$cache_key = 'dash_v2_' . md5( $widget_id . '_' . $locale );
  1155 	$cache_key = 'dash_v2_' . md5( $widget_id . '_' . $locale );
  1111 	$output    = get_transient( $cache_key );
  1156 	$output    = get_transient( $cache_key );
       
  1157 
  1112 	if ( false !== $output ) {
  1158 	if ( false !== $output ) {
  1113 		echo $output;
  1159 		echo $output;
  1114 		return true;
  1160 		return true;
  1115 	}
  1161 	}
  1116 
  1162 
  1137 /**
  1183 /**
  1138  * Calls widget control callback.
  1184  * Calls widget control callback.
  1139  *
  1185  *
  1140  * @since 2.5.0
  1186  * @since 2.5.0
  1141  *
  1187  *
  1142  * @global array $wp_dashboard_control_callbacks
  1188  * @global callable[] $wp_dashboard_control_callbacks
  1143  *
  1189  *
  1144  * @param int $widget_control_id Registered Widget ID.
  1190  * @param int|false $widget_control_id Optional. Registered widget ID. Default false.
  1145  */
  1191  */
  1146 function wp_dashboard_trigger_widget_control( $widget_control_id = false ) {
  1192 function wp_dashboard_trigger_widget_control( $widget_control_id = false ) {
  1147 	global $wp_dashboard_control_callbacks;
  1193 	global $wp_dashboard_control_callbacks;
  1148 
  1194 
  1149 	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 ] ) ) {
  1195 	if ( is_scalar( $widget_control_id ) && $widget_control_id
       
  1196 		&& isset( $wp_dashboard_control_callbacks[ $widget_control_id ] )
       
  1197 		&& is_callable( $wp_dashboard_control_callbacks[ $widget_control_id ] )
       
  1198 	) {
  1150 		call_user_func(
  1199 		call_user_func(
  1151 			$wp_dashboard_control_callbacks[ $widget_control_id ],
  1200 			$wp_dashboard_control_callbacks[ $widget_control_id ],
  1152 			'',
  1201 			'',
  1153 			array(
  1202 			array(
  1154 				'id'       => $widget_control_id,
  1203 				'id'       => $widget_control_id,
  1169  * @param string $widget_id
  1218  * @param string $widget_id
  1170  * @param array  $form_inputs
  1219  * @param array  $form_inputs
  1171  */
  1220  */
  1172 function wp_dashboard_rss_control( $widget_id, $form_inputs = array() ) {
  1221 function wp_dashboard_rss_control( $widget_id, $form_inputs = array() ) {
  1173 	$widget_options = get_option( 'dashboard_widget_options' );
  1222 	$widget_options = get_option( 'dashboard_widget_options' );
       
  1223 
  1174 	if ( ! $widget_options ) {
  1224 	if ( ! $widget_options ) {
  1175 		$widget_options = array();
  1225 		$widget_options = array();
  1176 	}
  1226 	}
  1177 
  1227 
  1178 	if ( ! isset( $widget_options[ $widget_id ] ) ) {
  1228 	if ( ! isset( $widget_options[ $widget_id ] ) ) {
  1197 				$widget_options[ $widget_id ]['title'] = htmlentities( strip_tags( $rss->get_title() ) );
  1247 				$widget_options[ $widget_id ]['title'] = htmlentities( strip_tags( $rss->get_title() ) );
  1198 				$rss->__destruct();
  1248 				$rss->__destruct();
  1199 				unset( $rss );
  1249 				unset( $rss );
  1200 			}
  1250 			}
  1201 		}
  1251 		}
       
  1252 
  1202 		update_option( 'dashboard_widget_options', $widget_options );
  1253 		update_option( 'dashboard_widget_options', $widget_options );
       
  1254 
  1203 		$locale    = get_user_locale();
  1255 		$locale    = get_user_locale();
  1204 		$cache_key = 'dash_v2_' . md5( $widget_id . '_' . $locale );
  1256 		$cache_key = 'dash_v2_' . md5( $widget_id . '_' . $locale );
  1205 		delete_transient( $cache_key );
  1257 		delete_transient( $cache_key );
  1206 	}
  1258 	}
  1207 
  1259 
  1377 						<span class="event-city">{{ event.location.location }}</span>
  1429 						<span class="event-city">{{ event.location.location }}</span>
  1378 					</div>
  1430 					</div>
  1379 				</div>
  1431 				</div>
  1380 
  1432 
  1381 				<div class="event-date-time">
  1433 				<div class="event-date-time">
  1382 					<span class="event-date">{{ event.formatted_date }}</span>
  1434 					<span class="event-date">{{ event.user_formatted_date }}</span>
  1383 					<# if ( 'meetup' === event.type ) { #>
  1435 					<# if ( 'meetup' === event.type ) { #>
  1384 						<span class="event-time">{{ event.formatted_time }}</span>
  1436 						<span class="event-time">
       
  1437 							{{ event.user_formatted_time }} {{ event.timeZoneAbbreviation }}
       
  1438 						</span>
  1385 					<# } #>
  1439 					<# } #>
  1386 				</div>
  1440 				</div>
  1387 			</li>
  1441 			</li>
  1388 		<# } ) #>
  1442 		<# } ) #>
       
  1443 
       
  1444 		<# if ( data.events.length <= 2 ) { #>
       
  1445 			<li class="event-none">
       
  1446 				<?php
       
  1447 				printf(
       
  1448 					/* translators: %s: Localized meetup organization documentation URL. */
       
  1449 					__( 'Want more events? <a href="%s">Help organize the next one</a>!' ),
       
  1450 					__( 'https://make.wordpress.org/community/organize-event-landing-page/' )
       
  1451 				);
       
  1452 				?>
       
  1453 			</li>
       
  1454 		<# } #>
       
  1455 
  1389 	</script>
  1456 	</script>
  1390 
  1457 
  1391 	<script id="tmpl-community-events-no-upcoming-events" type="text/template">
  1458 	<script id="tmpl-community-events-no-upcoming-events" type="text/template">
  1392 		<li class="event-none">
  1459 		<li class="event-none">
  1393 			<# if ( data.location.description ) { #>
  1460 			<# if ( data.location.description ) { #>
  1448 			 * @since 2.3.0
  1515 			 * @since 2.3.0
  1449 			 *
  1516 			 *
  1450 			 * @param string $title Title attribute for the widget's primary link.
  1517 			 * @param string $title Title attribute for the widget's primary link.
  1451 			 */
  1518 			 */
  1452 			'title'        => apply_filters( 'dashboard_primary_title', __( 'WordPress Blog' ) ),
  1519 			'title'        => apply_filters( 'dashboard_primary_title', __( 'WordPress Blog' ) ),
  1453 			'items'        => 1,
  1520 			'items'        => 2,
  1454 			'show_summary' => 0,
  1521 			'show_summary' => 0,
  1455 			'show_author'  => 0,
  1522 			'show_author'  => 0,
  1456 			'show_date'    => 0,
  1523 			'show_date'    => 0,
  1457 		),
  1524 		),
  1458 		'planet' => array(
  1525 		'planet' => array(
  1524  *
  1591  *
  1525  * Runs on the {@see 'activity_box_end'} hook in wp_dashboard_right_now().
  1592  * Runs on the {@see 'activity_box_end'} hook in wp_dashboard_right_now().
  1526  *
  1593  *
  1527  * @since 3.0.0
  1594  * @since 3.0.0
  1528  *
  1595  *
  1529  * @return bool|null True if not multisite, user can't upload files, or the space check option is disabled.
  1596  * @return true|void True if not multisite, user can't upload files, or the space check option is disabled.
  1530  */
  1597  */
  1531 function wp_dashboard_quota() {
  1598 function wp_dashboard_quota() {
  1532 	if ( ! is_multisite() || ! current_user_can( 'upload_files' ) || get_site_option( 'upload_space_check_disabled' ) ) {
  1599 	if ( ! is_multisite() || ! current_user_can( 'upload_files' )
       
  1600 		|| get_site_option( 'upload_space_check_disabled' )
       
  1601 	) {
  1533 		return true;
  1602 		return true;
  1534 	}
  1603 	}
  1535 
  1604 
  1536 	$quota = get_space_allowed();
  1605 	$quota = get_space_allowed();
  1537 	$used  = get_space_used();
  1606 	$used  = get_space_used();
  1539 	if ( $used > $quota ) {
  1608 	if ( $used > $quota ) {
  1540 		$percentused = '100';
  1609 		$percentused = '100';
  1541 	} else {
  1610 	} else {
  1542 		$percentused = ( $used / $quota ) * 100;
  1611 		$percentused = ( $used / $quota ) * 100;
  1543 	}
  1612 	}
       
  1613 
  1544 	$used_class  = ( $percentused >= 70 ) ? ' warning' : '';
  1614 	$used_class  = ( $percentused >= 70 ) ? ' warning' : '';
  1545 	$used        = round( $used, 2 );
  1615 	$used        = round( $used, 2 );
  1546 	$percentused = number_format( $percentused );
  1616 	$percentused = number_format( $percentused );
  1547 
  1617 
  1548 	?>
  1618 	?>
  1586 
  1656 
  1587 /**
  1657 /**
  1588  * Displays the browser update nag.
  1658  * Displays the browser update nag.
  1589  *
  1659  *
  1590  * @since 3.2.0
  1660  * @since 3.2.0
       
  1661  * @since 5.8.0 Added a special message for Internet Explorer users.
       
  1662  *
       
  1663  * @global bool $is_IE
  1591  */
  1664  */
  1592 function wp_dashboard_browser_nag() {
  1665 function wp_dashboard_browser_nag() {
       
  1666 	global $is_IE;
       
  1667 
  1593 	$notice   = '';
  1668 	$notice   = '';
  1594 	$response = wp_check_browser_version();
  1669 	$response = wp_check_browser_version();
  1595 
  1670 
  1596 	if ( $response ) {
  1671 	if ( $response ) {
  1597 		if ( $response['insecure'] ) {
  1672 		if ( $is_IE ) {
       
  1673 			$msg = __( 'Internet Explorer does not give you the best WordPress experience. Switch to Microsoft Edge, or another more modern browser to get the most from your site.' );
       
  1674 		} elseif ( $response['insecure'] ) {
  1598 			$msg = sprintf(
  1675 			$msg = sprintf(
  1599 				/* translators: %s: Browser name and link. */
  1676 				/* translators: %s: Browser name and link. */
  1600 				__( "It looks like you're using an insecure version of %s. Using an outdated browser makes your computer unsafe. For the best WordPress experience, please update your browser." ),
  1677 				__( "It looks like you're using an insecure version of %s. Using an outdated browser makes your computer unsafe. For the best WordPress experience, please update your browser." ),
  1601 				sprintf( '<a href="%s">%s</a>', esc_url( $response['update_url'] ), esc_html( $response['name'] ) )
  1678 				sprintf( '<a href="%s">%s</a>', esc_url( $response['update_url'] ), esc_html( $response['name'] ) )
  1602 			);
  1679 			);
  1610 
  1687 
  1611 		$browser_nag_class = '';
  1688 		$browser_nag_class = '';
  1612 		if ( ! empty( $response['img_src'] ) ) {
  1689 		if ( ! empty( $response['img_src'] ) ) {
  1613 			$img_src = ( is_ssl() && ! empty( $response['img_src_ssl'] ) ) ? $response['img_src_ssl'] : $response['img_src'];
  1690 			$img_src = ( is_ssl() && ! empty( $response['img_src_ssl'] ) ) ? $response['img_src_ssl'] : $response['img_src'];
  1614 
  1691 
  1615 			$notice           .= '<div class="alignright browser-icon"><a href="' . esc_attr( $response['update_url'] ) . '"><img src="' . esc_attr( $img_src ) . '" alt="" /></a></div>';
  1692 			$notice           .= '<div class="alignright browser-icon"><img src="' . esc_attr( $img_src ) . '" alt="" /></div>';
  1616 			$browser_nag_class = ' has-browser-icon';
  1693 			$browser_nag_class = ' has-browser-icon';
  1617 		}
  1694 		}
  1618 		$notice .= "<p class='browser-update-nag{$browser_nag_class}'>{$msg}</p>";
  1695 		$notice .= "<p class='browser-update-nag{$browser_nag_class}'>{$msg}</p>";
  1619 
  1696 
  1620 		$browsehappy = 'https://browsehappy.com/';
  1697 		$browsehappy = 'https://browsehappy.com/';
  1621 		$locale      = get_user_locale();
  1698 		$locale      = get_user_locale();
  1622 		if ( 'en_US' !== $locale ) {
  1699 		if ( 'en_US' !== $locale ) {
  1623 			$browsehappy = add_query_arg( 'locale', $locale, $browsehappy );
  1700 			$browsehappy = add_query_arg( 'locale', $locale, $browsehappy );
  1624 		}
  1701 		}
  1625 
  1702 
  1626 		$notice .= '<p>' . sprintf(
  1703 		if ( $is_IE ) {
  1627 			/* translators: 1: Browser update URL, 2: Browser name, 3: Browse Happy URL. */
  1704 			$msg_browsehappy = sprintf(
  1628 			__( '<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>' ),
  1705 				/* translators: %s: Browse Happy URL. */
  1629 			esc_attr( $response['update_url'] ),
  1706 				__( 'Learn how to <a href="%s" class="update-browser-link">browse happy</a>' ),
  1630 			esc_html( $response['name'] ),
  1707 				esc_url( $browsehappy )
  1631 			esc_url( $browsehappy )
  1708 			);
  1632 		) . '</p>';
  1709 		} else {
       
  1710 			$msg_browsehappy = sprintf(
       
  1711 				/* translators: 1: Browser update URL, 2: Browser name, 3: Browse Happy URL. */
       
  1712 				__( '<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>' ),
       
  1713 				esc_attr( $response['update_url'] ),
       
  1714 				esc_html( $response['name'] ),
       
  1715 				esc_url( $browsehappy )
       
  1716 			);
       
  1717 		}
       
  1718 
       
  1719 		$notice .= '<p>' . $msg_browsehappy . '</p>';
  1633 		$notice .= '<p class="hide-if-no-js"><a href="" class="dismiss" aria-label="' . esc_attr__( 'Dismiss the browser warning panel' ) . '">' . __( 'Dismiss' ) . '</a></p>';
  1720 		$notice .= '<p class="hide-if-no-js"><a href="" class="dismiss" aria-label="' . esc_attr__( 'Dismiss the browser warning panel' ) . '">' . __( 'Dismiss' ) . '</a></p>';
  1634 		$notice .= '<div class="clear"></div>';
  1721 		$notice .= '<div class="clear"></div>';
  1635 	}
  1722 	}
  1636 
  1723 
  1637 	/**
  1724 	/**
  1666 /**
  1753 /**
  1667  * Checks if the user needs a browser update.
  1754  * Checks if the user needs a browser update.
  1668  *
  1755  *
  1669  * @since 3.2.0
  1756  * @since 3.2.0
  1670  *
  1757  *
  1671  * @return array|bool Array of browser data on success, false on failure.
  1758  * @return array|false Array of browser data on success, false on failure.
  1672  */
  1759  */
  1673 function wp_check_browser_version() {
  1760 function wp_check_browser_version() {
  1674 	if ( empty( $_SERVER['HTTP_USER_AGENT'] ) ) {
  1761 	if ( empty( $_SERVER['HTTP_USER_AGENT'] ) ) {
  1675 		return false;
  1762 		return false;
  1676 	}
  1763 	}
  1677 
  1764 
  1678 	$key = md5( $_SERVER['HTTP_USER_AGENT'] );
  1765 	$key = md5( $_SERVER['HTTP_USER_AGENT'] );
  1679 
  1766 
  1680 	$response = get_site_transient( 'browser_' . $key );
  1767 	$response = get_site_transient( 'browser_' . $key );
       
  1768 
  1681 	if ( false === $response ) {
  1769 	if ( false === $response ) {
  1682 		// Include an unmodified $wp_version.
  1770 		// Include an unmodified $wp_version.
  1683 		require ABSPATH . WPINC . '/version.php';
  1771 		require ABSPATH . WPINC . '/version.php';
  1684 
  1772 
  1685 		$url     = 'http://api.wordpress.org/core/browse-happy/1.1/';
  1773 		$url     = 'http://api.wordpress.org/core/browse-happy/1.1/';
  1692 			$url = set_url_scheme( $url, 'https' );
  1780 			$url = set_url_scheme( $url, 'https' );
  1693 		}
  1781 		}
  1694 
  1782 
  1695 		$response = wp_remote_post( $url, $options );
  1783 		$response = wp_remote_post( $url, $options );
  1696 
  1784 
  1697 		if ( is_wp_error( $response ) || 200 != wp_remote_retrieve_response_code( $response ) ) {
  1785 		if ( is_wp_error( $response ) || 200 !== wp_remote_retrieve_response_code( $response ) ) {
  1698 			return false;
  1786 			return false;
  1699 		}
  1787 		}
  1700 
  1788 
  1701 		/**
  1789 		/**
  1702 		 * Response should be an array with:
  1790 		 * Response should be an array with:
  1733 	if ( ! $response ) {
  1821 	if ( ! $response ) {
  1734 		return;
  1822 		return;
  1735 	}
  1823 	}
  1736 
  1824 
  1737 	if ( isset( $response['is_secure'] ) && ! $response['is_secure'] ) {
  1825 	if ( isset( $response['is_secure'] ) && ! $response['is_secure'] ) {
  1738 		$msg = __( 'WordPress has detected that your site is running on an insecure version of PHP.' );
  1826 		$msg = sprintf(
       
  1827 			/* translators: %s: The server PHP version. */
       
  1828 			__( 'Your site is running an insecure version of PHP (%s), which should be updated.' ),
       
  1829 			PHP_VERSION
       
  1830 		);
  1739 	} else {
  1831 	} else {
  1740 		$msg = __( 'WordPress has detected that your site is running on an outdated version of PHP.' );
  1832 		$msg = sprintf(
  1741 	}
  1833 			/* translators: %s: The server PHP version. */
  1742 
  1834 			__( 'Your site is running an outdated version of PHP (%s), which should be updated.' ),
       
  1835 			PHP_VERSION
       
  1836 		);
       
  1837 	}
  1743 	?>
  1838 	?>
  1744 	<p><?php echo $msg; ?></p>
  1839 	<p><?php echo $msg; ?></p>
  1745 
  1840 
  1746 	<h3><?php _e( 'What is PHP and how does it affect my site?' ); ?></h3>
  1841 	<h3><?php _e( 'What is PHP and how does it affect my site?' ); ?></h3>
  1747 	<p><?php _e( 'PHP is the programming language we use to build and maintain WordPress. Newer versions of PHP are both faster and more secure, so updating will have a positive effect on your site&#8217;s performance.' ); ?></p>
  1842 	<p>
       
  1843 		<?php
       
  1844 		printf(
       
  1845 			/* translators: %s: The minimum recommended PHP version. */
       
  1846 			__( 'PHP is the programming language used to build and maintain WordPress. Newer versions of PHP are created with increased performance in mind, so you may see a positive effect on your site&#8217;s performance. The minimum recommended version of PHP is %s.' ),
       
  1847 			$response ? $response['recommended_version'] : ''
       
  1848 		);
       
  1849 		?>
       
  1850 	</p>
  1748 
  1851 
  1749 	<p class="button-container">
  1852 	<p class="button-container">
  1750 		<?php
  1853 		<?php
  1751 		printf(
  1854 		printf(
  1752 			'<a class="button button-primary" href="%1$s" target="_blank" rel="noopener noreferrer">%2$s <span class="screen-reader-text">%3$s</span><span aria-hidden="true" class="dashicons dashicons-external"></span></a>',
  1855 			'<a class="button button-primary" href="%1$s" target="_blank" rel="noopener">%2$s <span class="screen-reader-text">%3$s</span><span aria-hidden="true" class="dashicons dashicons-external"></span></a>',
  1753 			esc_url( wp_get_update_php_url() ),
  1856 			esc_url( wp_get_update_php_url() ),
  1754 			__( 'Learn more about updating PHP' ),
  1857 			__( 'Learn more about updating PHP' ),
  1755 			/* translators: Accessibility text. */
  1858 			/* translators: Accessibility text. */
  1756 			__( '(opens in a new tab)' )
  1859 			__( '(opens in a new tab)' )
  1757 		);
  1860 		);
  1803 		);
  1906 		);
  1804 	}
  1907 	}
  1805 
  1908 
  1806 	$issues_total = $issue_counts['recommended'] + $issue_counts['critical'];
  1909 	$issues_total = $issue_counts['recommended'] + $issue_counts['critical'];
  1807 	?>
  1910 	?>
  1808 	<div class="health-check-title-section site-health-progress-wrapper loading hide-if-no-js">
  1911 	<div class="health-check-widget">
  1809 		<div class="site-health-progress">
  1912 		<div class="health-check-widget-title-section site-health-progress-wrapper loading hide-if-no-js">
  1810 			<svg role="img" aria-hidden="true" focusable="false" width="100%" height="100%" viewBox="0 0 200 200" version="1.1" xmlns="http://www.w3.org/2000/svg">
  1913 			<div class="site-health-progress">
  1811 				<circle r="90" cx="100" cy="100" fill="transparent" stroke-dasharray="565.48" stroke-dashoffset="0"></circle>
  1914 				<svg role="img" aria-hidden="true" focusable="false" width="100%" height="100%" viewBox="0 0 200 200" version="1.1" xmlns="http://www.w3.org/2000/svg">
  1812 				<circle id="bar" r="90" cx="100" cy="100" fill="transparent" stroke-dasharray="565.48" stroke-dashoffset="0"></circle>
  1915 					<circle r="90" cx="100" cy="100" fill="transparent" stroke-dasharray="565.48" stroke-dashoffset="0"></circle>
  1813 			</svg>
  1916 					<circle id="bar" r="90" cx="100" cy="100" fill="transparent" stroke-dasharray="565.48" stroke-dashoffset="0"></circle>
       
  1917 				</svg>
       
  1918 			</div>
       
  1919 			<div class="site-health-progress-label">
       
  1920 				<?php if ( false === $get_issues ) : ?>
       
  1921 					<?php _e( 'No information yet&hellip;' ); ?>
       
  1922 				<?php else : ?>
       
  1923 					<?php _e( 'Results are still loading&hellip;' ); ?>
       
  1924 				<?php endif; ?>
       
  1925 			</div>
  1814 		</div>
  1926 		</div>
  1815 		<div class="site-health-progress-label">
  1927 
       
  1928 		<div class="site-health-details">
  1816 			<?php if ( false === $get_issues ) : ?>
  1929 			<?php if ( false === $get_issues ) : ?>
  1817 				<?php _e( 'No information yet&hellip;' ); ?>
  1930 				<p>
       
  1931 					<?php
       
  1932 					printf(
       
  1933 						/* translators: %s: URL to Site Health screen. */
       
  1934 						__( 'Site health checks will automatically run periodically to gather information about your site. You can also <a href="%s">visit the Site Health screen</a> to gather information about your site now.' ),
       
  1935 						esc_url( admin_url( 'site-health.php' ) )
       
  1936 					);
       
  1937 					?>
       
  1938 				</p>
  1818 			<?php else : ?>
  1939 			<?php else : ?>
  1819 				<?php _e( 'Results are still loading&hellip;' ); ?>
  1940 				<p>
       
  1941 					<?php if ( $issues_total <= 0 ) : ?>
       
  1942 						<?php _e( 'Great job! Your site currently passes all site health checks.' ); ?>
       
  1943 					<?php elseif ( 1 === (int) $issue_counts['critical'] ) : ?>
       
  1944 						<?php _e( 'Your site has a critical issue that should be addressed as soon as possible to improve its performance and security.' ); ?>
       
  1945 					<?php elseif ( $issue_counts['critical'] > 1 ) : ?>
       
  1946 						<?php _e( 'Your site has critical issues that should be addressed as soon as possible to improve its performance and security.' ); ?>
       
  1947 					<?php elseif ( 1 === (int) $issue_counts['recommended'] ) : ?>
       
  1948 						<?php _e( 'Your site&#8217;s health is looking good, but there is still one thing you can do to improve its performance and security.' ); ?>
       
  1949 					<?php else : ?>
       
  1950 						<?php _e( 'Your site&#8217;s health is looking good, but there are still some things you can do to improve its performance and security.' ); ?>
       
  1951 					<?php endif; ?>
       
  1952 				</p>
       
  1953 			<?php endif; ?>
       
  1954 
       
  1955 			<?php if ( $issues_total > 0 && false !== $get_issues ) : ?>
       
  1956 				<p>
       
  1957 					<?php
       
  1958 					printf(
       
  1959 						/* translators: 1: Number of issues. 2: URL to Site Health screen. */
       
  1960 						_n(
       
  1961 							'Take a look at the <strong>%1$d item</strong> on the <a href="%2$s">Site Health screen</a>.',
       
  1962 							'Take a look at the <strong>%1$d items</strong> on the <a href="%2$s">Site Health screen</a>.',
       
  1963 							$issues_total
       
  1964 						),
       
  1965 						$issues_total,
       
  1966 						esc_url( admin_url( 'site-health.php' ) )
       
  1967 					);
       
  1968 					?>
       
  1969 				</p>
  1820 			<?php endif; ?>
  1970 			<?php endif; ?>
  1821 		</div>
  1971 		</div>
  1822 	</div>
  1972 	</div>
  1823 
       
  1824 	<?php if ( false === $get_issues ) : ?>
       
  1825 		<p>
       
  1826 			<?php
       
  1827 			printf(
       
  1828 				/* translators: %s: URL to Site Health screen. */
       
  1829 				__( 'Site health checks will automatically run periodically to gather information about your site. You can also <a href="%s">visit the Site Health screen</a> to gather information about your site now.' ),
       
  1830 				esc_url( admin_url( 'site-health.php' ) )
       
  1831 			);
       
  1832 			?>
       
  1833 		</p>
       
  1834 	<?php else : ?>
       
  1835 		<p>
       
  1836 			<?php if ( $issue_counts['critical'] > 0 ) : ?>
       
  1837 				<?php _e( 'Your site has critical issues that should be addressed as soon as possible to improve its performance and security.' ); ?>
       
  1838 			<?php elseif ( $issues_total <= 0 ) : ?>
       
  1839 				<?php _e( 'Great job! Your site currently passes all site health checks.' ); ?>
       
  1840 			<?php else : ?>
       
  1841 				<?php _e( 'Your site&#8217;s health is looking good, but there are still some things you can do to improve its performance and security.' ); ?>
       
  1842 			<?php endif; ?>
       
  1843 		</p>
       
  1844 	<?php endif; ?>
       
  1845 
       
  1846 	<?php if ( $issues_total > 0 && false !== $get_issues ) : ?>
       
  1847 		<p>
       
  1848 			<?php
       
  1849 			printf(
       
  1850 				/* translators: 1: Number of issues. 2: URL to Site Health screen. */
       
  1851 				_n(
       
  1852 					'Take a look at the <strong>%1$d item</strong> on the <a href="%2$s">Site Health screen</a>.',
       
  1853 					'Take a look at the <strong>%1$d items</strong> on the <a href="%2$s">Site Health screen</a>.',
       
  1854 					$issues_total
       
  1855 				),
       
  1856 				$issues_total,
       
  1857 				esc_url( admin_url( 'site-health.php' ) )
       
  1858 			);
       
  1859 			?>
       
  1860 		</p>
       
  1861 	<?php endif; ?>
       
  1862 
  1973 
  1863 	<?php
  1974 	<?php
  1864 }
  1975 }
  1865 
  1976 
  1866 /**
  1977 /**
  1884 	<div class="welcome-panel-column">
  1995 	<div class="welcome-panel-column">
  1885 		<?php if ( current_user_can( 'customize' ) ) : ?>
  1996 		<?php if ( current_user_can( 'customize' ) ) : ?>
  1886 			<h3><?php _e( 'Get Started' ); ?></h3>
  1997 			<h3><?php _e( 'Get Started' ); ?></h3>
  1887 			<a class="button button-primary button-hero load-customize hide-if-no-customize" href="<?php echo wp_customize_url(); ?>"><?php _e( 'Customize Your Site' ); ?></a>
  1998 			<a class="button button-primary button-hero load-customize hide-if-no-customize" href="<?php echo wp_customize_url(); ?>"><?php _e( 'Customize Your Site' ); ?></a>
  1888 		<?php endif; ?>
  1999 		<?php endif; ?>
  1889 		<a class="button button-primary button-hero hide-if-customize" href="<?php echo admin_url( 'themes.php' ); ?>"><?php _e( 'Customize Your Site' ); ?></a>
  2000 		<a class="button button-primary button-hero hide-if-customize" href="<?php echo esc_url( admin_url( 'themes.php' ) ); ?>"><?php _e( 'Customize Your Site' ); ?></a>
  1890 		<?php if ( current_user_can( 'install_themes' ) || ( current_user_can( 'switch_themes' ) && count( wp_get_themes( array( 'allowed' => true ) ) ) > 1 ) ) : ?>
  2001 		<?php if ( current_user_can( 'install_themes' ) || ( current_user_can( 'switch_themes' ) && count( wp_get_themes( array( 'allowed' => true ) ) ) > 1 ) ) : ?>
  1891 			<?php $themes_link = current_user_can( 'customize' ) ? add_query_arg( 'autofocus[panel]', 'themes', admin_url( 'customize.php' ) ) : admin_url( 'themes.php' ); ?>
  2002 			<?php $themes_link = current_user_can( 'customize' ) ? add_query_arg( 'autofocus[panel]', 'themes', admin_url( 'customize.php' ) ) : admin_url( 'themes.php' ); ?>
  1892 			<p class="hide-if-no-customize">
  2003 			<p class="hide-if-no-customize">
  1893 				<?php
  2004 				<?php
  1894 					/* translators: %s: URL to Themes panel in Customizer or Themes screen. */
  2005 					/* translators: %s: URL to Themes panel in Customizer or Themes screen. */