[ Index ]

PHP Cross Reference of WordPress Trunk (Updated Daily)

Search

title

Body

[close]

/wp-admin/includes/ -> class-wp-media-list-table.php (source)

   1  <?php
   2  /**
   3   * List Table API: WP_Media_List_Table class
   4   *
   5   * @package WordPress
   6   * @subpackage Administration
   7   * @since 3.1.0
   8   */
   9  
  10  /**
  11   * Core class used to implement displaying media items in a list table.
  12   *
  13   * @since 3.1.0
  14   *
  15   * @see WP_List_Table
  16   */
  17  class WP_Media_List_Table extends WP_List_Table {
  18      /**
  19       * Holds the number of pending comments for each post.
  20       *
  21       * @since 4.4.0
  22       * @var array
  23       */
  24      protected $comment_pending_count = array();
  25  
  26      private $detached;
  27  
  28      private $is_trash;
  29  
  30      /**
  31       * Constructor.
  32       *
  33       * @since 3.1.0
  34       *
  35       * @see WP_List_Table::__construct() for more information on default arguments.
  36       *
  37       * @param array $args An associative array of arguments.
  38       */
  39  	public function __construct( $args = array() ) {
  40          $this->detached = ( isset( $_REQUEST['attachment-filter'] ) && 'detached' === $_REQUEST['attachment-filter'] );
  41  
  42          $this->modes = array(
  43              'list' => __( 'List view' ),
  44              'grid' => __( 'Grid view' ),
  45          );
  46  
  47          parent::__construct(
  48              array(
  49                  'plural' => 'media',
  50                  'screen' => isset( $args['screen'] ) ? $args['screen'] : null,
  51              )
  52          );
  53      }
  54  
  55      /**
  56       * @return bool
  57       */
  58  	public function ajax_user_can() {
  59          return current_user_can( 'upload_files' );
  60      }
  61  
  62      /**
  63       * @global string   $mode                  List table view mode.
  64       * @global WP_Query $wp_query              WordPress Query object.
  65       * @global array    $post_mime_types
  66       * @global array    $avail_post_mime_types
  67       */
  68  	public function prepare_items() {
  69          global $mode, $wp_query, $post_mime_types, $avail_post_mime_types;
  70  
  71          $mode = empty( $_REQUEST['mode'] ) ? 'list' : $_REQUEST['mode'];
  72  
  73          /*
  74           * Exclude attachments scheduled for deletion in the next two hours
  75           * if they are for zip packages for interrupted or failed updates.
  76           * See File_Upload_Upgrader class.
  77           */
  78          $not_in = array();
  79  
  80          $crons = _get_cron_array();
  81  
  82          if ( is_array( $crons ) ) {
  83              foreach ( $crons as $cron ) {
  84                  if ( isset( $cron['upgrader_scheduled_cleanup'] ) ) {
  85                      $details = reset( $cron['upgrader_scheduled_cleanup'] );
  86  
  87                      if ( ! empty( $details['args'][0] ) ) {
  88                          $not_in[] = (int) $details['args'][0];
  89                      }
  90                  }
  91              }
  92          }
  93  
  94          if ( ! empty( $_REQUEST['post__not_in'] ) && is_array( $_REQUEST['post__not_in'] ) ) {
  95              $not_in = array_merge( array_values( $_REQUEST['post__not_in'] ), $not_in );
  96          }
  97  
  98          if ( ! empty( $not_in ) ) {
  99              $_REQUEST['post__not_in'] = $not_in;
 100          }
 101  
 102          list( $post_mime_types, $avail_post_mime_types ) = wp_edit_attachments_query( $_REQUEST );
 103  
 104          $this->is_trash = isset( $_REQUEST['attachment-filter'] ) && 'trash' === $_REQUEST['attachment-filter'];
 105  
 106          $this->set_pagination_args(
 107              array(
 108                  'total_items' => $wp_query->found_posts,
 109                  'total_pages' => $wp_query->max_num_pages,
 110                  'per_page'    => $wp_query->query_vars['posts_per_page'],
 111              )
 112          );
 113          if ( $wp_query->posts ) {
 114              update_post_thumbnail_cache( $wp_query );
 115              update_post_parent_caches( $wp_query->posts );
 116          }
 117      }
 118  
 119      /**
 120       * @global array $post_mime_types
 121       * @global array $avail_post_mime_types
 122       * @return array
 123       */
 124  	protected function get_views() {
 125          global $post_mime_types, $avail_post_mime_types;
 126  
 127          $type_links = array();
 128  
 129          $filter = empty( $_GET['attachment-filter'] ) ? '' : $_GET['attachment-filter'];
 130  
 131          $type_links['all'] = sprintf(
 132              '<option value=""%s>%s</option>',
 133              selected( $filter, true, false ),
 134              __( 'All media items' )
 135          );
 136  
 137          foreach ( $post_mime_types as $mime_type => $label ) {
 138              if ( ! wp_match_mime_types( $mime_type, $avail_post_mime_types ) ) {
 139                  continue;
 140              }
 141  
 142              $selected = selected(
 143                  $filter && str_starts_with( $filter, 'post_mime_type:' ) &&
 144                      wp_match_mime_types( $mime_type, str_replace( 'post_mime_type:', '', $filter ) ),
 145                  true,
 146                  false
 147              );
 148  
 149              $type_links[ $mime_type ] = sprintf(
 150                  '<option value="post_mime_type:%s"%s>%s</option>',
 151                  esc_attr( $mime_type ),
 152                  $selected,
 153                  $label[0]
 154              );
 155          }
 156  
 157          $type_links['detached'] = '<option value="detached"' . ( $this->detached ? ' selected="selected"' : '' ) . '>' . _x( 'Unattached', 'media items' ) . '</option>';
 158  
 159          $type_links['mine'] = sprintf(
 160              '<option value="mine"%s>%s</option>',
 161              selected( 'mine' === $filter, true, false ),
 162              _x( 'Mine', 'media items' )
 163          );
 164  
 165          if ( $this->is_trash || ( defined( 'MEDIA_TRASH' ) && MEDIA_TRASH ) ) {
 166              $type_links['trash'] = sprintf(
 167                  '<option value="trash"%s>%s</option>',
 168                  selected( 'trash' === $filter, true, false ),
 169                  _x( 'Trash', 'attachment filter' )
 170              );
 171          }
 172  
 173          return $type_links;
 174      }
 175  
 176      /**
 177       * @return array
 178       */
 179  	protected function get_bulk_actions() {
 180          $actions = array();
 181  
 182          if ( MEDIA_TRASH ) {
 183              if ( $this->is_trash ) {
 184                  $actions['untrash'] = __( 'Restore' );
 185                  $actions['delete']  = __( 'Delete permanently' );
 186              } else {
 187                  $actions['trash'] = __( 'Move to Trash' );
 188              }
 189          } else {
 190              $actions['delete'] = __( 'Delete permanently' );
 191          }
 192  
 193          if ( $this->detached ) {
 194              $actions['attach'] = __( 'Attach' );
 195          }
 196  
 197          return $actions;
 198      }
 199  
 200      /**
 201       * @param string $which
 202       */
 203  	protected function extra_tablenav( $which ) {
 204          if ( 'bar' !== $which ) {
 205              return;
 206          }
 207          ?>
 208          <div class="actions">
 209              <?php
 210              if ( ! $this->is_trash ) {
 211                  $this->months_dropdown( 'attachment' );
 212              }
 213  
 214              /** This action is documented in wp-admin/includes/class-wp-posts-list-table.php */
 215              do_action( 'restrict_manage_posts', $this->screen->post_type, $which );
 216  
 217              submit_button( __( 'Filter' ), '', 'filter_action', false, array( 'id' => 'post-query-submit' ) );
 218  
 219              if ( $this->is_trash && $this->has_items()
 220                  && current_user_can( 'edit_others_posts' )
 221              ) {
 222                  submit_button( __( 'Empty Trash' ), 'apply', 'delete_all', false );
 223              }
 224              ?>
 225          </div>
 226          <?php
 227      }
 228  
 229      /**
 230       * @return string
 231       */
 232  	public function current_action() {
 233          if ( isset( $_REQUEST['found_post_id'] ) && isset( $_REQUEST['media'] ) ) {
 234              return 'attach';
 235          }
 236  
 237          if ( isset( $_REQUEST['parent_post_id'] ) && isset( $_REQUEST['media'] ) ) {
 238              return 'detach';
 239          }
 240  
 241          if ( isset( $_REQUEST['delete_all'] ) || isset( $_REQUEST['delete_all2'] ) ) {
 242              return 'delete_all';
 243          }
 244  
 245          return parent::current_action();
 246      }
 247  
 248      /**
 249       * @return bool
 250       */
 251  	public function has_items() {
 252          return have_posts();
 253      }
 254  
 255      /**
 256       */
 257  	public function no_items() {
 258          if ( $this->is_trash ) {
 259              _e( 'No media files found in Trash.' );
 260          } else {
 261              _e( 'No media files found.' );
 262          }
 263      }
 264  
 265      /**
 266       * Overrides parent views to use the filter bar display.
 267       *
 268       * @global string $mode List table view mode.
 269       */
 270  	public function views() {
 271          global $mode;
 272  
 273          $views = $this->get_views();
 274  
 275          $this->screen->render_screen_reader_content( 'heading_views' );
 276          ?>
 277          <div class="wp-filter">
 278              <div class="filter-items">
 279                  <?php $this->view_switcher( $mode ); ?>
 280  
 281                  <label for="attachment-filter" class="screen-reader-text">
 282                      <?php
 283                      /* translators: Hidden accessibility text. */
 284                      _e( 'Filter by type' );
 285                      ?>
 286                  </label>
 287                  <select class="attachment-filters" name="attachment-filter" id="attachment-filter">
 288                      <?php
 289                      if ( ! empty( $views ) ) {
 290                          foreach ( $views as $class => $view ) {
 291                              echo "\t$view\n";
 292                          }
 293                      }
 294                      ?>
 295                  </select>
 296  
 297                  <?php
 298                  $this->extra_tablenav( 'bar' );
 299  
 300                  /** This filter is documented in wp-admin/includes/class-wp-list-table.php */
 301                  $views = apply_filters( "views_{$this->screen->id}", array() );
 302  
 303                  // Back compat for pre-4.0 view links.
 304                  if ( ! empty( $views ) ) {
 305                      echo '<ul class="filter-links">';
 306                      foreach ( $views as $class => $view ) {
 307                          echo "<li class='$class'>$view</li>";
 308                      }
 309                      echo '</ul>';
 310                  }
 311                  ?>
 312              </div>
 313  
 314              <div class="search-form">
 315                  <p class="search-box">
 316                      <label class="screen-reader-text" for="media-search-input">
 317                      <?php
 318                      /* translators: Hidden accessibility text. */
 319                      esc_html_e( 'Search Media' );
 320                      ?>
 321                      </label>
 322                      <input type="search" id="media-search-input" class="search" name="s" value="<?php _admin_search_query(); ?>">
 323                      <input id="search-submit" type="submit" class="button" value="<?php esc_attr_e( 'Search Media' ); ?>">
 324                  </p>
 325              </div>
 326          </div>
 327          <?php
 328      }
 329  
 330      /**
 331       * @return string[] Array of column titles keyed by their column name.
 332       */
 333  	public function get_columns() {
 334          $posts_columns       = array();
 335          $posts_columns['cb'] = '<input type="checkbox" />';
 336          /* translators: Column name. */
 337          $posts_columns['title']  = _x( 'File', 'column name' );
 338          $posts_columns['author'] = __( 'Author' );
 339  
 340          $taxonomies = get_taxonomies_for_attachments( 'objects' );
 341          $taxonomies = wp_filter_object_list( $taxonomies, array( 'show_admin_column' => true ), 'and', 'name' );
 342  
 343          /**
 344           * Filters the taxonomy columns for attachments in the Media list table.
 345           *
 346           * @since 3.5.0
 347           *
 348           * @param string[] $taxonomies An array of registered taxonomy names to show for attachments.
 349           * @param string   $post_type  The post type. Default 'attachment'.
 350           */
 351          $taxonomies = apply_filters( 'manage_taxonomies_for_attachment_columns', $taxonomies, 'attachment' );
 352          $taxonomies = array_filter( $taxonomies, 'taxonomy_exists' );
 353  
 354          foreach ( $taxonomies as $taxonomy ) {
 355              if ( 'category' === $taxonomy ) {
 356                  $column_key = 'categories';
 357              } elseif ( 'post_tag' === $taxonomy ) {
 358                  $column_key = 'tags';
 359              } else {
 360                  $column_key = 'taxonomy-' . $taxonomy;
 361              }
 362  
 363              $posts_columns[ $column_key ] = get_taxonomy( $taxonomy )->labels->name;
 364          }
 365  
 366          /* translators: Column name. */
 367          if ( ! $this->detached ) {
 368              $posts_columns['parent'] = _x( 'Uploaded to', 'column name' );
 369  
 370              if ( post_type_supports( 'attachment', 'comments' ) ) {
 371                  $posts_columns['comments'] = sprintf(
 372                      '<span class="vers comment-grey-bubble" title="%1$s" aria-hidden="true"></span><span class="screen-reader-text">%2$s</span>',
 373                      esc_attr__( 'Comments' ),
 374                      /* translators: Hidden accessibility text. */
 375                      __( 'Comments' )
 376                  );
 377              }
 378          }
 379  
 380          /* translators: Column name. */
 381          $posts_columns['date'] = _x( 'Date', 'column name' );
 382  
 383          /**
 384           * Filters the Media list table columns.
 385           *
 386           * @since 2.5.0
 387           *
 388           * @param string[] $posts_columns An array of columns displayed in the Media list table.
 389           * @param bool     $detached      Whether the list table contains media not attached
 390           *                                to any posts. Default true.
 391           */
 392          return apply_filters( 'manage_media_columns', $posts_columns, $this->detached );
 393      }
 394  
 395      /**
 396       * @return array
 397       */
 398  	protected function get_sortable_columns() {
 399          return array(
 400              'title'    => array( 'title', false, _x( 'File', 'column name' ), __( 'Table ordered by File Name.' ) ),
 401              'author'   => array( 'author', false, __( 'Author' ), __( 'Table ordered by Author.' ) ),
 402              'parent'   => array( 'parent', false, _x( 'Uploaded to', 'column name' ), __( 'Table ordered by Uploaded To.' ) ),
 403              'comments' => array( 'comment_count', __( 'Comments' ), false, __( 'Table ordered by Comments.' ) ),
 404              'date'     => array( 'date', true, __( 'Date' ), __( 'Table ordered by Date.' ), 'desc' ),
 405          );
 406      }
 407  
 408      /**
 409       * Handles the checkbox column output.
 410       *
 411       * @since 4.3.0
 412       * @since 5.9.0 Renamed `$post` to `$item` to match parent class for PHP 8 named parameter support.
 413       *
 414       * @param WP_Post $item The current WP_Post object.
 415       */
 416  	public function column_cb( $item ) {
 417          // Restores the more descriptive, specific name for use within this method.
 418          $post = $item;
 419  
 420          if ( current_user_can( 'edit_post', $post->ID ) ) {
 421              ?>
 422              <input type="checkbox" name="media[]" id="cb-select-<?php echo $post->ID; ?>" value="<?php echo $post->ID; ?>" />
 423              <label for="cb-select-<?php echo $post->ID; ?>">
 424                  <span class="screen-reader-text">
 425                  <?php
 426                  /* translators: Hidden accessibility text. %s: Attachment title. */
 427                  printf( __( 'Select %s' ), _draft_or_post_title() );
 428                  ?>
 429                  </span>
 430              </label>
 431              <?php
 432          }
 433      }
 434  
 435      /**
 436       * Handles the title column output.
 437       *
 438       * @since 4.3.0
 439       *
 440       * @param WP_Post $post The current WP_Post object.
 441       */
 442  	public function column_title( $post ) {
 443          list( $mime ) = explode( '/', $post->post_mime_type );
 444  
 445          $attachment_id = $post->ID;
 446  
 447          if ( has_post_thumbnail( $post ) ) {
 448              $thumbnail_id = get_post_thumbnail_id( $post );
 449  
 450              if ( ! empty( $thumbnail_id ) ) {
 451                  $attachment_id = $thumbnail_id;
 452              }
 453          }
 454  
 455          $title      = _draft_or_post_title();
 456          $thumb      = wp_get_attachment_image( $attachment_id, array( 60, 60 ), true, array( 'alt' => '' ) );
 457          $link_start = '';
 458          $link_end   = '';
 459  
 460          if ( current_user_can( 'edit_post', $post->ID ) && ! $this->is_trash ) {
 461              $link_start = sprintf(
 462                  '<a href="%s" aria-label="%s">',
 463                  get_edit_post_link( $post->ID ),
 464                  /* translators: %s: Attachment title. */
 465                  esc_attr( sprintf( __( '&#8220;%s&#8221; (Edit)' ), $title ) )
 466              );
 467              $link_end = '</a>';
 468          }
 469  
 470          $class = $thumb ? ' class="has-media-icon"' : '';
 471          ?>
 472          <strong<?php echo $class; ?>>
 473              <?php
 474              echo $link_start;
 475  
 476              if ( $thumb ) :
 477                  ?>
 478                  <span class="media-icon <?php echo sanitize_html_class( $mime . '-icon' ); ?>"><?php echo $thumb; ?></span>
 479                  <?php
 480              endif;
 481  
 482              echo $title . $link_end;
 483  
 484              _media_states( $post );
 485              ?>
 486          </strong>
 487          <p class="filename">
 488              <span class="screen-reader-text">
 489                  <?php
 490                  /* translators: Hidden accessibility text. */
 491                  _e( 'File name:' );
 492                  ?>
 493              </span>
 494              <?php
 495              $file = get_attached_file( $post->ID );
 496              echo esc_html( wp_basename( $file ) );
 497              ?>
 498          </p>
 499          <?php
 500      }
 501  
 502      /**
 503       * Handles the author column output.
 504       *
 505       * @since 4.3.0
 506       *
 507       * @param WP_Post $post The current WP_Post object.
 508       */
 509  	public function column_author( $post ) {
 510          printf(
 511              '<a href="%s">%s</a>',
 512              esc_url( add_query_arg( array( 'author' => get_the_author_meta( 'ID' ) ), 'upload.php' ) ),
 513              get_the_author()
 514          );
 515      }
 516  
 517      /**
 518       * Handles the description column output.
 519       *
 520       * @since 4.3.0
 521       * @deprecated 6.2.0
 522       *
 523       * @param WP_Post $post The current WP_Post object.
 524       */
 525  	public function column_desc( $post ) {
 526          _deprecated_function( __METHOD__, '6.2.0' );
 527  
 528          echo has_excerpt() ? $post->post_excerpt : '';
 529      }
 530  
 531      /**
 532       * Handles the date column output.
 533       *
 534       * @since 4.3.0
 535       *
 536       * @param WP_Post $post The current WP_Post object.
 537       */
 538  	public function column_date( $post ) {
 539          if ( '0000-00-00 00:00:00' === $post->post_date ) {
 540              $h_time = __( 'Unpublished' );
 541          } else {
 542              $time      = get_post_timestamp( $post );
 543              $time_diff = time() - $time;
 544  
 545              if ( $time && $time_diff > 0 && $time_diff < DAY_IN_SECONDS ) {
 546                  /* translators: %s: Human-readable time difference. */
 547                  $h_time = sprintf( __( '%s ago' ), human_time_diff( $time ) );
 548              } else {
 549                  $h_time = get_the_time( __( 'Y/m/d' ), $post );
 550              }
 551          }
 552  
 553          /**
 554           * Filters the published time of an attachment displayed in the Media list table.
 555           *
 556           * @since 6.0.0
 557           *
 558           * @param string  $h_time      The published time.
 559           * @param WP_Post $post        Attachment object.
 560           * @param string  $column_name The column name.
 561           */
 562          echo apply_filters( 'media_date_column_time', $h_time, $post, 'date' );
 563      }
 564  
 565      /**
 566       * Handles the parent column output.
 567       *
 568       * @since 4.3.0
 569       *
 570       * @param WP_Post $post The current WP_Post object.
 571       */
 572  	public function column_parent( $post ) {
 573          $user_can_edit = current_user_can( 'edit_post', $post->ID );
 574  
 575          if ( $post->post_parent > 0 ) {
 576              $parent = get_post( $post->post_parent );
 577          } else {
 578              $parent = false;
 579          }
 580  
 581          if ( $parent ) {
 582              $title       = _draft_or_post_title( $post->post_parent );
 583              $parent_type = get_post_type_object( $parent->post_type );
 584  
 585              if ( $parent_type && $parent_type->show_ui && current_user_can( 'edit_post', $post->post_parent ) ) {
 586                  printf( '<strong><a href="%s">%s</a></strong>', get_edit_post_link( $post->post_parent ), $title );
 587              } elseif ( $parent_type && current_user_can( 'read_post', $post->post_parent ) ) {
 588                  printf( '<strong>%s</strong>', $title );
 589              } else {
 590                  _e( '(Private post)' );
 591              }
 592  
 593              if ( $user_can_edit ) :
 594                  $detach_url = add_query_arg(
 595                      array(
 596                          'parent_post_id' => $post->post_parent,
 597                          'media[]'        => $post->ID,
 598                          '_wpnonce'       => wp_create_nonce( 'bulk-' . $this->_args['plural'] ),
 599                      ),
 600                      'upload.php'
 601                  );
 602                  printf(
 603                      '<br /><a href="%s" class="hide-if-no-js detach-from-parent" aria-label="%s">%s</a>',
 604                      $detach_url,
 605                      /* translators: %s: Title of the post the attachment is attached to. */
 606                      esc_attr( sprintf( __( 'Detach from &#8220;%s&#8221;' ), $title ) ),
 607                      __( 'Detach' )
 608                  );
 609              endif;
 610          } else {
 611              _e( '(Unattached)' );
 612              ?>
 613              <?php
 614              if ( $user_can_edit ) {
 615                  $title = _draft_or_post_title( $post->post_parent );
 616                  printf(
 617                      '<br /><a href="#the-list" onclick="findPosts.open( \'media[]\', \'%s\' ); return false;" class="hide-if-no-js aria-button-if-js" aria-label="%s">%s</a>',
 618                      $post->ID,
 619                      /* translators: %s: Attachment title. */
 620                      esc_attr( sprintf( __( 'Attach &#8220;%s&#8221; to existing content' ), $title ) ),
 621                      __( 'Attach' )
 622                  );
 623              }
 624          }
 625      }
 626  
 627      /**
 628       * Handles the comments column output.
 629       *
 630       * @since 4.3.0
 631       *
 632       * @param WP_Post $post The current WP_Post object.
 633       */
 634  	public function column_comments( $post ) {
 635          echo '<div class="post-com-count-wrapper">';
 636  
 637          if ( isset( $this->comment_pending_count[ $post->ID ] ) ) {
 638              $pending_comments = $this->comment_pending_count[ $post->ID ];
 639          } else {
 640              $pending_comments = get_pending_comments_num( $post->ID );
 641          }
 642  
 643          $this->comments_bubble( $post->ID, $pending_comments );
 644  
 645          echo '</div>';
 646      }
 647  
 648      /**
 649       * Handles output for the default column.
 650       *
 651       * @since 4.3.0
 652       * @since 5.9.0 Renamed `$post` to `$item` to match parent class for PHP 8 named parameter support.
 653       *
 654       * @param WP_Post $item        The current WP_Post object.
 655       * @param string  $column_name Current column name.
 656       */
 657  	public function column_default( $item, $column_name ) {
 658          // Restores the more descriptive, specific name for use within this method.
 659          $post = $item;
 660  
 661          if ( 'categories' === $column_name ) {
 662              $taxonomy = 'category';
 663          } elseif ( 'tags' === $column_name ) {
 664              $taxonomy = 'post_tag';
 665          } elseif ( str_starts_with( $column_name, 'taxonomy-' ) ) {
 666              $taxonomy = substr( $column_name, 9 );
 667          } else {
 668              $taxonomy = false;
 669          }
 670  
 671          if ( $taxonomy ) {
 672              $terms = get_the_terms( $post->ID, $taxonomy );
 673  
 674              if ( is_array( $terms ) ) {
 675                  $output = array();
 676  
 677                  foreach ( $terms as $t ) {
 678                      $posts_in_term_qv             = array();
 679                      $posts_in_term_qv['taxonomy'] = $taxonomy;
 680                      $posts_in_term_qv['term']     = $t->slug;
 681  
 682                      $output[] = sprintf(
 683                          '<a href="%s">%s</a>',
 684                          esc_url( add_query_arg( $posts_in_term_qv, 'upload.php' ) ),
 685                          esc_html( sanitize_term_field( 'name', $t->name, $t->term_id, $taxonomy, 'display' ) )
 686                      );
 687                  }
 688  
 689                  echo implode( wp_get_list_item_separator(), $output );
 690              } else {
 691                  echo '<span aria-hidden="true">&#8212;</span><span class="screen-reader-text">' . get_taxonomy( $taxonomy )->labels->no_terms . '</span>';
 692              }
 693  
 694              return;
 695          }
 696  
 697          /**
 698           * Fires for each custom column in the Media list table.
 699           *
 700           * Custom columns are registered using the {@see 'manage_media_columns'} filter.
 701           *
 702           * @since 2.5.0
 703           *
 704           * @param string $column_name Name of the custom column.
 705           * @param int    $post_id     Attachment ID.
 706           */
 707          do_action( 'manage_media_custom_column', $column_name, $post->ID );
 708      }
 709  
 710      /**
 711       * @global WP_Post  $post     Global post object.
 712       * @global WP_Query $wp_query WordPress Query object.
 713       */
 714  	public function display_rows() {
 715          global $post, $wp_query;
 716  
 717          $post_ids = wp_list_pluck( $wp_query->posts, 'ID' );
 718          reset( $wp_query->posts );
 719  
 720          $this->comment_pending_count = get_pending_comments_num( $post_ids );
 721  
 722          add_filter( 'the_title', 'esc_html' );
 723  
 724          while ( have_posts() ) :
 725              the_post();
 726  
 727              if ( $this->is_trash && 'trash' !== $post->post_status
 728                  || ! $this->is_trash && 'trash' === $post->post_status
 729              ) {
 730                  continue;
 731              }
 732  
 733              $post_owner = ( get_current_user_id() === (int) $post->post_author ) ? 'self' : 'other';
 734              ?>
 735              <tr id="post-<?php echo $post->ID; ?>" class="<?php echo trim( ' author-' . $post_owner . ' status-' . $post->post_status ); ?>">
 736                  <?php $this->single_row_columns( $post ); ?>
 737              </tr>
 738              <?php
 739          endwhile;
 740      }
 741  
 742      /**
 743       * Gets the name of the default primary column.
 744       *
 745       * @since 4.3.0
 746       *
 747       * @return string Name of the default primary column, in this case, 'title'.
 748       */
 749  	protected function get_default_primary_column_name() {
 750          return 'title';
 751      }
 752  
 753      /**
 754       * @param WP_Post $post
 755       * @param string  $att_title
 756       * @return array
 757       */
 758  	private function _get_row_actions( $post, $att_title ) {
 759          $actions = array();
 760  
 761          if ( ! $this->is_trash && current_user_can( 'edit_post', $post->ID ) ) {
 762              $actions['edit'] = sprintf(
 763                  '<a href="%s" aria-label="%s">%s</a>',
 764                  esc_url( get_edit_post_link( $post->ID ) ),
 765                  /* translators: %s: Attachment title. */
 766                  esc_attr( sprintf( __( 'Edit &#8220;%s&#8221;' ), $att_title ) ),
 767                  __( 'Edit' )
 768              );
 769          }
 770  
 771          if ( current_user_can( 'delete_post', $post->ID ) ) {
 772              if ( $this->is_trash ) {
 773                  $actions['untrash'] = sprintf(
 774                      '<a href="%s" class="submitdelete aria-button-if-js" aria-label="%s">%s</a>',
 775                      esc_url( wp_nonce_url( "post.php?action=untrash&amp;post=$post->ID", 'untrash-post_' . $post->ID ) ),
 776                      /* translators: %s: Attachment title. */
 777                      esc_attr( sprintf( __( 'Restore &#8220;%s&#8221; from the Trash' ), $att_title ) ),
 778                      __( 'Restore' )
 779                  );
 780              } elseif ( EMPTY_TRASH_DAYS && MEDIA_TRASH ) {
 781                  $actions['trash'] = sprintf(
 782                      '<a href="%s" class="submitdelete aria-button-if-js" aria-label="%s">%s</a>',
 783                      esc_url( wp_nonce_url( "post.php?action=trash&amp;post=$post->ID", 'trash-post_' . $post->ID ) ),
 784                      /* translators: %s: Attachment title. */
 785                      esc_attr( sprintf( __( 'Move &#8220;%s&#8221; to the Trash' ), $att_title ) ),
 786                      _x( 'Trash', 'verb' )
 787                  );
 788              }
 789  
 790              if ( $this->is_trash || ! EMPTY_TRASH_DAYS || ! MEDIA_TRASH ) {
 791                  $show_confirmation = ( ! $this->is_trash && ! MEDIA_TRASH ) ? " onclick='return showNotice.warn();'" : '';
 792  
 793                  $actions['delete'] = sprintf(
 794                      '<a href="%s" class="submitdelete aria-button-if-js"%s aria-label="%s">%s</a>',
 795                      esc_url( wp_nonce_url( "post.php?action=delete&amp;post=$post->ID", 'delete-post_' . $post->ID ) ),
 796                      $show_confirmation,
 797                      /* translators: %s: Attachment title. */
 798                      esc_attr( sprintf( __( 'Delete &#8220;%s&#8221; permanently' ), $att_title ) ),
 799                      __( 'Delete Permanently' )
 800                  );
 801              }
 802          }
 803  
 804          $attachment_url = wp_get_attachment_url( $post->ID );
 805  
 806          if ( ! $this->is_trash ) {
 807              $permalink = get_permalink( $post->ID );
 808  
 809              if ( $permalink ) {
 810                  $actions['view'] = sprintf(
 811                      '<a href="%s" aria-label="%s" rel="bookmark">%s</a>',
 812                      esc_url( $permalink ),
 813                      /* translators: %s: Attachment title. */
 814                      esc_attr( sprintf( __( 'View &#8220;%s&#8221;' ), $att_title ) ),
 815                      __( 'View' )
 816                  );
 817              }
 818  
 819              if ( $attachment_url ) {
 820                  $actions['copy'] = sprintf(
 821                      '<span class="copy-to-clipboard-container"><button type="button" class="button-link copy-attachment-url media-library" data-clipboard-text="%s" aria-label="%s">%s</button><span class="success hidden" aria-hidden="true">%s</span></span>',
 822                      esc_url( $attachment_url ),
 823                      /* translators: %s: Attachment title. */
 824                      esc_attr( sprintf( __( 'Copy &#8220;%s&#8221; URL to clipboard' ), $att_title ) ),
 825                      __( 'Copy URL' ),
 826                      __( 'Copied!' )
 827                  );
 828              }
 829          }
 830  
 831          if ( $attachment_url ) {
 832              $actions['download'] = sprintf(
 833                  '<a href="%s" aria-label="%s" download>%s</a>',
 834                  esc_url( $attachment_url ),
 835                  /* translators: %s: Attachment title. */
 836                  esc_attr( sprintf( __( 'Download &#8220;%s&#8221;' ), $att_title ) ),
 837                  __( 'Download file' )
 838              );
 839          }
 840  
 841          if ( $this->detached && current_user_can( 'edit_post', $post->ID ) ) {
 842              $actions['attach'] = sprintf(
 843                  '<a href="#the-list" onclick="findPosts.open( \'media[]\', \'%s\' ); return false;" class="hide-if-no-js aria-button-if-js" aria-label="%s">%s</a>',
 844                  $post->ID,
 845                  /* translators: %s: Attachment title. */
 846                  esc_attr( sprintf( __( 'Attach &#8220;%s&#8221; to existing content' ), $att_title ) ),
 847                  __( 'Attach' )
 848              );
 849          }
 850  
 851          /**
 852           * Filters the action links for each attachment in the Media list table.
 853           *
 854           * @since 2.8.0
 855           *
 856           * @param string[] $actions  An array of action links for each attachment.
 857           *                           Includes 'Edit', 'Delete Permanently', 'View',
 858           *                           'Copy URL' and 'Download file'.
 859           * @param WP_Post  $post     WP_Post object for the current attachment.
 860           * @param bool     $detached Whether the list table contains media not attached
 861           *                           to any posts. Default true.
 862           */
 863          return apply_filters( 'media_row_actions', $actions, $post, $this->detached );
 864      }
 865  
 866      /**
 867       * Generates and displays row action links.
 868       *
 869       * @since 4.3.0
 870       * @since 5.9.0 Renamed `$post` to `$item` to match parent class for PHP 8 named parameter support.
 871       *
 872       * @param WP_Post $item        Attachment being acted upon.
 873       * @param string  $column_name Current column name.
 874       * @param string  $primary     Primary column name.
 875       * @return string Row actions output for media attachments, or an empty string
 876       *                if the current column is not the primary column.
 877       */
 878  	protected function handle_row_actions( $item, $column_name, $primary ) {
 879          if ( $primary !== $column_name ) {
 880              return '';
 881          }
 882  
 883          // Restores the more descriptive, specific name for use within this method.
 884          $post = $item;
 885  
 886          $att_title = _draft_or_post_title();
 887          $actions   = $this->_get_row_actions( $post, $att_title );
 888  
 889          return $this->row_actions( $actions );
 890      }
 891  }


Generated : Tue Mar 19 08:20:01 2024 Cross-referenced by PHPXref