[ Index ]

WordPress Cross Reference

title

Body

[close]

/wp-admin/includes/ -> dashboard.php (source)

   1  <?php
   2  /**
   3   * WordPress Dashboard Widget Administration Screen API
   4   *
   5   * @package WordPress
   6   * @subpackage Administration
   7   */
   8  
   9  /**
  10   * Registers dashboard widgets.
  11   *
  12   * Handles POST data, sets up filters.
  13   *
  14   * @since 2.5.0
  15   */
  16  function wp_dashboard_setup() {
  17      global $wp_registered_widgets, $wp_registered_widget_controls, $wp_dashboard_control_callbacks;
  18      $wp_dashboard_control_callbacks = array();
  19      $screen = get_current_screen();
  20  
  21      $update = false;
  22      $widget_options = get_option( 'dashboard_widget_options' );
  23      if ( !$widget_options || !is_array($widget_options) )
  24          $widget_options = array();
  25  
  26      /* Register Widgets and Controls */
  27  
  28      $response = wp_check_browser_version();
  29  
  30      if ( $response && $response['upgrade'] ) {
  31          add_filter( 'postbox_classes_dashboard_dashboard_browser_nag', 'dashboard_browser_nag_class' );
  32          if ( $response['insecure'] )
  33              wp_add_dashboard_widget( 'dashboard_browser_nag', __( 'You are using an insecure browser!' ), 'wp_dashboard_browser_nag' );
  34          else
  35              wp_add_dashboard_widget( 'dashboard_browser_nag', __( 'Your browser is out of date!' ), 'wp_dashboard_browser_nag' );
  36      }
  37  
  38      // Right Now
  39      if ( is_blog_admin() && current_user_can('edit_posts') )
  40          wp_add_dashboard_widget( 'dashboard_right_now', __( 'At a Glance' ), 'wp_dashboard_right_now' );
  41  
  42      if ( is_network_admin() )
  43          wp_add_dashboard_widget( 'network_dashboard_right_now', __( 'Right Now' ), 'wp_network_dashboard_right_now' );
  44  
  45      // Activity Widget
  46      if ( is_blog_admin() ) {
  47          wp_add_dashboard_widget( 'dashboard_activity', __( 'Activity' ), 'wp_dashboard_site_activity' );
  48      }
  49  
  50      // QuickPress Widget
  51      if ( is_blog_admin() && current_user_can( 'edit_posts' ) ) {
  52          $quick_draft_title = sprintf( '<span class="hide-if-no-js">%1$s</span> <span class="hide-if-js">%2$s</span>', __( 'Quick Draft' ), __( 'Drafts' ) );
  53          wp_add_dashboard_widget( 'dashboard_quick_press', $quick_draft_title, 'wp_dashboard_quick_press' );
  54      }
  55  
  56      // WordPress News
  57      wp_add_dashboard_widget( 'dashboard_primary', __( 'WordPress News' ), 'wp_dashboard_primary' );
  58  
  59      // Hook to register new widgets
  60      // Filter widget order
  61      if ( is_network_admin() ) {
  62          do_action( 'wp_network_dashboard_setup' );
  63          $dashboard_widgets = apply_filters( 'wp_network_dashboard_widgets', array() );
  64      } elseif ( is_user_admin() ) {
  65          do_action( 'wp_user_dashboard_setup' );
  66          $dashboard_widgets = apply_filters( 'wp_user_dashboard_widgets', array() );
  67      } else {
  68          do_action( 'wp_dashboard_setup' );
  69          $dashboard_widgets = apply_filters( 'wp_dashboard_widgets', array() );
  70      }
  71  
  72      foreach ( $dashboard_widgets as $widget_id ) {
  73          $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>';
  74          wp_add_dashboard_widget( $widget_id, $name, $wp_registered_widgets[$widget_id]['callback'], $wp_registered_widget_controls[$widget_id]['callback'] );
  75      }
  76  
  77      if ( 'POST' == $_SERVER['REQUEST_METHOD'] && isset($_POST['widget_id']) ) {
  78          check_admin_referer( 'edit-dashboard-widget_' . $_POST['widget_id'], 'dashboard-widget-nonce' );
  79          ob_start(); // hack - but the same hack wp-admin/widgets.php uses
  80          wp_dashboard_trigger_widget_control( $_POST['widget_id'] );
  81          ob_end_clean();
  82          wp_redirect( remove_query_arg( 'edit' ) );
  83          exit;
  84      }
  85  
  86      if ( $update )
  87          update_option( 'dashboard_widget_options', $widget_options );
  88  
  89      /** This action is documented in wp-admin/edit-form-advanced.php */
  90      do_action('do_meta_boxes', $screen->id, 'normal', '');
  91      /** This action is documented in wp-admin/edit-form-advanced.php */
  92      do_action('do_meta_boxes', $screen->id, 'side', '');
  93  }
  94  
  95  function wp_add_dashboard_widget( $widget_id, $widget_name, $callback, $control_callback = null, $callback_args = null ) {
  96      $screen = get_current_screen();
  97      global $wp_dashboard_control_callbacks;
  98  
  99      if ( $control_callback && current_user_can( 'edit_dashboard' ) && is_callable( $control_callback ) ) {
 100          $wp_dashboard_control_callbacks[$widget_id] = $control_callback;
 101          if ( isset( $_GET['edit'] ) && $widget_id == $_GET['edit'] ) {
 102              list($url) = explode( '#', add_query_arg( 'edit', false ), 2 );
 103              $widget_name .= ' <span class="postbox-title-action"><a href="' . esc_url( $url ) . '">' . __( 'Cancel' ) . '</a></span>';
 104              $callback = '_wp_dashboard_control_callback';
 105          } else {
 106              list($url) = explode( '#', add_query_arg( 'edit', $widget_id ), 2 );
 107              $widget_name .= ' <span class="postbox-title-action"><a href="' . esc_url( "$url#$widget_id" ) . '" class="edit-box open-box">' . __( 'Configure' ) . '</a></span>';
 108          }
 109      }
 110  
 111      $side_widgets = array( 'dashboard_quick_press', 'dashboard_primary' );
 112  
 113      $location = 'normal';
 114      if ( in_array($widget_id, $side_widgets) )
 115          $location = 'side';
 116  
 117      $priority = 'core';
 118      if ( 'dashboard_browser_nag' === $widget_id )
 119          $priority = 'high';
 120  
 121      add_meta_box( $widget_id, $widget_name, $callback, $screen, $location, $priority, $callback_args );
 122  }
 123  
 124  function _wp_dashboard_control_callback( $dashboard, $meta_box ) {
 125      echo '<form action="" method="post" class="dashboard-widget-control-form">';
 126      wp_dashboard_trigger_widget_control( $meta_box['id'] );
 127      wp_nonce_field( 'edit-dashboard-widget_' . $meta_box['id'], 'dashboard-widget-nonce' );
 128      echo '<input type="hidden" name="widget_id" value="' . esc_attr($meta_box['id']) . '" />';
 129      submit_button( __('Submit') );
 130      echo '</form>';
 131  }
 132  
 133  /**
 134   * Displays the dashboard.
 135   *
 136   * @since 2.5.0
 137   */
 138  function wp_dashboard() {
 139      $screen = get_current_screen();
 140      $columns = absint( $screen->get_columns() );
 141      $columns_css = '';
 142      if ( $columns ) {
 143          $columns_css = " columns-$columns";
 144      }
 145  
 146  ?>
 147  <div id="dashboard-widgets" class="metabox-holder<?php echo $columns_css; ?>">
 148      <div id='postbox-container-1' class='postbox-container'>
 149      <?php do_meta_boxes( $screen->id, 'normal', '' ); ?>
 150      </div>
 151      <div id='postbox-container-2' class='postbox-container'>
 152      <?php do_meta_boxes( $screen->id, 'side', '' ); ?>
 153      </div>
 154      <div id='postbox-container-3' class='postbox-container'>
 155      <?php do_meta_boxes( $screen->id, 'column3', '' ); ?>
 156      </div>
 157      <div id='postbox-container-4' class='postbox-container'>
 158      <?php do_meta_boxes( $screen->id, 'column4', '' ); ?>
 159      </div>
 160  </div>
 161  
 162  <?php
 163      wp_nonce_field( 'closedpostboxes', 'closedpostboxesnonce', false );
 164      wp_nonce_field( 'meta-box-order', 'meta-box-order-nonce', false );
 165  
 166  }
 167  
 168  /* Dashboard Widgets */
 169  
 170  /**
 171   * Dashboard widget that displays some basic stats about the site.
 172   *
 173   * Formerly 'Right Now'. A streamlined 'At a Glance' as of 3.8.
 174   *
 175   * @since 2.7.0
 176   */
 177  function wp_dashboard_right_now() {
 178      $theme = wp_get_theme();
 179      if ( current_user_can( 'switch_themes' ) )
 180          $theme_name = sprintf( '<a href="themes.php">%1$s</a>', $theme->display('Name') );
 181      else
 182          $theme_name = $theme->display('Name');
 183  ?>
 184      <div class="main">
 185      <ul>
 186      <?php
 187      // Posts and Pages
 188      foreach ( array( 'post', 'page' ) as $post_type ) {
 189          $num_posts = wp_count_posts( $post_type );
 190          if ( $num_posts && $num_posts->publish ) {
 191              if ( 'post' == $post_type ) {
 192                  $text = _n( '%s Post', '%s Posts', $num_posts->publish );
 193              } else {
 194                  $text = _n( '%s Page', '%s Pages', $num_posts->publish );
 195              }
 196              $text = sprintf( $text, number_format_i18n( $num_posts->publish ) );
 197              $post_type_object = get_post_type_object( $post_type );
 198              if ( $post_type_object && current_user_can( $post_type_object->cap->edit_posts ) ) {
 199                  printf( '<li class="%1$s-count"><a href="edit.php?post_type=%1$s">%2$s</a></li>', $post_type, $text );
 200              } else {
 201                  printf( '<li class="%1$s-count"><span>%2$s</span></li>', $post_type, $text );
 202              }
 203  
 204          }
 205      }
 206      // Comments
 207      $num_comm = wp_count_comments();
 208      if ( $num_comm && $num_comm->total_comments ) {
 209          $text = sprintf( _n( '%s Comment', '%s Comments', $num_comm->total_comments ), number_format_i18n( $num_comm->total_comments ) );
 210          ?>
 211          <li class="comment-count"><a href="edit-comments.php"><?php echo $text; ?></a></li>
 212          <?php
 213          if ( $num_comm->moderated ) {
 214              /* translators: Number of comments in moderation */
 215              $text = sprintf( _nx( '%s in moderation', '%s in moderation', $num_comm->moderated, 'comments' ), number_format_i18n( $num_comm->moderated ) );
 216              ?>
 217              <li class="comment-mod-count"><a href="edit-comments.php?comment_status=moderated"><?php echo $text; ?></a></li>
 218              <?php
 219          }
 220      }
 221  
 222      /**
 223       * Include additional elements in the 'At a Glance' dashboard widget.
 224       * This widget was previously 'Right Now'.
 225       *
 226       * @since 3.8.0
 227       * @param array $items Array of items.
 228       */
 229      $elements = apply_filters( 'dashboard_glance_items', array() );
 230      if ( $elements ) {
 231          echo '<li>' . implode( "</li>\n<li>", $elements ) . "</li>\n";
 232      }
 233  
 234      ?>
 235      </ul>
 236      <p><?php printf( __( 'WordPress %1$s running %2$s theme.' ), get_bloginfo( 'version', 'display' ), $theme_name ); ?></p>
 237      <?php
 238  
 239      // Check if search engines are asked not to index this site.
 240      if ( ! is_network_admin() && ! is_user_admin() && current_user_can( 'manage_options' ) && '1' != get_option( 'blog_public' ) ) {
 241  
 242          /**
 243           * Filter the title attribute for the link displayed in Site Content metabox when search engines are discouraged from indexing the site.
 244           *
 245           * @since 3.0.0
 246           *
 247           * @param string Default attribute text.
 248           */
 249          $title = apply_filters( 'privacy_on_link_title', __( 'Your site is asking search engines not to index its content' ) );
 250  
 251          /**
 252           * Filter the text for the link displayed in Site Content metabox when search engines are discouraged from indexing the site.
 253           *
 254           * @since 3.0.0
 255           *
 256           * @param string Default text.
 257           */
 258          $content = apply_filters( 'privacy_on_link_text' , __( 'Search Engines Discouraged' ) );
 259  
 260          echo "<p><a href='options-reading.php' title='$title'>$content</a></p>";
 261      }
 262      ?>
 263      </div>
 264      <?php
 265      // activity_box_end has a core action, but only prints content when multisite.
 266      // Using an output buffer is the only way to really check if anything's displayed here.
 267      ob_start();
 268      do_action( 'rightnow_end' );
 269      do_action( 'activity_box_end' );
 270      $actions = ob_get_clean();
 271  
 272      if ( !empty( $actions ) ) : ?>
 273      <div class="sub">
 274          <?php echo $actions; ?>
 275      </div>
 276      <?php endif;
 277  }
 278  
 279  function wp_network_dashboard_right_now() {
 280      $actions = array();
 281      if ( current_user_can('create_sites') )
 282          $actions['create-site'] = '<a href="' . network_admin_url('site-new.php') . '">' . __( 'Create a New Site' ) . '</a>';
 283      if ( current_user_can('create_users') )
 284          $actions['create-user'] = '<a href="' . network_admin_url('user-new.php') . '">' . __( 'Create a New User' ) . '</a>';
 285  
 286      $c_users = get_user_count();
 287      $c_blogs = get_blog_count();
 288  
 289      $user_text = sprintf( _n( '%s user', '%s users', $c_users ), number_format_i18n( $c_users ) );
 290      $blog_text = sprintf( _n( '%s site', '%s sites', $c_blogs ), number_format_i18n( $c_blogs ) );
 291  
 292      $sentence = sprintf( __( 'You have %1$s and %2$s.' ), $blog_text, $user_text );
 293  
 294      if ( $actions ) {
 295          echo '<ul class="subsubsub">';
 296          foreach ( $actions as $class => $action ) {
 297               $actions[ $class ] = "\t<li class='$class'>$action";
 298          }
 299          echo implode( " |</li>\n", $actions ) . "</li>\n";
 300          echo '</ul>';
 301      }
 302  ?>
 303      <br class="clear" />
 304  
 305      <p class="youhave"><?php echo $sentence; ?></p>
 306      <?php do_action( 'wpmuadminresult', '' ); ?>
 307  
 308      <form action="<?php echo network_admin_url('users.php'); ?>" method="get">
 309          <p>
 310              <input type="search" name="s" value="" size="30" autocomplete="off" />
 311              <?php submit_button( __( 'Search Users' ), 'button', 'submit', false, array( 'id' => 'submit_users' ) ); ?>
 312          </p>
 313      </form>
 314  
 315      <form action="<?php echo network_admin_url('sites.php'); ?>" method="get">
 316          <p>
 317              <input type="search" name="s" value="" size="30" autocomplete="off" />
 318              <?php submit_button( __( 'Search Sites' ), 'button', 'submit', false, array( 'id' => 'submit_sites' ) ); ?>
 319          </p>
 320      </form>
 321  <?php
 322      do_action( 'mu_rightnow_end' );
 323      do_action( 'mu_activity_box_end' );
 324  }
 325  
 326  /**
 327   * The Quick Draft widget display and creation of drafts.
 328   *
 329   * @since 3.8.0
 330   *
 331   * @param string $error_msg Optional. Error message. Default false.
 332   */
 333  function wp_dashboard_quick_press( $error_msg = false ) {
 334      global $post_ID;
 335  
 336      /* Check if a new auto-draft (= no new post_ID) is needed or if the old can be used */
 337      $last_post_id = (int) get_user_option( 'dashboard_quick_press_last_post_id' ); // Get the last post_ID
 338      if ( $last_post_id ) {
 339          $post = get_post( $last_post_id );
 340          if ( empty( $post ) || $post->post_status != 'auto-draft' ) { // auto-draft doesn't exists anymore
 341              $post = get_default_post_to_edit( 'post', true );
 342              update_user_option( get_current_user_id(), 'dashboard_quick_press_last_post_id', (int) $post->ID ); // Save post_ID
 343          } else {
 344              $post->post_title = ''; // Remove the auto draft title
 345          }
 346      } else {
 347          $post = get_default_post_to_edit( 'post' , true);
 348          $user_id = get_current_user_id();
 349          // Don't create an option if this is a super admin who does not belong to this site.
 350          if ( ! ( is_super_admin( $user_id ) && ! in_array( get_current_blog_id(), array_keys( get_blogs_of_user( $user_id ) ) ) ) )
 351              update_user_option( $user_id, 'dashboard_quick_press_last_post_id', (int) $post->ID ); // Save post_ID
 352      }
 353  
 354      $post_ID = (int) $post->ID;
 355  ?>
 356  
 357      <form name="post" action="<?php echo esc_url( admin_url( 'post.php' ) ); ?>" method="post" id="quick-press" class="initial-form hide-if-no-js">
 358  
 359          <?php if ( $error_msg ) : ?>
 360          <div class="error"><?php echo $error_msg; ?></div>
 361          <?php endif; ?>
 362  
 363          <div class="input-text-wrap" id="title-wrap">
 364              <label class="screen-reader-text prompt" for="title" id="title-prompt-text"><?php echo apply_filters( 'enter_title_here', __( 'Title' ), $post ); ?></label>
 365              <input type="text" name="post_title" id="title" autocomplete="off" />
 366          </div>
 367  
 368          <div class="textarea-wrap" id="description-wrap">
 369              <label class="screen-reader-text prompt" for="content" id="content-prompt-text"><?php _e( 'What&#8217;s on your mind?' ); ?></label>
 370              <textarea name="content" id="content" class="mceEditor" rows="3" cols="15"></textarea>
 371          </div>
 372  
 373          <p class="submit">
 374              <input type="hidden" name="action" id="quickpost-action" value="post-quickdraft-save" />
 375              <input type="hidden" name="post_ID" value="<?php echo $post_ID; ?>" />
 376              <input type="hidden" name="post_type" value="post" />
 377              <?php wp_nonce_field( 'add-post' ); ?>
 378              <?php submit_button( __( 'Save Draft' ), 'primary', 'save', false, array( 'id' => 'save-post' ) ); ?>
 379              <br class="clear" />
 380          </p>
 381  
 382      </form>
 383      <?php
 384      wp_dashboard_recent_drafts();
 385  }
 386  
 387  /**
 388   * Show recent drafts of the user on the dashboard.
 389   *
 390   * @since 2.7.0
 391   */
 392  function wp_dashboard_recent_drafts( $drafts = false ) {
 393      if ( ! $drafts ) {
 394          $query_args = array(
 395              'post_type'      => 'post',
 396              'post_status'    => 'draft',
 397              'author'         => get_current_user_id(),
 398              'posts_per_page' => 4,
 399              'orderby'        => 'modified',
 400              'order'          => 'DESC'
 401          );
 402          $drafts = get_posts( $query_args );
 403          if ( ! $drafts ) {
 404              return;
 405           }
 406       }
 407  
 408      echo '<div class="drafts">';
 409      if ( count( $drafts ) > 3 ) {
 410          echo '<p class="view-all"><a href="' . esc_url( admin_url( 'edit.php?post_status=draft' ) ) . '">' . _x( 'View all', 'drafts' ) . "</a></p>\n";
 411       }
 412      echo '<h4 class="hide-if-no-js">' . __( 'Drafts' ) . "</h4>\n<ul>";
 413  
 414      $drafts = array_slice( $drafts, 0, 3 );
 415      foreach ( $drafts as $draft ) {
 416          $url = get_edit_post_link( $draft->ID );
 417          $title = _draft_or_post_title( $draft->ID );
 418          echo "<li>\n";
 419          echo '<div class="draft-title"><a href="' . esc_url( $url ) . '" title="' . esc_attr( sprintf( __( 'Edit &#8220;%s&#8221;' ), $title ) ) . '">' . esc_html( $title ) . '</a>';
 420          echo '<time datetime="' . get_the_time( 'c', $draft ) . '">' . get_the_time( get_option( 'date_format' ), $draft ) . '</time></div>';
 421          if ( $the_content = wp_trim_words( $draft->post_content, 10 ) ) {
 422              echo '<p>' . $the_content . '</p>';
 423           }
 424          echo "</li>\n";
 425       }
 426      echo "</ul>\n</div>";
 427  }
 428  
 429  function _wp_dashboard_recent_comments_row( &$comment, $show_date = true ) {
 430      $GLOBALS['comment'] =& $comment;
 431  
 432      $comment_post_url = get_edit_post_link( $comment->comment_post_ID );
 433      $comment_post_title = strip_tags(get_the_title( $comment->comment_post_ID ));
 434      $comment_post_link = "<a href='$comment_post_url'>$comment_post_title</a>";
 435      $comment_link = '<a class="comment-link" href="' . esc_url(get_comment_link()) . '">#</a>';
 436  
 437      $actions_string = '';
 438      if ( current_user_can( 'edit_comment', $comment->comment_ID ) ) {
 439          // preorder it: Approve | Reply | Edit | Spam | Trash
 440          $actions = array(
 441              'approve' => '', 'unapprove' => '',
 442              'reply' => '',
 443              'edit' => '',
 444              'spam' => '',
 445              'trash' => '', 'delete' => ''
 446          );
 447  
 448          $del_nonce = esc_html( '_wpnonce=' . wp_create_nonce( "delete-comment_$comment->comment_ID" ) );
 449          $approve_nonce = esc_html( '_wpnonce=' . wp_create_nonce( "approve-comment_$comment->comment_ID" ) );
 450  
 451          $approve_url = esc_url( "comment.php?action=approvecomment&p=$comment->comment_post_ID&c=$comment->comment_ID&$approve_nonce" );
 452          $unapprove_url = esc_url( "comment.php?action=unapprovecomment&p=$comment->comment_post_ID&c=$comment->comment_ID&$approve_nonce" );
 453          $spam_url = esc_url( "comment.php?action=spamcomment&p=$comment->comment_post_ID&c=$comment->comment_ID&$del_nonce" );
 454          $trash_url = esc_url( "comment.php?action=trashcomment&p=$comment->comment_post_ID&c=$comment->comment_ID&$del_nonce" );
 455          $delete_url = esc_url( "comment.php?action=deletecomment&p=$comment->comment_post_ID&c=$comment->comment_ID&$del_nonce" );
 456  
 457          $actions['approve'] = "<a href='$approve_url' data-wp-lists='dim:the-comment-list:comment-$comment->comment_ID:unapproved:e7e7d3:e7e7d3:new=approved' class='vim-a' title='" . esc_attr__( 'Approve this comment' ) . "'>" . __( 'Approve' ) . '</a>';
 458          $actions['unapprove'] = "<a href='$unapprove_url' data-wp-lists='dim:the-comment-list:comment-$comment->comment_ID:unapproved:e7e7d3:e7e7d3:new=unapproved' class='vim-u' title='" . esc_attr__( 'Unapprove this comment' ) . "'>" . __( 'Unapprove' ) . '</a>';
 459          $actions['edit'] = "<a href='comment.php?action=editcomment&amp;c={$comment->comment_ID}' title='" . esc_attr__('Edit comment') . "'>". __('Edit') . '</a>';
 460          $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>';
 461          $actions['spam'] = "<a href='$spam_url' data-wp-lists='delete:the-comment-list:comment-$comment->comment_ID::spam=1' class='vim-s vim-destructive' title='" . esc_attr__( 'Mark this comment as spam' ) . "'>" . /* translators: mark as spam link */ _x( 'Spam', 'verb' ) . '</a>';
 462          if ( !EMPTY_TRASH_DAYS )
 463              $actions['delete'] = "<a href='$delete_url' data-wp-lists='delete:the-comment-list:comment-$comment->comment_ID::trash=1' class='delete vim-d vim-destructive'>" . __('Delete Permanently') . '</a>';
 464          else
 465              $actions['trash'] = "<a href='$trash_url' data-wp-lists='delete:the-comment-list:comment-$comment->comment_ID::trash=1' class='delete vim-d vim-destructive' title='" . esc_attr__( 'Move this comment to the trash' ) . "'>" . _x('Trash', 'verb') . '</a>';
 466  
 467          $actions = apply_filters( 'comment_row_actions', array_filter($actions), $comment );
 468  
 469          $i = 0;
 470          foreach ( $actions as $action => $link ) {
 471              ++$i;
 472              ( ( ('approve' == $action || 'unapprove' == $action) && 2 === $i ) || 1 === $i ) ? $sep = '' : $sep = ' | ';
 473  
 474              // Reply and quickedit need a hide-if-no-js span
 475              if ( 'reply' == $action || 'quickedit' == $action )
 476                  $action .= ' hide-if-no-js';
 477  
 478              $actions_string .= "<span class='$action'>$sep$link</span>";
 479          }
 480      }
 481  
 482  ?>
 483  
 484          <div id="comment-<?php echo $comment->comment_ID; ?>" <?php comment_class( array( 'comment-item', wp_get_comment_status($comment->comment_ID) ) ); ?>>
 485              <?php if ( !$comment->comment_type || 'comment' == $comment->comment_type ) : ?>
 486  
 487              <?php echo get_avatar( $comment, 50, 'mystery' ); ?>
 488  
 489              <div class="dashboard-comment-wrap">
 490              <h4 class="comment-meta">
 491                  <?php printf( /* translators: 1: comment author, 2: post link, 3: notification if the comment is pending */__( 'From %1$s on %2$s%3$s' ),
 492                      '<cite class="comment-author">' . get_comment_author_link() . '</cite>', $comment_post_link.' '.$comment_link, ' <span class="approve">' . __( '[Pending]' ) . '</span>' ); ?>
 493              </h4>
 494  
 495              <?php
 496              else :
 497                  switch ( $comment->comment_type ) :
 498                  case 'pingback' :
 499                      $type = __( 'Pingback' );
 500                      break;
 501                  case 'trackback' :
 502                      $type = __( 'Trackback' );
 503                      break;
 504                  default :
 505                      $type = ucwords( $comment->comment_type );
 506                  endswitch;
 507                  $type = esc_html( $type );
 508              ?>
 509              <div class="dashboard-comment-wrap">
 510              <?php /* translators: %1$s is type of comment, %2$s is link to the post */ ?>
 511              <h4 class="comment-meta"><?php printf( _x( '%1$s on %2$s', 'dashboard' ), "<strong>$type</strong>", $comment_post_link." ".$comment_link ); ?></h4>
 512              <p class="comment-author"><?php comment_author_link(); ?></p>
 513  
 514              <?php endif; // comment_type ?>
 515              <blockquote><p><?php comment_excerpt(); ?></p></blockquote>
 516              <p class="row-actions"><?php echo $actions_string; ?></p>
 517              </div>
 518          </div>
 519  <?php
 520  }
 521  
 522  /**
 523   * Callback function for Activity widget.
 524   *
 525   * @since 3.8.0
 526   */
 527  function wp_dashboard_site_activity() {
 528  
 529      echo '<div id="activity-widget">';
 530  
 531      $future_posts = wp_dashboard_recent_posts( array(
 532          'display' => 2,
 533          'max'     => 5,
 534          'status'  => 'future',
 535          'order'   => 'ASC',
 536          'title'   => __( 'Publishing Soon' ),
 537          'id'      => 'future-posts',
 538      ) );
 539      $recent_posts = wp_dashboard_recent_posts( array(
 540          'display' => 2,
 541          'max'     => 5,
 542          'status'  => 'publish',
 543          'order'   => 'DESC',
 544          'title'   => __( 'Recently Published' ),
 545          'id'      => 'published-posts',
 546      ) );
 547  
 548      $recent_comments = wp_dashboard_recent_comments();
 549  
 550      if ( !$future_posts && !$recent_posts && !$recent_comments ) {
 551          echo '<div class="no-activity">';
 552          echo '<p class="smiley"></p>';
 553          echo '<p>' . __( 'No activity yet!' ) . '</p>';
 554          echo '</div>';
 555      }
 556  
 557      echo '</div>';
 558  }
 559  
 560  /**
 561   * Generates Publishing Soon and Recently Published sections.
 562   *
 563   * @since 3.8.0
 564   *
 565   * @param array $args {
 566   *     An array of query and display arguments.
 567   *
 568   *     @type int    $display Number of posts to display.
 569   *     @type int    $max     Maximum number of posts to query.
 570   *     @type string $status  Post status.
 571   *     @type string $order   Designates ascending ('ASC') or descending ('DESC') order.
 572   *     @type string $title   Section title.
 573   *     @type string $id      The container id.
 574   * }
 575   * @return bool False if no posts were found. True otherwise.
 576   */
 577  function wp_dashboard_recent_posts( $args ) {
 578      $query_args = array(
 579          'post_type'      => 'post',
 580          'post_status'    => $args['status'],
 581          'orderby'        => 'date',
 582          'order'          => $args['order'],
 583          'posts_per_page' => intval( $args['max'] ),
 584          'no_found_rows'  => true,
 585          'cache_results'  => false
 586      );
 587      $posts = new WP_Query( $query_args );
 588  
 589      if ( $posts->have_posts() ) {
 590  
 591          echo '<div id="' . $args['id'] . '" class="activity-block">';
 592  
 593          if ( $posts->post_count > $args['display'] ) {
 594              echo '<small class="show-more hide-if-no-js"><a href="#">' . sprintf( __( 'See %s more&hellip;'), $posts->post_count - intval( $args['display'] ) ) . '</a></small>';
 595          }
 596  
 597          echo '<h4>' . $args['title'] . '</h4>';
 598  
 599          echo '<ul>';
 600  
 601          $i = 0;
 602          $today    = date( 'Y-m-d', current_time( 'timestamp' ) );
 603          $tomorrow = date( 'Y-m-d', strtotime( '+1 day', current_time( 'timestamp' ) ) );
 604  
 605          while ( $posts->have_posts() ) {
 606              $posts->the_post();
 607  
 608              $time = get_the_time( 'U' );
 609              if ( date( 'Y-m-d', $time ) == $today ) {
 610                  $relative = __( 'Today' );
 611              } elseif ( date( 'Y-m-d', $time ) == $tomorrow ) {
 612                  $relative = __( 'Tomorrow' );
 613              } else {
 614                  /* translators: date and time format for recent posts on the dashboard, see http://php.net/date */
 615                  $relative = date_i18n( __( 'M jS' ), $time );
 616              }
 617  
 618               $text = sprintf(
 619                  /* translators: 1: relative date, 2: time, 4: post title */
 620                   __( '<span>%1$s, %2$s</span> <a href="%3$s">%4$s</a>' ),
 621                    $relative,
 622                    get_the_time(),
 623                    get_edit_post_link(),
 624                    _draft_or_post_title()
 625                );
 626  
 627               $hidden = $i >= $args['display'] ? ' class="hidden"' : '';
 628               echo "<li{$hidden}>$text</li>";
 629              $i++;
 630          }
 631  
 632          echo '</ul>';
 633          echo '</div>';
 634  
 635      } else {
 636          return false;
 637      }
 638  
 639      wp_reset_postdata();
 640  
 641      return true;
 642  }
 643  
 644  /**
 645   * Show Comments section.
 646   *
 647   * @since 3.8.0
 648   *
 649   * @param int $total_items Optional. Number of comments to query. Default 5.
 650   * @return bool False if no comments were found. True otherwise.
 651   */
 652  function wp_dashboard_recent_comments( $total_items = 5 ) {
 653      global $wpdb;
 654  
 655      // Select all comment types and filter out spam later for better query performance.
 656      $comments = array();
 657      $start = 0;
 658  
 659      $comments_query = array(
 660          'number' => $total_items * 5,
 661          'offset' => 0
 662      );
 663      if ( ! current_user_can( 'edit_posts' ) )
 664          $comments_query['status'] = 'approve';
 665  
 666      while ( count( $comments ) < $total_items && $possible = get_comments( $comments_query ) ) {
 667          foreach ( $possible as $comment ) {
 668              if ( ! current_user_can( 'read_post', $comment->comment_post_ID ) )
 669                  continue;
 670              $comments[] = $comment;
 671              if ( count( $comments ) == $total_items )
 672                  break 2;
 673          }
 674          $comments_query['offset'] += $comments_query['number'];
 675          $comments_query['number'] = $total_items * 10;
 676      }
 677  
 678  
 679  
 680      if ( $comments ) {
 681          echo '<div id="latest-comments" class="activity-block">';
 682          echo '<h4>' . __( 'Comments' ) . '</h4>';
 683  
 684          echo '<div id="the-comment-list" data-wp-lists="list:comment">';
 685          foreach ( $comments as $comment )
 686              _wp_dashboard_recent_comments_row( $comment );
 687          echo '</div>';
 688  
 689          if ( current_user_can('edit_posts') )
 690              _get_list_table('WP_Comments_List_Table')->views();
 691  
 692          wp_comment_reply( -1, false, 'dashboard', false );
 693          wp_comment_trashnotice();
 694  
 695          echo '</div>';
 696      } else {
 697          return false;
 698      }
 699      return true;
 700  }
 701  
 702  /**
 703   * Display generic dashboard RSS widget feed.
 704   *
 705   * @since 2.5.0
 706   *
 707   * @param string $widget_id
 708   */
 709  function wp_dashboard_rss_output( $widget_id ) {
 710      $widgets = get_option( 'dashboard_widget_options' );
 711      echo '<div class="rss-widget">';
 712      wp_widget_rss_output( $widgets[ $widget_id ] );
 713      echo "</div>";
 714  }
 715  
 716  /**
 717   * Checks to see if all of the feed url in $check_urls are cached.
 718   *
 719   * If $check_urls is empty, look for the rss feed url found in the dashboard
 720   * widget options of $widget_id. If cached, call $callback, a function that
 721   * echoes out output for this widget. If not cache, echo a "Loading..." stub
 722   * which is later replaced by AJAX call (see top of /wp-admin/index.php)
 723   *
 724   * @since 2.5.0
 725   *
 726   * @param string $widget_id
 727   * @param callback $callback
 728   * @param array $check_urls RSS feeds
 729   * @return bool False on failure. True on success.
 730   */
 731  function wp_dashboard_cached_rss_widget( $widget_id, $callback, $check_urls = array() ) {
 732      $loading = '<p class="widget-loading hide-if-no-js">' . __( 'Loading&#8230;' ) . '</p><p class="hide-if-js">' . __( 'This widget requires JavaScript.' ) . '</p>';
 733      $doing_ajax = ( defined('DOING_AJAX') && DOING_AJAX );
 734  
 735      if ( empty($check_urls) ) {
 736          $widgets = get_option( 'dashboard_widget_options' );
 737          if ( empty($widgets[$widget_id]['url']) && ! $doing_ajax ) {
 738              echo $loading;
 739              return false;
 740          }
 741          $check_urls = array( $widgets[$widget_id]['url'] );
 742      }
 743  
 744      $cache_key = 'dash_' . md5( $widget_id );
 745      if ( false !== ( $output = get_transient( $cache_key ) ) ) {
 746          echo $output;
 747          return true;
 748      }
 749  
 750      if ( ! $doing_ajax ) {
 751          echo $loading;
 752          return false;
 753      }
 754  
 755      if ( $callback && is_callable( $callback ) ) {
 756          $args = array_slice( func_get_args(), 2 );
 757          array_unshift( $args, $widget_id );
 758          ob_start();
 759          call_user_func_array( $callback, $args );
 760          set_transient( $cache_key, ob_get_flush(), 12 * HOUR_IN_SECONDS ); // Default lifetime in cache of 12 hours (same as the feeds)
 761      }
 762  
 763      return true;
 764  }
 765  
 766  /* Dashboard Widgets Controls */
 767  
 768  // Calls widget_control callback
 769  /**
 770   * Calls widget control callback.
 771   *
 772   * @since 2.5.0
 773   *
 774   * @param int $widget_control_id Registered Widget ID.
 775   */
 776  function wp_dashboard_trigger_widget_control( $widget_control_id = false ) {
 777      global $wp_dashboard_control_callbacks;
 778  
 779      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]) ) {
 780          call_user_func( $wp_dashboard_control_callbacks[$widget_control_id], '', array( 'id' => $widget_control_id, 'callback' => $wp_dashboard_control_callbacks[$widget_control_id] ) );
 781      }
 782  }
 783  
 784  /**
 785   * The RSS dashboard widget control.
 786   *
 787   * Sets up $args to be used as input to wp_widget_rss_form(). Handles POST data
 788   * from RSS-type widgets.
 789   *
 790   * @since 2.5.0
 791   *
 792   * @param string $widget_id
 793   * @param array $form_inputs
 794   */
 795  function wp_dashboard_rss_control( $widget_id, $form_inputs = array() ) {
 796      if ( !$widget_options = get_option( 'dashboard_widget_options' ) )
 797          $widget_options = array();
 798  
 799      if ( !isset($widget_options[$widget_id]) )
 800          $widget_options[$widget_id] = array();
 801  
 802      $number = 1; // Hack to use wp_widget_rss_form()
 803      $widget_options[$widget_id]['number'] = $number;
 804  
 805      if ( 'POST' == $_SERVER['REQUEST_METHOD'] && isset($_POST['widget-rss'][$number]) ) {
 806          $_POST['widget-rss'][$number] = wp_unslash( $_POST['widget-rss'][$number] );
 807          $widget_options[$widget_id] = wp_widget_rss_process( $_POST['widget-rss'][$number] );
 808          $widget_options[$widget_id]['number'] = $number;
 809          // title is optional. If black, fill it if possible
 810          if ( !$widget_options[$widget_id]['title'] && isset($_POST['widget-rss'][$number]['title']) ) {
 811              $rss = fetch_feed($widget_options[$widget_id]['url']);
 812              if ( is_wp_error($rss) ) {
 813                  $widget_options[$widget_id]['title'] = htmlentities(__('Unknown Feed'));
 814              } else {
 815                  $widget_options[$widget_id]['title'] = htmlentities(strip_tags($rss->get_title()));
 816                  $rss->__destruct();
 817                  unset($rss);
 818              }
 819          }
 820          update_option( 'dashboard_widget_options', $widget_options );
 821          $cache_key = 'dash_' . md5( $widget_id );
 822          delete_transient( $cache_key );
 823      }
 824  
 825      wp_widget_rss_form( $widget_options[$widget_id], $form_inputs );
 826  }
 827  
 828  /**
 829   * WordPress News dashboard widget.
 830   *
 831   * @since 2.7.0
 832   */
 833  function wp_dashboard_primary() {
 834      $feeds = array(
 835          'news'   => array(
 836              'link'         => apply_filters( 'dashboard_primary_link', __( 'http://wordpress.org/news/' ) ),
 837              'url'          => apply_filters( 'dashboard_primary_feed', __( 'http://wordpress.org/news/feed/' ) ),
 838              'title'        => apply_filters( 'dashboard_primary_title', __( 'WordPress Blog' ) ),
 839              'items'        => 1,
 840              'show_summary' => 1,
 841              'show_author'  => 0,
 842              'show_date'    => 1,
 843          ),
 844          'planet' => array(
 845              'link'         => apply_filters( 'dashboard_secondary_link', __( 'http://planet.wordpress.org/' ) ),
 846              'url'          => apply_filters( 'dashboard_secondary_feed', __( 'http://planet.wordpress.org/feed/' ) ),
 847              'title'        => apply_filters( 'dashboard_secondary_title', __( 'Other WordPress News' ) ),
 848              'items'        => 3,
 849              'show_summary' => 0,
 850              'show_author'  => 0,
 851              'show_date'    => 0,
 852          )
 853      );
 854  
 855      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' ) ) ) {
 856          $feeds['plugins'] = array(
 857              'link'         => '',
 858              'url'          => array(
 859                  'popular' => 'http://wordpress.org/plugins/rss/browse/popular/',
 860              ),
 861              'title'        => '',
 862              'items'        => 1,
 863              'show_summary' => 0,
 864              'show_author'  => 0,
 865              'show_date'    => 0,
 866          );
 867      }
 868  
 869      wp_dashboard_cached_rss_widget( 'dashboard_primary', 'wp_dashboard_primary_output', $feeds );
 870  }
 871  
 872  /**
 873   * Display the WordPress news feeds.
 874   *
 875   * @since 3.8.0
 876   *
 877   * @param string $widget_id Widget ID.
 878   * @param array  $feeds     Array of RSS feeds.
 879   */
 880  function wp_dashboard_primary_output( $widget_id, $feeds ) {
 881      foreach( $feeds as $type => $args ) {
 882          $args['type'] = $type;
 883          echo '<div class="rss-widget">';
 884          if ( $type === 'plugins' ) {
 885              wp_dashboard_plugins_output( $args['url'], $args );
 886          } else {
 887              wp_widget_rss_output( $args['url'], $args );
 888          }
 889          echo "</div>";
 890      }
 891  }
 892  
 893  /**
 894   * Display plugins text for the WordPress news widget.
 895   *
 896   * @since 2.5.0
 897   */
 898  function wp_dashboard_plugins_output( $rss, $args = array() ) {
 899      // Plugin feeds plus link to install them
 900      $popular = fetch_feed( $args['url']['popular'] );
 901  
 902      if ( false === $plugin_slugs = get_transient( 'plugin_slugs' ) ) {
 903          $plugin_slugs = array_keys( get_plugins() );
 904          set_transient( 'plugin_slugs', $plugin_slugs, DAY_IN_SECONDS );
 905      }
 906  
 907      echo '<ul>';
 908  
 909      foreach ( array(
 910          'popular' => __( 'Popular Plugin' )
 911      ) as $feed => $label ) {
 912          if ( is_wp_error($$feed) || !$$feed->get_item_quantity() )
 913              continue;
 914  
 915          $items = $$feed->get_items(0, 5);
 916  
 917          // Pick a random, non-installed plugin
 918          while ( true ) {
 919              // Abort this foreach loop iteration if there's no plugins left of this type
 920              if ( 0 == count($items) )
 921                  continue 2;
 922  
 923              $item_key = array_rand($items);
 924              $item = $items[$item_key];
 925  
 926              list($link, $frag) = explode( '#', $item->get_link() );
 927  
 928              $link = esc_url($link);
 929              if ( preg_match( '|/([^/]+?)/?$|', $link, $matches ) )
 930                  $slug = $matches[1];
 931              else {
 932                  unset( $items[$item_key] );
 933                  continue;
 934              }
 935  
 936              // Is this random plugin's slug already installed? If so, try again.
 937              reset( $plugin_slugs );
 938              foreach ( $plugin_slugs as $plugin_slug ) {
 939                  if ( $slug == substr( $plugin_slug, 0, strlen( $slug ) ) ) {
 940                      unset( $items[$item_key] );
 941                      continue 2;
 942                  }
 943              }
 944  
 945              // If we get to this point, then the random plugin isn't installed and we can stop the while().
 946              break;
 947          }
 948  
 949          // Eliminate some common badly formed plugin descriptions
 950          while ( ( null !== $item_key = array_rand($items) ) && false !== strpos( $items[$item_key]->get_description(), 'Plugin Name:' ) )
 951              unset($items[$item_key]);
 952  
 953          if ( !isset($items[$item_key]) )
 954              continue;
 955  
 956          $title = esc_html( $item->get_title() );
 957  
 958          $description = esc_html( strip_tags( @html_entity_decode( $item->get_description(), ENT_QUOTES, get_option( 'blog_charset' ) ) ) );
 959  
 960          $ilink = wp_nonce_url('plugin-install.php?tab=plugin-information&plugin=' . $slug, 'install-plugin_' . $slug) . '&amp;TB_iframe=true&amp;width=600&amp;height=800';
 961  
 962          echo "<li class='dashboard-news-plugin'><span>$label:</span> <a href='$link' class='dashboard-news-plugin-link'>$title</a></h5>&nbsp;<span>(<a href='$ilink' class='thickbox' title='$title'>" . __( 'Install' ) . "</a>)</span></li>";
 963  
 964          $$feed->__destruct();
 965          unset( $$feed );
 966      }
 967  
 968      echo '</ul>';
 969  }
 970  
 971  /**
 972   * Display file upload quota on dashboard.
 973   *
 974   * Runs on the activity_box_end hook in wp_dashboard_right_now().
 975   *
 976   * @since 3.0.0
 977   *
 978   * @return bool True if not multisite, user can't upload files, or the space check option is disabled.
 979  */
 980  function wp_dashboard_quota() {
 981      if ( !is_multisite() || !current_user_can( 'upload_files' ) || get_site_option( 'upload_space_check_disabled' ) )
 982          return true;
 983  
 984      $quota = get_space_allowed();
 985      $used = get_space_used();
 986  
 987      if ( $used > $quota )
 988          $percentused = '100';
 989      else
 990          $percentused = ( $used / $quota ) * 100;
 991      $used_class = ( $percentused >= 70 ) ? ' warning' : '';
 992      $used = round( $used, 2 );
 993      $percentused = number_format( $percentused );
 994  
 995      ?>
 996      <h4 class="mu-storage"><?php _e( 'Storage Space' ); ?></h4>
 997      <div class="mu-storage">
 998      <ul>
 999          <li class="storage-count">
1000              <?php $text = sprintf(
1001                  /* translators: number of megabytes */
1002                  __( '%s MB Space Allowed' ),
1003                  number_format_i18n( $quota )
1004              );
1005              printf(
1006                  '<a href="%1$s" title="%2$s">%3$s</a>',
1007                  esc_url( admin_url( 'upload.php' ) ),
1008                  __( 'Manage Uploads' ),
1009                  $text
1010              ); ?>
1011          </li><li class="storage-count <?php echo $used_class; ?>">
1012              <?php $text = sprintf(
1013                  /* translators: 1: number of megabytes, 2: percentage */
1014                  __( '%1$s MB (%2$s%%) Space Used' ),
1015                  number_format_i18n( $used, 2 ),
1016                  $percentused
1017              );
1018              printf(
1019                  '<a href="%1$s" title="%2$s" class="musublink">%3$s</a>',
1020                  esc_url( admin_url( 'upload.php' ) ),
1021                  __( 'Manage Uploads' ),
1022                  $text
1023              ); ?>
1024          </li>
1025      </ul>
1026      </div>
1027      <?php
1028  }
1029  add_action( 'activity_box_end', 'wp_dashboard_quota' );
1030  
1031  // Display Browser Nag Meta Box
1032  function wp_dashboard_browser_nag() {
1033      $notice = '';
1034      $response = wp_check_browser_version();
1035  
1036      if ( $response ) {
1037          if ( $response['insecure'] ) {
1038              $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'] ) );
1039          } else {
1040              $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'] ) );
1041          }
1042  
1043          $browser_nag_class = '';
1044          if ( !empty( $response['img_src'] ) ) {
1045              $img_src = ( is_ssl() && ! empty( $response['img_src_ssl'] ) )? $response['img_src_ssl'] : $response['img_src'];
1046  
1047              $notice .= '<div class="alignright browser-icon"><a href="' . esc_attr($response['update_url']) . '"><img src="' . esc_attr( $img_src ) . '" alt="" /></a></div>';
1048              $browser_nag_class = ' has-browser-icon';
1049          }
1050          $notice .= "<p class='browser-update-nag{$browser_nag_class}'>{$msg}</p>";
1051  
1052          $browsehappy = 'http://browsehappy.com/';
1053          $locale = get_locale();
1054          if ( 'en_US' !== $locale )
1055              $browsehappy = add_query_arg( 'locale', $locale, $browsehappy );
1056  
1057          $notice .= '<p>' . sprintf( __( '<a href="%1$s" class="update-browser-link">Update %2$s</a> or learn how to <a href="%3$s" class="browse-happy-link">browse happy</a>' ), esc_attr( $response['update_url'] ), esc_html( $response['name'] ), esc_url( $browsehappy ) ) . '</p>';
1058          $notice .= '<p class="hide-if-no-js"><a href="" class="dismiss">' . __( 'Dismiss' ) . '</a></p>';
1059          $notice .= '<div class="clear"></div>';
1060      }
1061  
1062      echo apply_filters( 'browse-happy-notice', $notice, $response );
1063  }
1064  
1065  function dashboard_browser_nag_class( $classes ) {
1066      $response = wp_check_browser_version();
1067  
1068      if ( $response && $response['insecure'] )
1069          $classes[] = 'browser-insecure';
1070  
1071      return $classes;
1072  }
1073  
1074  /**
1075   * Check if the user needs a browser update
1076   *
1077   * @since 3.2.0
1078   *
1079   * @return array|bool False on failure, array of browser data on success.
1080   */
1081  function wp_check_browser_version() {
1082      if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
1083          return false;
1084  
1085      $key = md5( $_SERVER['HTTP_USER_AGENT'] );
1086  
1087      if ( false === ($response = get_site_transient('browser_' . $key) ) ) {
1088          global $wp_version;
1089  
1090          $options = array(
1091              'body'            => array( 'useragent' => $_SERVER['HTTP_USER_AGENT'] ),
1092              'user-agent'    => 'WordPress/' . $wp_version . '; ' . home_url()
1093          );
1094  
1095          $response = wp_remote_post( 'http://api.wordpress.org/core/browse-happy/1.1/', $options );
1096  
1097          if ( is_wp_error( $response ) || 200 != wp_remote_retrieve_response_code( $response ) )
1098              return false;
1099  
1100          /**
1101           * Response should be an array with:
1102           *  'name' - string - A user friendly browser name
1103           *  'version' - string - The most recent version of the browser
1104           *  'current_version' - string - The version of the browser the user is using
1105           *  'upgrade' - boolean - Whether the browser needs an upgrade
1106           *  'insecure' - boolean - Whether the browser is deemed insecure
1107           *  'upgrade_url' - string - The url to visit to upgrade
1108           *  'img_src' - string - An image representing the browser
1109           *  'img_src_ssl' - string - An image (over SSL) representing the browser
1110           */
1111          $response = json_decode( wp_remote_retrieve_body( $response ), true );
1112  
1113          if ( ! is_array( $response ) )
1114              return false;
1115  
1116          set_site_transient( 'browser_' . $key, $response, WEEK_IN_SECONDS );
1117      }
1118  
1119      return $response;
1120  }
1121  
1122  /**
1123   * Empty function usable by plugins to output empty dashboard widget (to be populated later by JS).
1124   */
1125  function wp_dashboard_empty() {}
1126  
1127  /**
1128   * Displays a welcome panel to introduce users to WordPress.
1129   *
1130   * @since 3.3.0
1131   */
1132  function wp_welcome_panel() {
1133      ?>
1134      <div class="welcome-panel-content">
1135      <h3><?php _e( 'Welcome to WordPress!' ); ?></h3>
1136      <p class="about-description"><?php _e( 'We&#8217;ve assembled some links to get you started:' ); ?></p>
1137      <div class="welcome-panel-column-container">
1138      <div class="welcome-panel-column">
1139          <h4><?php _e( 'Get Started' ); ?></h4>
1140          <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>
1141          <a class="button button-primary button-hero hide-if-customize" href="<?php echo admin_url( 'themes.php' ); ?>"><?php _e( 'Customize Your Site' ); ?></a>
1142          <?php if ( current_user_can( 'install_themes' ) || ( current_user_can( 'switch_themes' ) && count( wp_get_themes( array( 'allowed' => true ) ) ) > 1 ) ) : ?>
1143              <p class="hide-if-no-customize"><?php printf( __( 'or, <a href="%s">change your theme completely</a>' ), admin_url( 'themes.php' ) ); ?></p>
1144          <?php endif; ?>
1145      </div>
1146      <div class="welcome-panel-column">
1147          <h4><?php _e( 'Next Steps' ); ?></h4>
1148          <ul>
1149          <?php if ( 'page' == get_option( 'show_on_front' ) && ! get_option( 'page_for_posts' ) ) : ?>
1150              <li><?php printf( '<a href="%s" class="welcome-icon welcome-edit-page">' . __( 'Edit your front page' ) . '</a>', get_edit_post_link( get_option( 'page_on_front' ) ) ); ?></li>
1151              <li><?php printf( '<a href="%s" class="welcome-icon welcome-add-page">' . __( 'Add additional pages' ) . '</a>', admin_url( 'post-new.php?post_type=page' ) ); ?></li>
1152          <?php elseif ( 'page' == get_option( 'show_on_front' ) ) : ?>
1153              <li><?php printf( '<a href="%s" class="welcome-icon welcome-edit-page">' . __( 'Edit your front page' ) . '</a>', get_edit_post_link( get_option( 'page_on_front' ) ) ); ?></li>
1154              <li><?php printf( '<a href="%s" class="welcome-icon welcome-add-page">' . __( 'Add additional pages' ) . '</a>', admin_url( 'post-new.php?post_type=page' ) ); ?></li>
1155              <li><?php printf( '<a href="%s" class="welcome-icon welcome-write-blog">' . __( 'Add a blog post' ) . '</a>', admin_url( 'post-new.php' ) ); ?></li>
1156          <?php else : ?>
1157              <li><?php printf( '<a href="%s" class="welcome-icon welcome-write-blog">' . __( 'Write your first blog post' ) . '</a>', admin_url( 'post-new.php' ) ); ?></li>
1158              <li><?php printf( '<a href="%s" class="welcome-icon welcome-add-page">' . __( 'Add an About page' ) . '</a>', admin_url( 'post-new.php?post_type=page' ) ); ?></li>
1159          <?php endif; ?>
1160              <li><?php printf( '<a href="%s" class="welcome-icon welcome-view-site">' . __( 'View your site' ) . '</a>', home_url( '/' ) ); ?></li>
1161          </ul>
1162      </div>
1163      <div class="welcome-panel-column welcome-panel-last">
1164          <h4><?php _e( 'More Actions' ); ?></h4>
1165          <ul>
1166              <li><?php printf( '<div class="welcome-icon welcome-widgets-menus">' . __( 'Manage <a href="%1$s">widgets</a> or <a href="%2$s">menus</a>' ) . '</div>', admin_url( 'widgets.php' ), admin_url( 'nav-menus.php' ) ); ?></li>
1167              <li><?php printf( '<a href="%s" class="welcome-icon welcome-comments">' . __( 'Turn comments on or off' ) . '</a>', admin_url( 'options-discussion.php' ) ); ?></li>
1168              <li><?php printf( '<a href="%s" class="welcome-icon welcome-learn-more">' . __( 'Learn more about getting started' ) . '</a>', __( 'http://codex.wordpress.org/First_Steps_With_WordPress' ) ); ?></li>
1169          </ul>
1170      </div>
1171      </div>
1172      </div>
1173      <?php
1174  }


Generated: Tue Mar 25 01:41:18 2014 WordPress honlapkészítés: online1.hu