[ Index ]

PHP Cross Reference of WordPress Trunk (Updated Daily)

Search

title

Body

[close]

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

   1  <?php
   2  /**
   3   * WordPress Dashboard "On This Day" widget.
   4   *
   5   * @package WordPress
   6   * @subpackage Administration
   7   * @since 7.1.0
   8   */
   9  
  10  /**
  11   * Registers the On This Day dashboard widget.
  12   *
  13   * Designed to be the single entry point called from the dashboard setup
  14   * routine. The widget is always registered so that it remains available in
  15   * Screen Options and keeps its user-customized position. When there are no
  16   * matching posts, a marker class is added to the postbox so the widget can be
  17   * hidden with CSS.
  18   *
  19   * @since 7.1.0
  20   */
  21  function wp_dashboard_on_this_day_setup() {
  22      add_filter( 'postbox_classes_dashboard_wp_dashboard_on_this_day', 'wp_dashboard_on_this_day_postbox_classes' );
  23  
  24      wp_add_dashboard_widget(
  25          'wp_dashboard_on_this_day',
  26          __( 'On This Day' ),
  27          'wp_dashboard_on_this_day'
  28      );
  29  }
  30  
  31  /**
  32   * Hides the On This Day postbox when there are no posts to show.
  33   *
  34   * Adds the core `hidden` class so the widget stays registered — preserving its
  35   * Screen Options entry and user-customized position — while being hidden when
  36   * empty. A user can still reveal it via Screen Options, in which case the
  37   * placeholder message is shown.
  38   *
  39   * @since 7.1.0
  40   *
  41   * @param string[] $classes An array of postbox classes.
  42   * @return string[] Filtered postbox classes.
  43   */
  44  function wp_dashboard_on_this_day_postbox_classes( $classes ) {
  45      if ( empty( wp_dashboard_on_this_day_get_posts() ) ) {
  46          $classes[] = 'hidden';
  47      }
  48  
  49      return $classes;
  50  }
  51  
  52  /**
  53   * Renders the On This Day dashboard widget.
  54   *
  55   * Outputs the matching posts grouped by publication year, newest year first.
  56   *
  57   * @since 7.1.0
  58   */
  59  function wp_dashboard_on_this_day() {
  60      $posts = wp_dashboard_on_this_day_get_posts();
  61  
  62      if ( empty( $posts ) ) {
  63          // Placeholder shown when a user reveals the hidden widget via Screen
  64          // Options on a day with no matching posts.
  65          echo '<p>' . esc_html__( 'No posts were published on this day in previous years.' ) . '</p>';
  66          return;
  67      }
  68  
  69      $posts_by_year = array();
  70      $post_count    = count( $posts );
  71  
  72      foreach ( $posts as $post ) {
  73          $year = get_the_date( 'Y', $post );
  74  
  75          if ( ! isset( $posts_by_year[ $year ] ) ) {
  76              $posts_by_year[ $year ] = array();
  77          }
  78  
  79          $posts_by_year[ $year ][] = $post;
  80      }
  81  
  82      /* translators: Date format for the On This Day widget date, without year. See https://www.php.net/manual/datetime.format.php */
  83      $date = '<strong>' . esc_html( wp_date( _x( 'F jS', 'on this day date format' ) ) ) . '</strong>';
  84      ?>
  85      <div class="wp-on-this-day-widget">
  86          <p>
  87              <?php
  88              if ( 1 === $post_count ) {
  89                  printf(
  90                      /* translators: %s: Date, without year. */
  91                      esc_html__( 'One post has been published on %s:' ),
  92                      $date // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Date is escaped above.
  93                  );
  94              } else {
  95                  printf(
  96                      esc_html(
  97                          /* translators: 1: Number of posts, 2: Date, without year. */
  98                          _n(
  99                              '%1$s post has been published on %2$s:',
 100                              '%1$s posts have been published on %2$s:',
 101                              $post_count
 102                          )
 103                      ),
 104                      esc_html( number_format_i18n( $post_count ) ),
 105                      $date // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Date is escaped above.
 106                  );
 107              }
 108              ?>
 109          </p>
 110          <ul>
 111              <?php foreach ( $posts_by_year as $year => $year_posts ) : ?>
 112                  <li>
 113                      <h3><?php echo esc_html( $year ); ?></h3>
 114                      <ul>
 115                          <?php foreach ( $year_posts as $year_post ) : ?>
 116                              <?php
 117                              $title = get_the_title( $year_post );
 118  
 119                              if ( '' === trim( $title ) ) {
 120                                  $title = __( '(no title)' );
 121                              }
 122  
 123                              $author_id   = (int) $year_post->post_author;
 124                              $author_name = $author_id > 0 ? (string) get_the_author_meta( 'display_name', $author_id ) : '';
 125                              $show_author = '' !== trim( $author_name ) && get_current_user_id() !== $author_id;
 126                              ?>
 127                              <li>
 128                                  <a href="<?php echo esc_url( get_permalink( $year_post ) ); ?>"><?php echo esc_html( $title ); ?></a>
 129                                  <?php if ( $show_author ) : ?>
 130                                      <?php
 131                                      echo '<span class="wp-on-this-day-post-author">' . esc_html(
 132                                          sprintf(
 133                                              /* translators: %s: Post author's display name. */
 134                                              __( 'by %s' ),
 135                                              $author_name
 136                                          )
 137                                      ) . '</span>';
 138                                      ?>
 139                                  <?php endif; ?>
 140                              </li>
 141                          <?php endforeach; ?>
 142                      </ul>
 143                  </li>
 144              <?php endforeach; ?>
 145          </ul>
 146      </div>
 147      <?php
 148  }
 149  
 150  /**
 151   * Retrieves published posts from all authors that were published on this
 152   * calendar day in previous years.
 153   *
 154   * The date constraint matches today's month and day, combined with a
 155   * `before` clause anchored to January 1 of the current year. Up to ten posts
 156   * are returned; use the `wp_dashboard_on_this_day_query_args` filter to change
 157   * the limit. Results are cached by WP_Query's native query caching.
 158   *
 159   * @since 7.1.0
 160   *
 161   * @return WP_Post[] Array of posts ordered by newest first.
 162   */
 163  function wp_dashboard_on_this_day_get_posts() {
 164      $today      = current_datetime();
 165      $year       = (int) $today->format( 'Y' );
 166      $date_query = array(
 167          'relation' => 'AND',
 168          array(
 169              'before' => array( 'year' => $year ),
 170          ),
 171          _wp_dashboard_on_this_day_date_query_clause( $today ),
 172      );
 173  
 174      $args = array(
 175          'post_type'              => 'post',
 176          'post_status'            => array( 'publish' ),
 177          'posts_per_page'         => 10,
 178          'ignore_sticky_posts'    => true,
 179          'orderby'                => 'date',
 180          'order'                  => 'DESC',
 181          'no_found_rows'          => true,
 182          'update_post_term_cache' => false,
 183          'update_post_meta_cache' => false,
 184          'date_query'             => $date_query,
 185      );
 186  
 187      /**
 188       * Filters the arguments used to query posts for the On This Day dashboard widget.
 189       *
 190       * @since 7.1.0
 191       *
 192       * @param array $args WP_Query arguments.
 193       */
 194      $args = apply_filters( 'wp_dashboard_on_this_day_query_args', $args );
 195  
 196      $query = new WP_Query( $args );
 197  
 198      return $query->posts;
 199  }
 200  
 201  /**
 202   * Builds the date query clause for today's anniversary date.
 203   *
 204   * On February 28 in a non-leap year, February 29 posts are included so
 205   * leap-day anniversaries still appear.
 206   *
 207   * @since 7.1.0
 208   * @access private
 209   *
 210   * @param DateTimeInterface $date Date to build the clause for.
 211   * @return array Date query clause.
 212   */
 213  function _wp_dashboard_on_this_day_date_query_clause( $date ) {
 214      $month  = (int) $date->format( 'm' );
 215      $day    = (int) $date->format( 'd' );
 216      $clause = array(
 217          'month' => $month,
 218          'day'   => $day,
 219      );
 220  
 221      // Display leap day posts on Feb 28 in non leap years.
 222      if (
 223          28 === $day
 224          && 2 === $month
 225          && false === (bool) $date->format( 'L' )
 226      ) {
 227          $clause = array(
 228              'relation' => 'OR',
 229              $clause,
 230              array(
 231                  'month' => 2,
 232                  'day'   => 29,
 233              ),
 234          );
 235      }
 236  
 237      return $clause;
 238  }


Generated : Sat Jul 11 08:20:14 2026 Cross-referenced by PHPXref