164 add_action( 'admin_footer', array( $this, '_js_vars' ) ); |
164 add_action( 'admin_footer', array( $this, '_js_vars' ) ); |
165 } |
165 } |
166 |
166 |
167 if ( empty( $this->modes ) ) { |
167 if ( empty( $this->modes ) ) { |
168 $this->modes = array( |
168 $this->modes = array( |
169 'list' => __( 'List View' ), |
169 'list' => __( 'Compact view' ), |
170 'excerpt' => __( 'Excerpt View' ), |
170 'excerpt' => __( 'Extended view' ), |
171 ); |
171 ); |
172 } |
172 } |
173 } |
173 } |
174 |
174 |
175 /** |
175 /** |
194 * @param string $name Property to check if set. |
194 * @param string $name Property to check if set. |
195 * @param mixed $value Property value. |
195 * @param mixed $value Property value. |
196 * @return mixed Newly-set property. |
196 * @return mixed Newly-set property. |
197 */ |
197 */ |
198 public function __set( $name, $value ) { |
198 public function __set( $name, $value ) { |
199 if ( in_array( $name, $this->compat_fields ) ) { |
199 if ( in_array( $name, $this->compat_fields, true ) ) { |
200 return $this->$name = $value; |
200 return $this->$name = $value; |
201 } |
201 } |
202 } |
202 } |
203 |
203 |
204 /** |
204 /** |
208 * |
208 * |
209 * @param string $name Property to check if set. |
209 * @param string $name Property to check if set. |
210 * @return bool Whether the property is set. |
210 * @return bool Whether the property is set. |
211 */ |
211 */ |
212 public function __isset( $name ) { |
212 public function __isset( $name ) { |
213 if ( in_array( $name, $this->compat_fields ) ) { |
213 if ( in_array( $name, $this->compat_fields, true ) ) { |
214 return isset( $this->$name ); |
214 return isset( $this->$name ); |
215 } |
215 } |
216 } |
216 } |
217 |
217 |
218 /** |
218 /** |
221 * @since 4.0.0 |
221 * @since 4.0.0 |
222 * |
222 * |
223 * @param string $name Property to unset. |
223 * @param string $name Property to unset. |
224 */ |
224 */ |
225 public function __unset( $name ) { |
225 public function __unset( $name ) { |
226 if ( in_array( $name, $this->compat_fields ) ) { |
226 if ( in_array( $name, $this->compat_fields, true ) ) { |
227 unset( $this->$name ); |
227 unset( $this->$name ); |
228 } |
228 } |
229 } |
229 } |
230 |
230 |
231 /** |
231 /** |
232 * Make private/protected methods readable for backward compatibility. |
232 * Make private/protected methods readable for backward compatibility. |
233 * |
233 * |
234 * @since 4.0.0 |
234 * @since 4.0.0 |
235 * |
235 * |
236 * @param string $name Method to call. |
236 * @param string $name Method to call. |
237 * @param array $arguments Arguments to pass when calling. |
237 * @param array $arguments Arguments to pass when calling. |
238 * @return mixed|bool Return value of the callback, false otherwise. |
238 * @return mixed|bool Return value of the callback, false otherwise. |
239 */ |
239 */ |
240 public function __call( $name, $arguments ) { |
240 public function __call( $name, $arguments ) { |
241 if ( in_array( $name, $this->compat_methods ) ) { |
241 if ( in_array( $name, $this->compat_methods, true ) ) { |
242 return call_user_func_array( array( $this, $name ), $arguments ); |
242 return $this->$name( ...$arguments ); |
243 } |
243 } |
244 return false; |
244 return false; |
245 } |
245 } |
246 |
246 |
247 /** |
247 /** |
370 </p> |
370 </p> |
371 <?php |
371 <?php |
372 } |
372 } |
373 |
373 |
374 /** |
374 /** |
375 * Get an associative array ( id => link ) with the list |
375 * Gets the list of views available on this table. |
376 * of views available on this table. |
376 * |
|
377 * The format is an associative array: |
|
378 * - `'id' => 'link'` |
377 * |
379 * |
378 * @since 3.1.0 |
380 * @since 3.1.0 |
379 * |
381 * |
380 * @return array |
382 * @return array |
381 */ |
383 */ |
382 protected function get_views() { |
384 protected function get_views() { |
383 return array(); |
385 return array(); |
384 } |
386 } |
385 |
387 |
386 /** |
388 /** |
387 * Display the list of views available on this table. |
389 * Displays the list of views available on this table. |
388 * |
390 * |
389 * @since 3.1.0 |
391 * @since 3.1.0 |
390 */ |
392 */ |
391 public function views() { |
393 public function views() { |
392 $views = $this->get_views(); |
394 $views = $this->get_views(); |
394 * Filters the list of available list table views. |
396 * Filters the list of available list table views. |
395 * |
397 * |
396 * The dynamic portion of the hook name, `$this->screen->id`, refers |
398 * The dynamic portion of the hook name, `$this->screen->id`, refers |
397 * to the ID of the current screen, usually a string. |
399 * to the ID of the current screen, usually a string. |
398 * |
400 * |
399 * @since 3.5.0 |
401 * @since 3.1.0 |
400 * |
402 * |
401 * @param string[] $views An array of available list table views. |
403 * @param string[] $views An array of available list table views. |
402 */ |
404 */ |
403 $views = apply_filters( "views_{$this->screen->id}", $views ); |
405 $views = apply_filters( "views_{$this->screen->id}", $views ); |
404 |
406 |
415 echo implode( " |</li>\n", $views ) . "</li>\n"; |
417 echo implode( " |</li>\n", $views ) . "</li>\n"; |
416 echo '</ul>'; |
418 echo '</ul>'; |
417 } |
419 } |
418 |
420 |
419 /** |
421 /** |
420 * Get an associative array ( option_name => option_title ) with the list |
422 * Gets the list of bulk actions available on this table. |
421 * of bulk actions available on this table. |
423 * |
|
424 * The format is an associative array: |
|
425 * - `'option_name' => 'option_title'` |
422 * |
426 * |
423 * @since 3.1.0 |
427 * @since 3.1.0 |
424 * |
428 * |
425 * @return array |
429 * @return array |
426 */ |
430 */ |
427 protected function get_bulk_actions() { |
431 protected function get_bulk_actions() { |
428 return array(); |
432 return array(); |
429 } |
433 } |
430 |
434 |
431 /** |
435 /** |
432 * Display the bulk actions dropdown. |
436 * Displays the bulk actions dropdown. |
433 * |
437 * |
434 * @since 3.1.0 |
438 * @since 3.1.0 |
435 * |
439 * |
436 * @param string $which The location of the bulk actions: 'top' or 'bottom'. |
440 * @param string $which The location of the bulk actions: 'top' or 'bottom'. |
437 * This is designated as optional for backward compatibility. |
441 * This is designated as optional for backward compatibility. |
438 */ |
442 */ |
439 protected function bulk_actions( $which = '' ) { |
443 protected function bulk_actions( $which = '' ) { |
440 if ( is_null( $this->_actions ) ) { |
444 if ( is_null( $this->_actions ) ) { |
441 $this->_actions = $this->get_bulk_actions(); |
445 $this->_actions = $this->get_bulk_actions(); |
|
446 |
442 /** |
447 /** |
443 * Filters the list table Bulk Actions drop-down. |
448 * Filters the list table bulk actions drop-down. |
444 * |
449 * |
445 * The dynamic portion of the hook name, `$this->screen->id`, refers |
450 * The dynamic portion of the hook name, `$this->screen->id`, refers |
446 * to the ID of the current screen, usually a string. |
451 * to the ID of the current screen, usually a string. |
447 * |
452 * |
448 * This filter can currently only be used to remove bulk actions. |
453 * @since 3.1.0 |
449 * |
|
450 * @since 3.5.0 |
|
451 * |
454 * |
452 * @param string[] $actions An array of the available bulk actions. |
455 * @param string[] $actions An array of the available bulk actions. |
453 */ |
456 */ |
454 $this->_actions = apply_filters( "bulk_actions-{$this->screen->id}", $this->_actions ); |
457 $this->_actions = apply_filters( "bulk_actions-{$this->screen->id}", $this->_actions ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores |
455 $two = ''; |
458 |
|
459 $two = ''; |
456 } else { |
460 } else { |
457 $two = '2'; |
461 $two = '2'; |
458 } |
462 } |
459 |
463 |
460 if ( empty( $this->_actions ) ) { |
464 if ( empty( $this->_actions ) ) { |
461 return; |
465 return; |
462 } |
466 } |
463 |
467 |
464 echo '<label for="bulk-action-selector-' . esc_attr( $which ) . '" class="screen-reader-text">' . __( 'Select bulk action' ) . '</label>'; |
468 echo '<label for="bulk-action-selector-' . esc_attr( $which ) . '" class="screen-reader-text">' . __( 'Select bulk action' ) . '</label>'; |
465 echo '<select name="action' . $two . '" id="bulk-action-selector-' . esc_attr( $which ) . "\">\n"; |
469 echo '<select name="action' . $two . '" id="bulk-action-selector-' . esc_attr( $which ) . "\">\n"; |
466 echo '<option value="-1">' . __( 'Bulk Actions' ) . "</option>\n"; |
470 echo '<option value="-1">' . __( 'Bulk actions' ) . "</option>\n"; |
467 |
471 |
468 foreach ( $this->_actions as $name => $title ) { |
472 foreach ( $this->_actions as $name => $title ) { |
469 $class = 'edit' === $name ? ' class="hide-if-no-js"' : ''; |
473 $class = 'edit' === $name ? ' class="hide-if-no-js"' : ''; |
470 |
474 |
471 echo "\t" . '<option value="' . $name . '"' . $class . '>' . $title . "</option>\n"; |
475 echo "\t" . '<option value="' . $name . '"' . $class . '>' . $title . "</option>\n"; |
476 submit_button( __( 'Apply' ), 'action', '', false, array( 'id' => "doaction$two" ) ); |
480 submit_button( __( 'Apply' ), 'action', '', false, array( 'id' => "doaction$two" ) ); |
477 echo "\n"; |
481 echo "\n"; |
478 } |
482 } |
479 |
483 |
480 /** |
484 /** |
481 * Get the current action selected from the bulk actions dropdown. |
485 * Gets the current action selected from the bulk actions dropdown. |
482 * |
486 * |
483 * @since 3.1.0 |
487 * @since 3.1.0 |
484 * |
488 * |
485 * @return string|false The action name or False if no action was selected |
489 * @return string|false The action name. False if no action was selected. |
486 */ |
490 */ |
487 public function current_action() { |
491 public function current_action() { |
488 if ( isset( $_REQUEST['filter_action'] ) && ! empty( $_REQUEST['filter_action'] ) ) { |
492 if ( isset( $_REQUEST['filter_action'] ) && ! empty( $_REQUEST['filter_action'] ) ) { |
489 return false; |
493 return false; |
490 } |
494 } |
499 |
503 |
500 return false; |
504 return false; |
501 } |
505 } |
502 |
506 |
503 /** |
507 /** |
504 * Generate row actions div |
508 * Generates the required HTML for a list of row action links. |
505 * |
509 * |
506 * @since 3.1.0 |
510 * @since 3.1.0 |
507 * |
511 * |
508 * @param string[] $actions An array of action links. |
512 * @param string[] $actions An array of action links. |
509 * @param bool $always_visible Whether the actions should be always visible. |
513 * @param bool $always_visible Whether the actions should be always visible. |
510 * @return string |
514 * @return string The HTML for the row actions. |
511 */ |
515 */ |
512 protected function row_actions( $actions, $always_visible = false ) { |
516 protected function row_actions( $actions, $always_visible = false ) { |
513 $action_count = count( $actions ); |
517 $action_count = count( $actions ); |
514 $i = 0; |
|
515 |
518 |
516 if ( ! $action_count ) { |
519 if ( ! $action_count ) { |
517 return ''; |
520 return ''; |
518 } |
521 } |
519 |
522 |
|
523 $mode = get_user_setting( 'posts_list_mode', 'list' ); |
|
524 |
|
525 if ( 'excerpt' === $mode ) { |
|
526 $always_visible = true; |
|
527 } |
|
528 |
520 $out = '<div class="' . ( $always_visible ? 'row-actions visible' : 'row-actions' ) . '">'; |
529 $out = '<div class="' . ( $always_visible ? 'row-actions visible' : 'row-actions' ) . '">'; |
|
530 |
|
531 $i = 0; |
|
532 |
521 foreach ( $actions as $action => $link ) { |
533 foreach ( $actions as $action => $link ) { |
522 ++$i; |
534 ++$i; |
523 ( $i == $action_count ) ? $sep = '' : $sep = ' | '; |
535 |
524 $out .= "<span class='$action'>$link$sep</span>"; |
536 $sep = ( $i < $action_count ) ? ' | ' : ''; |
525 } |
537 |
|
538 $out .= "<span class='$action'>$link$sep</span>"; |
|
539 } |
|
540 |
526 $out .= '</div>'; |
541 $out .= '</div>'; |
527 |
542 |
528 $out .= '<button type="button" class="toggle-row"><span class="screen-reader-text">' . __( 'Show more details' ) . '</span></button>'; |
543 $out .= '<button type="button" class="toggle-row"><span class="screen-reader-text">' . __( 'Show more details' ) . '</span></button>'; |
529 |
544 |
530 return $out; |
545 return $out; |
531 } |
546 } |
532 |
547 |
533 /** |
548 /** |
534 * Display a monthly dropdown for filtering items |
549 * Displays a dropdown for filtering items in the list table by month. |
535 * |
550 * |
536 * @since 3.1.0 |
551 * @since 3.1.0 |
537 * |
552 * |
538 * @global wpdb $wpdb |
553 * @global wpdb $wpdb WordPress database abstraction object. |
539 * @global WP_Locale $wp_locale |
554 * @global WP_Locale $wp_locale WordPress date and time locale object. |
540 * |
555 * |
541 * @param string $post_type |
556 * @param string $post_type The post type. |
542 */ |
557 */ |
543 protected function months_dropdown( $post_type ) { |
558 protected function months_dropdown( $post_type ) { |
544 global $wpdb, $wp_locale; |
559 global $wpdb, $wp_locale; |
545 |
560 |
546 /** |
561 /** |
578 /** |
593 /** |
579 * Filters the 'Months' drop-down results. |
594 * Filters the 'Months' drop-down results. |
580 * |
595 * |
581 * @since 3.7.0 |
596 * @since 3.7.0 |
582 * |
597 * |
583 * @param object $months The months drop-down query results. |
598 * @param object[] $months Array of the months drop-down query results. |
584 * @param string $post_type The post type. |
599 * @param string $post_type The post type. |
585 */ |
600 */ |
586 $months = apply_filters( 'months_dropdown_results', $months, $post_type ); |
601 $months = apply_filters( 'months_dropdown_results', $months, $post_type ); |
587 |
602 |
588 $month_count = count( $months ); |
603 $month_count = count( $months ); |
589 |
604 |
607 |
622 |
608 printf( |
623 printf( |
609 "<option %s value='%s'>%s</option>\n", |
624 "<option %s value='%s'>%s</option>\n", |
610 selected( $m, $year . $month, false ), |
625 selected( $m, $year . $month, false ), |
611 esc_attr( $arc_row->year . $month ), |
626 esc_attr( $arc_row->year . $month ), |
612 /* translators: 1: month name, 2: 4-digit year */ |
627 /* translators: 1: Month name, 2: 4-digit year. */ |
613 sprintf( __( '%1$s %2$d' ), $wp_locale->get_month( $month ), $year ) |
628 sprintf( __( '%1$s %2$d' ), $wp_locale->get_month( $month ), $year ) |
614 ); |
629 ); |
615 } |
630 } |
616 ?> |
631 ?> |
617 </select> |
632 </select> |
618 <?php |
633 <?php |
619 } |
634 } |
620 |
635 |
621 /** |
636 /** |
622 * Display a view switcher |
637 * Displays a view switcher. |
623 * |
638 * |
624 * @since 3.1.0 |
639 * @since 3.1.0 |
625 * |
640 * |
626 * @param string $current_mode |
641 * @param string $current_mode |
627 */ |
642 */ |
629 ?> |
644 ?> |
630 <input type="hidden" name="mode" value="<?php echo esc_attr( $current_mode ); ?>" /> |
645 <input type="hidden" name="mode" value="<?php echo esc_attr( $current_mode ); ?>" /> |
631 <div class="view-switch"> |
646 <div class="view-switch"> |
632 <?php |
647 <?php |
633 foreach ( $this->modes as $mode => $title ) { |
648 foreach ( $this->modes as $mode => $title ) { |
634 $classes = array( 'view-' . $mode ); |
649 $classes = array( 'view-' . $mode ); |
|
650 $aria_current = ''; |
|
651 |
635 if ( $current_mode === $mode ) { |
652 if ( $current_mode === $mode ) { |
636 $classes[] = 'current'; |
653 $classes[] = 'current'; |
|
654 $aria_current = ' aria-current="page"'; |
637 } |
655 } |
|
656 |
638 printf( |
657 printf( |
639 "<a href='%s' class='%s' id='view-switch-$mode'><span class='screen-reader-text'>%s</span></a>\n", |
658 "<a href='%s' class='%s' id='view-switch-$mode'$aria_current><span class='screen-reader-text'>%s</span></a>\n", |
640 esc_url( add_query_arg( 'mode', $mode ) ), |
659 esc_url( remove_query_arg( 'attachment-filter', add_query_arg( 'mode', $mode ) ) ), |
641 implode( ' ', $classes ), |
660 implode( ' ', $classes ), |
642 $title |
661 $title |
643 ); |
662 ); |
644 } |
663 } |
645 ?> |
664 ?> |
646 </div> |
665 </div> |
647 <?php |
666 <?php |
648 } |
667 } |
649 |
668 |
650 /** |
669 /** |
651 * Display a comment count bubble |
670 * Displays a comment count bubble. |
652 * |
671 * |
653 * @since 3.1.0 |
672 * @since 3.1.0 |
654 * |
673 * |
655 * @param int $post_id The post ID. |
674 * @param int $post_id The post ID. |
656 * @param int $pending_comments Number of pending comments. |
675 * @param int $pending_comments Number of pending comments. |
659 $approved_comments = get_comments_number(); |
678 $approved_comments = get_comments_number(); |
660 |
679 |
661 $approved_comments_number = number_format_i18n( $approved_comments ); |
680 $approved_comments_number = number_format_i18n( $approved_comments ); |
662 $pending_comments_number = number_format_i18n( $pending_comments ); |
681 $pending_comments_number = number_format_i18n( $pending_comments ); |
663 |
682 |
664 $approved_only_phrase = sprintf( _n( '%s comment', '%s comments', $approved_comments ), $approved_comments_number ); |
683 $approved_only_phrase = sprintf( |
665 $approved_phrase = sprintf( _n( '%s approved comment', '%s approved comments', $approved_comments ), $approved_comments_number ); |
684 /* translators: %s: Number of comments. */ |
666 $pending_phrase = sprintf( _n( '%s pending comment', '%s pending comments', $pending_comments ), $pending_comments_number ); |
685 _n( '%s comment', '%s comments', $approved_comments ), |
667 |
686 $approved_comments_number |
668 // No comments at all. |
687 ); |
|
688 |
|
689 $approved_phrase = sprintf( |
|
690 /* translators: %s: Number of comments. */ |
|
691 _n( '%s approved comment', '%s approved comments', $approved_comments ), |
|
692 $approved_comments_number |
|
693 ); |
|
694 |
|
695 $pending_phrase = sprintf( |
|
696 /* translators: %s: Number of comments. */ |
|
697 _n( '%s pending comment', '%s pending comments', $pending_comments ), |
|
698 $pending_comments_number |
|
699 ); |
|
700 |
669 if ( ! $approved_comments && ! $pending_comments ) { |
701 if ( ! $approved_comments && ! $pending_comments ) { |
|
702 // No comments at all. |
670 printf( |
703 printf( |
671 '<span aria-hidden="true">—</span><span class="screen-reader-text">%s</span>', |
704 '<span aria-hidden="true">—</span><span class="screen-reader-text">%s</span>', |
672 __( 'No comments' ) |
705 __( 'No comments' ) |
673 ); |
706 ); |
674 // Approved comments have different display depending on some conditions. |
707 } elseif ( $approved_comments && 'trash' === get_post_status( $post_id ) ) { |
|
708 // Don't link the comment bubble for a trashed post. |
|
709 printf( |
|
710 '<span class="post-com-count post-com-count-approved"><span class="comment-count-approved" aria-hidden="true">%s</span><span class="screen-reader-text">%s</span></span>', |
|
711 $approved_comments_number, |
|
712 $pending_comments ? $approved_phrase : $approved_only_phrase |
|
713 ); |
675 } elseif ( $approved_comments ) { |
714 } elseif ( $approved_comments ) { |
|
715 // Link the comment bubble to approved comments. |
676 printf( |
716 printf( |
677 '<a href="%s" class="post-com-count post-com-count-approved"><span class="comment-count-approved" aria-hidden="true">%s</span><span class="screen-reader-text">%s</span></a>', |
717 '<a href="%s" class="post-com-count post-com-count-approved"><span class="comment-count-approved" aria-hidden="true">%s</span><span class="screen-reader-text">%s</span></a>', |
678 esc_url( |
718 esc_url( |
679 add_query_arg( |
719 add_query_arg( |
680 array( |
720 array( |
686 ), |
726 ), |
687 $approved_comments_number, |
727 $approved_comments_number, |
688 $pending_comments ? $approved_phrase : $approved_only_phrase |
728 $pending_comments ? $approved_phrase : $approved_only_phrase |
689 ); |
729 ); |
690 } else { |
730 } else { |
|
731 // Don't link the comment bubble when there are no approved comments. |
691 printf( |
732 printf( |
692 '<span class="post-com-count post-com-count-no-comments"><span class="comment-count comment-count-no-comments" aria-hidden="true">%s</span><span class="screen-reader-text">%s</span></span>', |
733 '<span class="post-com-count post-com-count-no-comments"><span class="comment-count comment-count-no-comments" aria-hidden="true">%s</span><span class="screen-reader-text">%s</span></span>', |
693 $approved_comments_number, |
734 $approved_comments_number, |
694 $pending_comments ? __( 'No approved comments' ) : __( 'No comments' ) |
735 $pending_comments ? __( 'No approved comments' ) : __( 'No comments' ) |
695 ); |
736 ); |
752 } |
793 } |
753 |
794 |
754 /** |
795 /** |
755 * Filters the number of items to be displayed on each page of the list table. |
796 * Filters the number of items to be displayed on each page of the list table. |
756 * |
797 * |
757 * The dynamic hook name, $option, refers to the `per_page` option depending |
798 * The dynamic hook name, `$option`, refers to the `per_page` option depending |
758 * on the type of list table in use. Possible values include: 'edit_comments_per_page', |
799 * on the type of list table in use. Possible filter names include: |
759 * 'sites_network_per_page', 'site_themes_network_per_page', 'themes_network_per_page', |
800 * |
760 * 'users_network_per_page', 'edit_post_per_page', 'edit_page_per_page', |
801 * - `edit_comments_per_page` |
761 * 'edit_{$post_type}_per_page', etc. |
802 * - `sites_network_per_page` |
|
803 * - `site_themes_network_per_page` |
|
804 * - `themes_network_per_page'` |
|
805 * - `users_network_per_page` |
|
806 * - `edit_post_per_page` |
|
807 * - `edit_page_per_page'` |
|
808 * - `edit_{$post_type}_per_page` |
|
809 * - `edit_post_tag_per_page` |
|
810 * - `edit_category_per_page` |
|
811 * - `edit_{$taxonomy}_per_page` |
|
812 * - `site_users_network_per_page` |
|
813 * - `users_per_page` |
762 * |
814 * |
763 * @since 2.9.0 |
815 * @since 2.9.0 |
764 * |
816 * |
765 * @param int $per_page Number of items to be displayed. Default 20. |
817 * @param int $per_page Number of items to be displayed. Default 20. |
766 */ |
818 */ |
767 return (int) apply_filters( "{$option}", $per_page ); |
819 return (int) apply_filters( "{$option}", $per_page ); |
768 } |
820 } |
769 |
821 |
770 /** |
822 /** |
771 * Display the pagination. |
823 * Displays the pagination. |
772 * |
824 * |
773 * @since 3.1.0 |
825 * @since 3.1.0 |
774 * |
826 * |
775 * @param string $which |
827 * @param string $which |
776 */ |
828 */ |
788 |
840 |
789 if ( 'top' === $which && $total_pages > 1 ) { |
841 if ( 'top' === $which && $total_pages > 1 ) { |
790 $this->screen->render_screen_reader_content( 'heading_pagination' ); |
842 $this->screen->render_screen_reader_content( 'heading_pagination' ); |
791 } |
843 } |
792 |
844 |
793 $output = '<span class="displaying-num">' . sprintf( _n( '%s item', '%s items', $total_items ), number_format_i18n( $total_items ) ) . '</span>'; |
845 $output = '<span class="displaying-num">' . sprintf( |
|
846 /* translators: %s: Number of items. */ |
|
847 _n( '%s item', '%s items', $total_items ), |
|
848 number_format_i18n( $total_items ) |
|
849 ) . '</span>'; |
794 |
850 |
795 $current = $this->get_pagenum(); |
851 $current = $this->get_pagenum(); |
796 $removable_query_args = wp_removable_query_args(); |
852 $removable_query_args = wp_removable_query_args(); |
797 |
853 |
798 $current_url = set_url_scheme( 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] ); |
854 $current_url = set_url_scheme( 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] ); |
802 $page_links = array(); |
858 $page_links = array(); |
803 |
859 |
804 $total_pages_before = '<span class="paging-input">'; |
860 $total_pages_before = '<span class="paging-input">'; |
805 $total_pages_after = '</span></span>'; |
861 $total_pages_after = '</span></span>'; |
806 |
862 |
807 $disable_first = $disable_last = $disable_prev = $disable_next = false; |
863 $disable_first = false; |
808 |
864 $disable_last = false; |
809 if ( $current == 1 ) { |
865 $disable_prev = false; |
|
866 $disable_next = false; |
|
867 |
|
868 if ( 1 == $current ) { |
810 $disable_first = true; |
869 $disable_first = true; |
811 $disable_prev = true; |
870 $disable_prev = true; |
812 } |
871 } |
813 if ( $current == 2 ) { |
872 if ( 2 == $current ) { |
814 $disable_first = true; |
873 $disable_first = true; |
815 } |
874 } |
816 if ( $current == $total_pages ) { |
875 if ( $total_pages == $current ) { |
817 $disable_last = true; |
876 $disable_last = true; |
818 $disable_next = true; |
877 $disable_next = true; |
819 } |
878 } |
820 if ( $current == $total_pages - 1 ) { |
879 if ( $total_pages - 1 == $current ) { |
821 $disable_last = true; |
880 $disable_last = true; |
822 } |
881 } |
823 |
882 |
824 if ( $disable_first ) { |
883 if ( $disable_first ) { |
825 $page_links[] = '<span class="tablenav-pages-navspan button disabled" aria-hidden="true">«</span>'; |
884 $page_links[] = '<span class="tablenav-pages-navspan button disabled" aria-hidden="true">«</span>'; |
853 $current, |
912 $current, |
854 strlen( $total_pages ) |
913 strlen( $total_pages ) |
855 ); |
914 ); |
856 } |
915 } |
857 $html_total_pages = sprintf( "<span class='total-pages'>%s</span>", number_format_i18n( $total_pages ) ); |
916 $html_total_pages = sprintf( "<span class='total-pages'>%s</span>", number_format_i18n( $total_pages ) ); |
858 $page_links[] = $total_pages_before . sprintf( _x( '%1$s of %2$s', 'paging' ), $html_current_page, $html_total_pages ) . $total_pages_after; |
917 $page_links[] = $total_pages_before . sprintf( |
|
918 /* translators: 1: Current page, 2: Total pages. */ |
|
919 _x( '%1$s of %2$s', 'paging' ), |
|
920 $html_current_page, |
|
921 $html_total_pages |
|
922 ) . $total_pages_after; |
859 |
923 |
860 if ( $disable_next ) { |
924 if ( $disable_next ) { |
861 $page_links[] = '<span class="tablenav-pages-navspan button disabled" aria-hidden="true">›</span>'; |
925 $page_links[] = '<span class="tablenav-pages-navspan button disabled" aria-hidden="true">›</span>'; |
862 } else { |
926 } else { |
863 $page_links[] = sprintf( |
927 $page_links[] = sprintf( |
894 |
958 |
895 echo $this->_pagination; |
959 echo $this->_pagination; |
896 } |
960 } |
897 |
961 |
898 /** |
962 /** |
899 * Get a list of columns. The format is: |
963 * Gets a list of columns. |
900 * 'internal-name' => 'Title' |
964 * |
|
965 * The format is: |
|
966 * - `'internal-name' => 'Title'` |
901 * |
967 * |
902 * @since 3.1.0 |
968 * @since 3.1.0 |
903 * @abstract |
969 * @abstract |
904 * |
970 * |
905 * @return array |
971 * @return array |
906 */ |
972 */ |
907 public function get_columns() { |
973 public function get_columns() { |
908 die( 'function WP_List_Table::get_columns() must be over-ridden in a sub-class.' ); |
974 die( 'function WP_List_Table::get_columns() must be overridden in a subclass.' ); |
909 } |
975 } |
910 |
976 |
911 /** |
977 /** |
912 * Get a list of sortable columns. The format is: |
978 * Gets a list of sortable columns. |
913 * 'internal-name' => 'orderby' |
979 * |
914 * or |
980 * The format is: |
915 * 'internal-name' => array( 'orderby', true ) |
981 * - `'internal-name' => 'orderby'` |
916 * |
982 * - `'internal-name' => array( 'orderby', 'asc' )` - The second element sets the initial sorting order. |
917 * The second format will make the initial sorting order be descending |
983 * - `'internal-name' => array( 'orderby', true )` - The second element makes the initial order descending. |
918 * |
984 * |
919 * @since 3.1.0 |
985 * @since 3.1.0 |
920 * |
986 * |
921 * @return array |
987 * @return array |
922 */ |
988 */ |
973 */ |
1039 */ |
974 protected function get_primary_column_name() { |
1040 protected function get_primary_column_name() { |
975 $columns = get_column_headers( $this->screen ); |
1041 $columns = get_column_headers( $this->screen ); |
976 $default = $this->get_default_primary_column_name(); |
1042 $default = $this->get_default_primary_column_name(); |
977 |
1043 |
978 // If the primary column doesn't exist fall back to the |
1044 // If the primary column doesn't exist, |
979 // first non-checkbox column. |
1045 // fall back to the first non-checkbox column. |
980 if ( ! isset( $columns[ $default ] ) ) { |
1046 if ( ! isset( $columns[ $default ] ) ) { |
981 $default = WP_List_Table::get_default_primary_column_name(); |
1047 $default = WP_List_Table::get_default_primary_column_name(); |
982 } |
1048 } |
983 |
1049 |
984 /** |
1050 /** |
997 |
1063 |
998 return $column; |
1064 return $column; |
999 } |
1065 } |
1000 |
1066 |
1001 /** |
1067 /** |
1002 * Get a list of all, hidden and sortable columns, with filter applied |
1068 * Gets a list of all, hidden and sortable columns, with filter applied. |
1003 * |
1069 * |
1004 * @since 3.1.0 |
1070 * @since 3.1.0 |
1005 * |
1071 * |
1006 * @return array |
1072 * @return array |
1007 */ |
1073 */ |
1008 protected function get_column_info() { |
1074 protected function get_column_info() { |
1009 // $_column_headers is already set / cached |
1075 // $_column_headers is already set / cached. |
1010 if ( isset( $this->_column_headers ) && is_array( $this->_column_headers ) ) { |
1076 if ( isset( $this->_column_headers ) && is_array( $this->_column_headers ) ) { |
1011 // Back-compat for list tables that have been manually setting $_column_headers for horse reasons. |
1077 // Back-compat for list tables that have been manually setting $_column_headers for horse reasons. |
1012 // In 4.3, we added a fourth argument for primary column. |
1078 // In 4.3, we added a fourth argument for primary column. |
1013 $column_headers = array( array(), array(), array(), $this->get_primary_column_name() ); |
1079 $column_headers = array( array(), array(), array(), $this->get_primary_column_name() ); |
1014 foreach ( $this->_column_headers as $key => $value ) { |
1080 foreach ( $this->_column_headers as $key => $value ) { |
1026 * Filters the list table sortable columns for a specific screen. |
1092 * Filters the list table sortable columns for a specific screen. |
1027 * |
1093 * |
1028 * The dynamic portion of the hook name, `$this->screen->id`, refers |
1094 * The dynamic portion of the hook name, `$this->screen->id`, refers |
1029 * to the ID of the current screen, usually a string. |
1095 * to the ID of the current screen, usually a string. |
1030 * |
1096 * |
1031 * @since 3.5.0 |
1097 * @since 3.1.0 |
1032 * |
1098 * |
1033 * @param array $sortable_columns An array of sortable columns. |
1099 * @param array $sortable_columns An array of sortable columns. |
1034 */ |
1100 */ |
1035 $_sortable = apply_filters( "manage_{$this->screen->id}_sortable_columns", $sortable_columns ); |
1101 $_sortable = apply_filters( "manage_{$this->screen->id}_sortable_columns", $sortable_columns ); |
1036 |
1102 |
1066 $hidden = array_intersect( array_keys( $columns ), array_filter( $hidden ) ); |
1132 $hidden = array_intersect( array_keys( $columns ), array_filter( $hidden ) ); |
1067 return count( $columns ) - count( $hidden ); |
1133 return count( $columns ) - count( $hidden ); |
1068 } |
1134 } |
1069 |
1135 |
1070 /** |
1136 /** |
1071 * Print column headers, accounting for hidden and sortable columns. |
1137 * Prints column headers, accounting for hidden and sortable columns. |
1072 * |
1138 * |
1073 * @since 3.1.0 |
1139 * @since 3.1.0 |
1074 * |
1140 * |
1075 * @staticvar int $cb_counter |
1141 * @param bool $with_id Whether to set the ID attribute or not |
1076 * |
|
1077 * @param bool $with_id Whether to set the id attribute or not |
|
1078 */ |
1142 */ |
1079 public function print_column_headers( $with_id = true ) { |
1143 public function print_column_headers( $with_id = true ) { |
1080 list( $columns, $hidden, $sortable, $primary ) = $this->get_column_info(); |
1144 list( $columns, $hidden, $sortable, $primary ) = $this->get_column_info(); |
1081 |
1145 |
1082 $current_url = set_url_scheme( 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] ); |
1146 $current_url = set_url_scheme( 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] ); |
1102 } |
1166 } |
1103 |
1167 |
1104 foreach ( $columns as $column_key => $column_display_name ) { |
1168 foreach ( $columns as $column_key => $column_display_name ) { |
1105 $class = array( 'manage-column', "column-$column_key" ); |
1169 $class = array( 'manage-column', "column-$column_key" ); |
1106 |
1170 |
1107 if ( in_array( $column_key, $hidden ) ) { |
1171 if ( in_array( $column_key, $hidden, true ) ) { |
1108 $class[] = 'hidden'; |
1172 $class[] = 'hidden'; |
1109 } |
1173 } |
1110 |
1174 |
1111 if ( 'cb' === $column_key ) { |
1175 if ( 'cb' === $column_key ) { |
1112 $class[] = 'check-column'; |
1176 $class[] = 'check-column'; |
1113 } elseif ( in_array( $column_key, array( 'posts', 'comments', 'links' ) ) ) { |
1177 } elseif ( in_array( $column_key, array( 'posts', 'comments', 'links' ), true ) ) { |
1114 $class[] = 'num'; |
1178 $class[] = 'num'; |
1115 } |
1179 } |
1116 |
1180 |
1117 if ( $column_key === $primary ) { |
1181 if ( $column_key === $primary ) { |
1118 $class[] = 'column-primary'; |
1182 $class[] = 'column-primary'; |
1120 |
1184 |
1121 if ( isset( $sortable[ $column_key ] ) ) { |
1185 if ( isset( $sortable[ $column_key ] ) ) { |
1122 list( $orderby, $desc_first ) = $sortable[ $column_key ]; |
1186 list( $orderby, $desc_first ) = $sortable[ $column_key ]; |
1123 |
1187 |
1124 if ( $current_orderby === $orderby ) { |
1188 if ( $current_orderby === $orderby ) { |
1125 $order = 'asc' === $current_order ? 'desc' : 'asc'; |
1189 $order = 'asc' === $current_order ? 'desc' : 'asc'; |
|
1190 |
1126 $class[] = 'sorted'; |
1191 $class[] = 'sorted'; |
1127 $class[] = $current_order; |
1192 $class[] = $current_order; |
1128 } else { |
1193 } else { |
1129 $order = $desc_first ? 'desc' : 'asc'; |
1194 $order = strtolower( $desc_first ); |
|
1195 |
|
1196 if ( ! in_array( $order, array( 'desc', 'asc' ), true ) ) { |
|
1197 $order = $desc_first ? 'desc' : 'asc'; |
|
1198 } |
|
1199 |
1130 $class[] = 'sortable'; |
1200 $class[] = 'sortable'; |
1131 $class[] = $desc_first ? 'asc' : 'desc'; |
1201 $class[] = 'desc' === $order ? 'asc' : 'desc'; |
1132 } |
1202 } |
1133 |
1203 |
1134 $column_display_name = '<a href="' . esc_url( add_query_arg( compact( 'orderby', 'order' ), $current_url ) ) . '"><span>' . $column_display_name . '</span><span class="sorting-indicator"></span></a>'; |
1204 $column_display_name = sprintf( |
|
1205 '<a href="%s"><span>%s</span><span class="sorting-indicator"></span></a>', |
|
1206 esc_url( add_query_arg( compact( 'orderby', 'order' ), $current_url ) ), |
|
1207 $column_display_name |
|
1208 ); |
1135 } |
1209 } |
1136 |
1210 |
1137 $tag = ( 'cb' === $column_key ) ? 'td' : 'th'; |
1211 $tag = ( 'cb' === $column_key ) ? 'td' : 'th'; |
1138 $scope = ( 'th' === $tag ) ? 'scope="col"' : ''; |
1212 $scope = ( 'th' === $tag ) ? 'scope="col"' : ''; |
1139 $id = $with_id ? "id='$column_key'" : ''; |
1213 $id = $with_id ? "id='$column_key'" : ''; |
1185 <?php |
1259 <?php |
1186 $this->display_tablenav( 'bottom' ); |
1260 $this->display_tablenav( 'bottom' ); |
1187 } |
1261 } |
1188 |
1262 |
1189 /** |
1263 /** |
1190 * Get a list of CSS classes for the WP_List_Table table tag. |
1264 * Gets a list of CSS classes for the WP_List_Table table tag. |
1191 * |
1265 * |
1192 * @since 3.1.0 |
1266 * @since 3.1.0 |
1193 * |
1267 * |
1194 * @return array List of CSS classes for the table tag. |
1268 * @return string[] Array of CSS classes for the table tag. |
1195 */ |
1269 */ |
1196 protected function get_table_classes() { |
1270 protected function get_table_classes() { |
1197 return array( 'widefat', 'fixed', 'striped', $this->_args['plural'] ); |
1271 $mode = get_user_setting( 'posts_list_mode', 'list' ); |
1198 } |
1272 |
1199 |
1273 $mode_class = esc_attr( 'table-view-' . $mode ); |
1200 /** |
1274 |
1201 * Generate the table navigation above or below the table |
1275 return array( 'widefat', 'fixed', 'striped', $mode_class, $this->_args['plural'] ); |
|
1276 } |
|
1277 |
|
1278 /** |
|
1279 * Generates the table navigation above or below the table |
1202 * |
1280 * |
1203 * @since 3.1.0 |
1281 * @since 3.1.0 |
1204 * @param string $which |
1282 * @param string $which |
1205 */ |
1283 */ |
1206 protected function display_tablenav( $which ) { |
1284 protected function display_tablenav( $which ) { |
1224 </div> |
1302 </div> |
1225 <?php |
1303 <?php |
1226 } |
1304 } |
1227 |
1305 |
1228 /** |
1306 /** |
1229 * Extra controls to be displayed between bulk actions and pagination |
1307 * Extra controls to be displayed between bulk actions and pagination. |
1230 * |
1308 * |
1231 * @since 3.1.0 |
1309 * @since 3.1.0 |
1232 * |
1310 * |
1233 * @param string $which |
1311 * @param string $which |
1234 */ |
1312 */ |
1235 protected function extra_tablenav( $which ) {} |
1313 protected function extra_tablenav( $which ) {} |
1236 |
1314 |
1237 /** |
1315 /** |
1238 * Generate the tbody element for the list table. |
1316 * Generates the tbody element for the list table. |
1239 * |
1317 * |
1240 * @since 3.1.0 |
1318 * @since 3.1.0 |
1241 */ |
1319 */ |
1242 public function display_rows_or_placeholder() { |
1320 public function display_rows_or_placeholder() { |
1243 if ( $this->has_items() ) { |
1321 if ( $this->has_items() ) { |
1283 * @param object $item |
1361 * @param object $item |
1284 */ |
1362 */ |
1285 protected function column_cb( $item ) {} |
1363 protected function column_cb( $item ) {} |
1286 |
1364 |
1287 /** |
1365 /** |
1288 * Generates the columns for a single row of the table |
1366 * Generates the columns for a single row of the table. |
1289 * |
1367 * |
1290 * @since 3.1.0 |
1368 * @since 3.1.0 |
1291 * |
1369 * |
1292 * @param object $item The current item |
1370 * @param object $item The current item. |
1293 */ |
1371 */ |
1294 protected function single_row_columns( $item ) { |
1372 protected function single_row_columns( $item ) { |
1295 list( $columns, $hidden, $sortable, $primary ) = $this->get_column_info(); |
1373 list( $columns, $hidden, $sortable, $primary ) = $this->get_column_info(); |
1296 |
1374 |
1297 foreach ( $columns as $column_name => $column_display_name ) { |
1375 foreach ( $columns as $column_name => $column_display_name ) { |
1298 $classes = "$column_name column-$column_name"; |
1376 $classes = "$column_name column-$column_name"; |
1299 if ( $primary === $column_name ) { |
1377 if ( $primary === $column_name ) { |
1300 $classes .= ' has-row-actions column-primary'; |
1378 $classes .= ' has-row-actions column-primary'; |
1301 } |
1379 } |
1302 |
1380 |
1303 if ( in_array( $column_name, $hidden ) ) { |
1381 if ( in_array( $column_name, $hidden, true ) ) { |
1304 $classes .= ' hidden'; |
1382 $classes .= ' hidden'; |
1305 } |
1383 } |
1306 |
1384 |
1307 // Comments column uses HTML in the display name with screen reader text. |
1385 // Comments column uses HTML in the display name with screen reader text. |
1308 // Instead of using esc_attr(), we strip tags to get closer to a user-friendly string. |
1386 // Instead of using esc_attr(), we strip tags to get closer to a user-friendly string. |
1342 * @since 4.3.0 |
1420 * @since 4.3.0 |
1343 * |
1421 * |
1344 * @param object $item The item being acted upon. |
1422 * @param object $item The item being acted upon. |
1345 * @param string $column_name Current column name. |
1423 * @param string $column_name Current column name. |
1346 * @param string $primary Primary column name. |
1424 * @param string $primary Primary column name. |
1347 * @return string The row actions HTML, or an empty string if the current column is the primary column. |
1425 * @return string The row actions HTML, or an empty string |
|
1426 * if the current column is not the primary column. |
1348 */ |
1427 */ |
1349 protected function handle_row_actions( $item, $column_name, $primary ) { |
1428 protected function handle_row_actions( $item, $column_name, $primary ) { |
1350 return $column_name === $primary ? '<button type="button" class="toggle-row"><span class="screen-reader-text">' . __( 'Show more details' ) . '</span></button>' : ''; |
1429 return $column_name === $primary ? '<button type="button" class="toggle-row"><span class="screen-reader-text">' . __( 'Show more details' ) . '</span></button>' : ''; |
1351 } |
1430 } |
1352 |
1431 |
1353 /** |
1432 /** |
1354 * Handle an incoming ajax request (called from admin-ajax.php) |
1433 * Handles an incoming ajax request (called from admin-ajax.php) |
1355 * |
1434 * |
1356 * @since 3.1.0 |
1435 * @since 3.1.0 |
1357 */ |
1436 */ |
1358 public function ajax_response() { |
1437 public function ajax_response() { |
1359 $this->prepare_items(); |
1438 $this->prepare_items(); |
1369 |
1448 |
1370 $response = array( 'rows' => $rows ); |
1449 $response = array( 'rows' => $rows ); |
1371 |
1450 |
1372 if ( isset( $this->_pagination_args['total_items'] ) ) { |
1451 if ( isset( $this->_pagination_args['total_items'] ) ) { |
1373 $response['total_items_i18n'] = sprintf( |
1452 $response['total_items_i18n'] = sprintf( |
|
1453 /* translators: Number of items. */ |
1374 _n( '%s item', '%s items', $this->_pagination_args['total_items'] ), |
1454 _n( '%s item', '%s items', $this->_pagination_args['total_items'] ), |
1375 number_format_i18n( $this->_pagination_args['total_items'] ) |
1455 number_format_i18n( $this->_pagination_args['total_items'] ) |
1376 ); |
1456 ); |
1377 } |
1457 } |
1378 if ( isset( $this->_pagination_args['total_pages'] ) ) { |
1458 if ( isset( $this->_pagination_args['total_pages'] ) ) { |