Make WordPress Core

Ticket #29881: wp-posts-list-table-2.diff

File wp-posts-list-table-2.diff, 28.0 KB (added by joehoyle, 11 years ago)
  • src/wp-admin/includes/class-wp-posts-list-table.php

     
    4646        private $sticky_posts_count = 0;
    4747
    4848        /**
     49         * Stores the current row's level.
     50         *
     51         * As WP_List_Table doesn't have a concept of hierarchical rows, we have
     52         * to store the row level so it can be accessed by the column_$column_name methods.
     53         * @var integer
     54         */
     55        private $row_level = 0;
     56
     57        /**
    4958         * Constructor.
    50          *
     59         * 
    5160         * @since 3.1.0
    5261         * @access public
    5362         *
     
    542551                unset( $children_pages[$parent] ); //required in order to keep track of orphans
    543552        }
    544553
    545         public function single_row( $post, $level = 0 ) {
     554        /**
     555         * Display the Checkbox column, only if the user can edit the post
     556         *
     557         * @param  WP_Post $post
     558         * @return null
     559         */
     560        public function column_cb( $post ) {
     561
     562                if ( ! current_user_can( 'edit_post', $post->ID ) ) {
     563                        return '';
     564                }
     565
     566                ?>
     567                <label class="screen-reader-text" for="cb-select-<?php echo esc_attr( $post->ID ); ?>"><?php printf( __( 'Select %s' ), _draft_or_post_title( $post ) ); ?></label>
     568                <input id="cb-select-<?php the_ID(); ?>" type="checkbox" name="post[]" value="<?php echo esc_attr( $post->ID ); ?>" />
     569                <div class="locked-indicator"></div>
     570                <?php
     571        }
     572
     573        /**
     574         * Display the title column for a post
     575         *
     576         * @param  WP_Post $post
     577         * @return null
     578         */
     579        public function column_title( $post ) {
     580
    546581                global $mode;
    547                 static $alternate;
    548582
    549                 $global_post = get_post();
    550                 $GLOBALS['post'] = $post;
    551                 setup_postdata( $post );
    552 
     583                $level = $this->row_level;
    553584                $edit_link = get_edit_post_link( $post->ID );
    554585                $title = _draft_or_post_title();
    555586                $post_type_object = get_post_type_object( $post->post_type );
    556587                $can_edit_post = current_user_can( 'edit_post', $post->ID );
     588                $lock_holder = wp_check_post_lock( $post->ID );
    557589
    558                 $alternate = 'alternate' == $alternate ? '' : 'alternate';
    559                 $classes = $alternate . ' iedit author-' . ( get_current_user_id() == $post->post_author ? 'self' : 'other' );
     590                if ( $this->hierarchical_display ) {
     591                        if ( 0 == $level && (int) $post->post_parent > 0 ) {
     592                                // Sent level 0 by accident, by default, or because we don't know the actual level.
     593                                $find_main_page = (int) $post->post_parent;
     594                                while ( $find_main_page > 0 ) {
     595                                        $parent = get_post( $find_main_page );
    560596
    561                 $lock_holder = wp_check_post_lock( $post->ID );
    562                 if ( $lock_holder ) {
    563                         $classes .= ' wp-locked';
    564                         $lock_holder = get_userdata( $lock_holder );
     597                                        if ( is_null( $parent ) )
     598                                                break;
     599
     600                                        $level++;
     601                                        $find_main_page = (int) $parent->post_parent;
     602
     603                                        if ( !isset( $parent_name ) ) {
     604                                                /** This filter is documented in wp-includes/post-template.php */
     605                                                $parent_name = apply_filters( 'the_title', $parent->post_title, $parent->ID );
     606                                        }
     607                                }
     608                        }
    565609                }
    566610
    567                 if ( $post->post_parent ) {
    568                     $count = count( get_post_ancestors( $post->ID ) );
    569                     $classes .= ' level-'. $count;
     611                $pad = str_repeat( '&#8212; ', $level );
     612
     613                echo "<strong>";
     614
     615                if ( $format = get_post_format( $post->ID ) ) {
     616                        $label = get_post_format_string( $format );
     617
     618                        echo '<a href="' . esc_url( add_query_arg( array( 'post_format' => $format, 'post_type' => $post->post_type ), 'edit.php' ) ) . '" class="post-state-format post-format-icon post-format-' . $format . '" title="' . $label . '">' . $label . ":</a> ";
     619                }
     620
     621                if ( $can_edit_post && $post->post_status != 'trash' ) {
     622                        echo '<a class="row-title" href="' . $edit_link . '" title="' . esc_attr( sprintf( __( 'Edit &#8220;%s&#8221;' ), $title ) ) . '">' . $pad . $title . '</a>';
    570623                } else {
    571                     $classes .= ' level-0';
     624                        echo $pad . $title;
    572625                }
    573         ?>
    574                 <tr id="post-<?php echo $post->ID; ?>" class="<?php echo implode( ' ', get_post_class( $classes, $post->ID ) ); ?>">
    575         <?php
     626                _post_states( $post );
    576627
    577                 list( $columns, $hidden ) = $this->get_column_info();
     628                if ( isset( $parent_name ) )
     629                        echo ' | ' . $post_type_object->labels->parent_item_colon . ' ' . esc_html( $parent_name );
    578630
    579                 foreach ( $columns as $column_name => $column_display_name ) {
    580                         $class = "class=\"$column_name column-$column_name\"";
     631                echo "</strong>\n";
    581632
    582                         $style = '';
    583                         if ( in_array( $column_name, $hidden ) )
    584                                 $style = ' style="display:none;"';
     633                if ( $can_edit_post && $post->post_status != 'trash' ) {
     634                        if ( $lock_holder ) {
     635                                $locked_avatar = get_avatar( $lock_holder->ID, 18 );
     636                                $locked_text = esc_html( sprintf( __( '%s is currently editing' ), $lock_holder->display_name ) );
     637                        } else {
     638                                $locked_avatar = $locked_text = '';
     639                        }
    585640
    586                         $attributes = "$class$style";
     641                        echo '<div class="locked-info"><span class="locked-avatar">' . $locked_avatar . '</span> <span class="locked-text">' . $locked_text . "</span></div>\n";
     642                }
    587643
    588                         switch ( $column_name ) {
     644                if ( ! $this->hierarchical_display && 'excerpt' == $mode && current_user_can( 'read_post', $post->ID ) ) {
     645                        the_excerpt();
     646                }
    589647
    590                         case 'cb':
    591                         ?>
    592                         <th scope="row" class="check-column">
    593                                 <?php
     648                $actions = array();
     649                if ( $can_edit_post && 'trash' != $post->post_status ) {
     650                        $actions['edit'] = '<a href="' . get_edit_post_link( $post->ID, true ) . '" title="' . esc_attr__( 'Edit this item' ) . '">' . __( 'Edit' ) . '</a>';
     651                        $actions['inline hide-if-no-js'] = '<a href="#" class="editinline" title="' . esc_attr__( 'Edit this item inline' ) . '">' . __( 'Quick&nbsp;Edit' ) . '</a>';
     652                }
     653                if ( current_user_can( 'delete_post', $post->ID ) ) {
     654                        if ( 'trash' == $post->post_status )
     655                                $actions['untrash'] = "<a title='" . esc_attr__( 'Restore this item from the Trash' ) . "' href='" . wp_nonce_url( admin_url( sprintf( $post_type_object->_edit_link . '&amp;action=untrash', $post->ID ) ), 'untrash-post_' . $post->ID ) . "'>" . __( 'Restore' ) . "</a>";
     656                        elseif ( EMPTY_TRASH_DAYS )
     657                                $actions['trash'] = "<a class='submitdelete' title='" . esc_attr__( 'Move this item to the Trash' ) . "' href='" . get_delete_post_link( $post->ID ) . "'>" . __( 'Trash' ) . "</a>";
     658                        if ( 'trash' == $post->post_status || !EMPTY_TRASH_DAYS )
     659                                $actions['delete'] = "<a class='submitdelete' title='" . esc_attr__( 'Delete this item permanently' ) . "' href='" . get_delete_post_link( $post->ID, '', true ) . "'>" . __( 'Delete Permanently' ) . "</a>";
     660                }
     661                if ( $post_type_object->public ) {
     662                        if ( in_array( $post->post_status, array( 'pending', 'draft', 'future' ) ) ) {
    594663                                if ( $can_edit_post ) {
    595 
    596                                 ?>
    597                                 <label class="screen-reader-text" for="cb-select-<?php the_ID(); ?>"><?php printf( __( 'Select %s' ), $title ); ?></label>
    598                                 <input id="cb-select-<?php the_ID(); ?>" type="checkbox" name="post[]" value="<?php the_ID(); ?>" />
    599                                 <div class="locked-indicator"></div>
    600                                 <?php
     664                                        $preview_link = set_url_scheme( get_permalink( $post->ID ) );
     665                                        /** This filter is documented in wp-admin/includes/meta-boxes.php */
     666                                        $preview_link = apply_filters( 'preview_post_link', add_query_arg( 'preview', 'true', $preview_link ), $post );
     667                                        $actions['view'] = '<a href="' . esc_url( $preview_link ) . '" title="' . esc_attr( sprintf( __( 'Preview &#8220;%s&#8221;' ), $title ) ) . '" rel="permalink">' . __( 'Preview' ) . '</a>';
    601668                                }
    602                                 ?>
    603                         </th>
    604                         <?php
    605                         break;
     669                        } elseif ( 'trash' != $post->post_status ) {
     670                                $actions['view'] = '<a href="' . get_permalink( $post->ID ) . '" title="' . esc_attr( sprintf( __( 'View &#8220;%s&#8221;' ), $title ) ) . '" rel="permalink">' . __( 'View' ) . '</a>';
     671                        }
     672                }
    606673
    607                         case 'title':
    608                                 $attributes = 'class="post-title page-title column-title"' . $style;
    609                                 if ( $this->hierarchical_display ) {
    610                                         if ( 0 == $level && (int) $post->post_parent > 0 ) {
    611                                                 // Sent level 0 by accident, by default, or because we don't know the actual level.
    612                                                 $find_main_page = (int) $post->post_parent;
    613                                                 while ( $find_main_page > 0 ) {
    614                                                         $parent = get_post( $find_main_page );
     674                if ( is_post_type_hierarchical( $post->post_type ) ) {
    615675
    616                                                         if ( is_null( $parent ) )
    617                                                                 break;
     676                        /**
     677                         * Filter the array of row action links on the Pages list table.
     678                         *
     679                         * The filter is evaluated only for hierarchical post types.
     680                         *
     681                         * @since 2.8.0
     682                         *
     683                         * @param array   $actions An array of row action links. Defaults are
     684                         *                         'Edit', 'Quick Edit', 'Restore, 'Trash',
     685                         *                         'Delete Permanently', 'Preview', and 'View'.
     686                         * @param WP_Post $post    The post object.
     687                         */
     688                        $actions = apply_filters( 'page_row_actions', $actions, $post );
     689                } else {
    618690
    619                                                         $level++;
    620                                                         $find_main_page = (int) $parent->post_parent;
     691                        /**
     692                         * Filter the array of row action links on the Posts list table.
     693                         *
     694                         * The filter is evaluated only for non-hierarchical post types.
     695                         *
     696                         * @since 2.8.0
     697                         *
     698                         * @param array   $actions An array of row action links. Defaults are
     699                         *                         'Edit', 'Quick Edit', 'Restore, 'Trash',
     700                         *                         'Delete Permanently', 'Preview', and 'View'.
     701                         * @param WP_Post $post    The post object.
     702                         */
     703                        $actions = apply_filters( 'post_row_actions', $actions, $post );
     704                }
    621705
    622                                                         if ( !isset( $parent_name ) ) {
    623                                                                 /** This filter is documented in wp-includes/post-template.php */
    624                                                                 $parent_name = apply_filters( 'the_title', $parent->post_title, $parent->ID );
    625                                                         }
    626                                                 }
    627                                         }
    628                                 }
     706                echo $this->row_actions( $actions );
    629707
    630                                 $pad = str_repeat( '&#8212; ', $level );
    631                                 echo "<td $attributes><strong>";
     708                get_inline_data( $post );
     709        }
    632710
    633                                 if ( $format = get_post_format( $post->ID ) ) {
    634                                         $label = get_post_format_string( $format );
     711        /**
     712         * Display the post date column for a post
     713         *
     714         * @param  WP_Post $post
     715         * @return null
     716         */
     717        public function column_date( $post ) {
    635718
    636                                         echo '<a href="' . esc_url( add_query_arg( array( 'post_format' => $format, 'post_type' => $post->post_type ), 'edit.php' ) ) . '" class="post-state-format post-format-icon post-format-' . $format . '" title="' . $label . '">' . $label . ":</a> ";
    637                                 }
     719                global $mode;
     720                $column_name = 'date';
    638721
    639                                 if ( $can_edit_post && $post->post_status != 'trash' ) {
    640                                         echo '<a class="row-title" href="' . $edit_link . '" title="' . esc_attr( sprintf( __( 'Edit &#8220;%s&#8221;' ), $title ) ) . '">' . $pad . $title . '</a>';
    641                                 } else {
    642                                         echo $pad . $title;
    643                                 }
    644                                 _post_states( $post );
     722                if ( '0000-00-00 00:00:00' == $post->post_date ) {
     723                        $t_time = $h_time = __( 'Unpublished' );
     724                        $time_diff = 0;
     725                } else {
     726                        $t_time = get_the_time( __( 'Y/m/d g:i:s A' ) );
     727                        $m_time = $post->post_date;
     728                        $time = get_post_time( 'G', true, $post );
    645729
    646                                 if ( isset( $parent_name ) )
    647                                         echo ' | ' . $post_type_object->labels->parent_item_colon . ' ' . esc_html( $parent_name );
     730                        $time_diff = time() - $time;
    648731
    649                                 echo "</strong>\n";
     732                        if ( $time_diff > 0 && $time_diff < DAY_IN_SECONDS )
     733                                $h_time = sprintf( __( '%s ago' ), human_time_diff( $time ) );
     734                        else
     735                                $h_time = mysql2date( __( 'Y/m/d' ), $m_time );
     736                }
    650737
    651                                 if ( $can_edit_post && $post->post_status != 'trash' ) {
    652                                         if ( $lock_holder ) {
    653                                                 $locked_avatar = get_avatar( $lock_holder->ID, 18 );
    654                                                 $locked_text = esc_html( sprintf( __( '%s is currently editing' ), $lock_holder->display_name ) );
    655                                         } else {
    656                                                 $locked_avatar = $locked_text = '';
    657                                         }
     738                if ( 'excerpt' == $mode ) {
    658739
    659                                         echo '<div class="locked-info"><span class="locked-avatar">' . $locked_avatar . '</span> <span class="locked-text">' . $locked_text . "</span></div>\n";
    660                                 }
     740                        /**
     741                         * Filter the published time of the post.
     742                         *
     743                         * If $mode equals 'excerpt', the published time and date are both displayed.
     744                         * If $mode equals 'list' (default), the publish date is displayed, with the
     745                         * time and date together available as an abbreviation definition.
     746                         *
     747                         * @since 2.5.1
     748                         *
     749                         * @param array   $t_time      The published time.
     750                         * @param WP_Post $post        Post object.
     751                         * @param string  $column_name The column name.
     752                         * @param string  $mode        The list display mode ('excerpt' or 'list').
     753                         */
     754                        echo apply_filters( 'post_date_column_time', $t_time, $post, $column_name, $mode );
     755                } else {
    661756
    662                                 if ( ! $this->hierarchical_display && 'excerpt' == $mode && current_user_can( 'read_post', $post->ID ) )
    663                                                 the_excerpt();
     757                        /** This filter is documented in wp-admin/includes/class-wp-posts-list-table.php */
     758                        echo '<abbr title="' . $t_time . '">' . apply_filters( 'post_date_column_time', $h_time, $post, $column_name, $mode ) . '</abbr>';
     759                }
     760                echo '<br />';
     761                if ( 'publish' == $post->post_status ) {
     762                        _e( 'Published' );
     763                } elseif ( 'future' == $post->post_status ) {
     764                        if ( $time_diff > 0 )
     765                                echo '<strong class="attention">' . __( 'Missed schedule' ) . '</strong>';
     766                        else
     767                                _e( 'Scheduled' );
     768                } else {
     769                        _e( 'Last Modified' );
     770                }
     771        }
    664772
    665                                 $actions = array();
    666                                 if ( $can_edit_post && 'trash' != $post->post_status ) {
    667                                         $actions['edit'] = '<a href="' . get_edit_post_link( $post->ID, true ) . '" title="' . esc_attr__( 'Edit this item' ) . '">' . __( 'Edit' ) . '</a>';
    668                                         $actions['inline hide-if-no-js'] = '<a href="#" class="editinline" title="' . esc_attr__( 'Edit this item inline' ) . '">' . __( 'Quick&nbsp;Edit' ) . '</a>';
    669                                 }
    670                                 if ( current_user_can( 'delete_post', $post->ID ) ) {
    671                                         if ( 'trash' == $post->post_status )
    672                                                 $actions['untrash'] = "<a title='" . esc_attr__( 'Restore this item from the Trash' ) . "' href='" . wp_nonce_url( admin_url( sprintf( $post_type_object->_edit_link . '&amp;action=untrash', $post->ID ) ), 'untrash-post_' . $post->ID ) . "'>" . __( 'Restore' ) . "</a>";
    673                                         elseif ( EMPTY_TRASH_DAYS )
    674                                                 $actions['trash'] = "<a class='submitdelete' title='" . esc_attr__( 'Move this item to the Trash' ) . "' href='" . get_delete_post_link( $post->ID ) . "'>" . __( 'Trash' ) . "</a>";
    675                                         if ( 'trash' == $post->post_status || !EMPTY_TRASH_DAYS )
    676                                                 $actions['delete'] = "<a class='submitdelete' title='" . esc_attr__( 'Delete this item permanently' ) . "' href='" . get_delete_post_link( $post->ID, '', true ) . "'>" . __( 'Delete Permanently' ) . "</a>";
    677                                 }
    678                                 if ( $post_type_object->public ) {
    679                                         if ( in_array( $post->post_status, array( 'pending', 'draft', 'future' ) ) ) {
    680                                                 if ( $can_edit_post ) {
    681                                                         $preview_link = set_url_scheme( get_permalink( $post->ID ) );
    682                                                         /** This filter is documented in wp-admin/includes/meta-boxes.php */
    683                                                         $preview_link = apply_filters( 'preview_post_link', add_query_arg( 'preview', 'true', $preview_link ), $post );
    684                                                         $actions['view'] = '<a href="' . esc_url( $preview_link ) . '" title="' . esc_attr( sprintf( __( 'Preview &#8220;%s&#8221;' ), $title ) ) . '" rel="permalink">' . __( 'Preview' ) . '</a>';
    685                                                 }
    686                                         } elseif ( 'trash' != $post->post_status ) {
    687                                                 $actions['view'] = '<a href="' . get_permalink( $post->ID ) . '" title="' . esc_attr( sprintf( __( 'View &#8220;%s&#8221;' ), $title ) ) . '" rel="permalink">' . __( 'View' ) . '</a>';
    688                                         }
    689                                 }
     773        /**
     774         * Display the comment count column for a post
     775         *
     776         * @param  WP_Post $post
     777         * @return null
     778         */
     779        public function column_comments( $post ) {
    690780
    691                                 if ( is_post_type_hierarchical( $post->post_type ) ) {
     781                $pending_comments = isset( $this->comment_pending_count[$post->ID] ) ? $this->comment_pending_count[$post->ID] : 0;
    692782
    693                                         /**
    694                                          * Filter the array of row action links on the Pages list table.
    695                                          *
    696                                          * The filter is evaluated only for hierarchical post types.
    697                                          *
    698                                          * @since 2.8.0
    699                                          *
    700                                          * @param array   $actions An array of row action links. Defaults are
    701                                          *                         'Edit', 'Quick Edit', 'Restore, 'Trash',
    702                                          *                         'Delete Permanently', 'Preview', and 'View'.
    703                                          * @param WP_Post $post    The post object.
    704                                          */
    705                                         $actions = apply_filters( 'page_row_actions', $actions, $post );
    706                                 } else {
     783                ?>
     784                <div class="post-com-count-wrapper">
     785                        <?php $this->comments_bubble( $post->ID, $pending_comments ); ?>
     786                </div>
     787                <?php
     788        }
    707789
    708                                         /**
    709                                          * Filter the array of row action links on the Posts list table.
    710                                          *
    711                                          * The filter is evaluated only for non-hierarchical post types.
    712                                          *
    713                                          * @since 2.8.0
    714                                          *
    715                                          * @param array   $actions An array of row action links. Defaults are
    716                                          *                         'Edit', 'Quick Edit', 'Restore, 'Trash',
    717                                          *                         'Delete Permanently', 'Preview', and 'View'.
    718                                          * @param WP_Post $post    The post object.
    719                                          */
    720                                         $actions = apply_filters( 'post_row_actions', $actions, $post );
    721                                 }
     790        /**
     791         * Display the post author column for the post
     792         *
     793         * @param  WP_Post $post
     794         * @return null
     795         */
     796        public function column_author( $post ) {
    722797
    723                                 echo $this->row_actions( $actions );
     798                $author = get_userdata( $post->post_author );
    724799
    725                                 get_inline_data( $post );
    726                                 echo '</td>';
    727                         break;
     800                printf( '<a href="%s">%s</a>',
     801                        esc_url( add_query_arg( array( 'post_type' => $post->post_type, 'author' => $post->post_author ), 'edit.php' ) ),
     802                        apply_filters( 'the_author', $author->display_name )
     803                );
     804        }
    728805
    729                         case 'date':
    730                                 if ( '0000-00-00 00:00:00' == $post->post_date ) {
    731                                         $t_time = $h_time = __( 'Unpublished' );
    732                                         $time_diff = 0;
    733                                 } else {
    734                                         $t_time = get_the_time( __( 'Y/m/d g:i:s A' ) );
    735                                         $m_time = $post->post_date;
    736                                         $time = get_post_time( 'G', true, $post );
     806        /**
     807         * Display the post tags column for the post
     808         *
     809         * @param  WP_Post $post
     810         * @return null
     811         */
     812        public function column_tags( $post ) {
     813                $this->output_taxonomy_column( $post, 'post_tag' );
     814        }
    737815
    738                                         $time_diff = time() - $time;
     816        /**
     817         * Display the post categories column for the post
     818         *
     819         * @param  WP_Post $post
     820         * @return null
     821         */
     822        public function column_categories( $post ) {
     823                $this->output_taxonomy_column( $post, 'category' );
     824        }
    739825
    740                                         if ( $time_diff > 0 && $time_diff < DAY_IN_SECONDS )
    741                                                 $h_time = sprintf( __( '%s ago' ), human_time_diff( $time ) );
    742                                         else
    743                                                 $h_time = mysql2date( __( 'Y/m/d' ), $m_time );
    744                                 }
     826        /**
     827         * Display a taxonomy's column for the post
     828         *
     829         * @param  WP_Post $post     
     830         * @param  string  $taxonomy
     831         * @return null
     832         */
     833        protected function output_taxonomy_column( $post, $taxonomy ) {
    745834
    746                                 echo '<td ' . $attributes . '>';
    747                                 if ( 'excerpt' == $mode ) {
     835                $taxonomy_object = get_taxonomy( $taxonomy );
    748836
    749                                         /**
    750                                          * Filter the published time of the post.
    751                                          *
    752                                          * If $mode equals 'excerpt', the published time and date are both displayed.
    753                                          * If $mode equals 'list' (default), the publish date is displayed, with the
    754                                          * time and date together available as an abbreviation definition.
    755                                          *
    756                                          * @since 2.5.1
    757                                          *
    758                                          * @param array   $t_time      The published time.
    759                                          * @param WP_Post $post        Post object.
    760                                          * @param string  $column_name The column name.
    761                                          * @param string  $mode        The list display mode ('excerpt' or 'list').
    762                                          */
    763                                         echo apply_filters( 'post_date_column_time', $t_time, $post, $column_name, $mode );
     837                if ( $terms = get_the_terms( $post->ID, $taxonomy ) ) {
     838                        $out = array();
     839                        foreach ( $terms as $t ) {
     840                                $posts_in_term_qv = array();
     841                                if ( 'post' != $post->post_type )
     842                                        $posts_in_term_qv['post_type'] = $post->post_type;
     843                                if ( $taxonomy_object->query_var ) {
     844                                        $posts_in_term_qv[ $taxonomy_object->query_var ] = $t->slug;
    764845                                } else {
    765 
    766                                         /** This filter is documented in wp-admin/includes/class-wp-posts-list-table.php */
    767                                         echo '<abbr title="' . $t_time . '">' . apply_filters( 'post_date_column_time', $h_time, $post, $column_name, $mode ) . '</abbr>';
     846                                        $posts_in_term_qv['taxonomy'] = $taxonomy;
     847                                        $posts_in_term_qv['term'] = $t->slug;
    768848                                }
    769                                 echo '<br />';
    770                                 if ( 'publish' == $post->post_status ) {
    771                                         _e( 'Published' );
    772                                 } elseif ( 'future' == $post->post_status ) {
    773                                         if ( $time_diff > 0 )
    774                                                 echo '<strong class="attention">' . __( 'Missed schedule' ) . '</strong>';
    775                                         else
    776                                                 _e( 'Scheduled' );
    777                                 } else {
    778                                         _e( 'Last Modified' );
    779                                 }
    780                                 echo '</td>';
    781                         break;
    782849
    783                         case 'comments':
    784                         ?>
    785                         <td <?php echo $attributes ?>><div class="post-com-count-wrapper">
    786                         <?php
    787                                 $pending_comments = isset( $this->comment_pending_count[$post->ID] ) ? $this->comment_pending_count[$post->ID] : 0;
     850                                $out[] = sprintf( '<a href="%s">%s</a>',
     851                                        esc_url( add_query_arg( $posts_in_term_qv, 'edit.php' ) ),
     852                                        esc_html( sanitize_term_field( 'name', $t->name, $t->term_id, $taxonomy, 'display' ) )
     853                                );
     854                        }
     855                        /* translators: used between list items, there is a space after the comma */
     856                        echo join( __( ', ' ), $out );
     857                } else {
     858                        echo '&#8212;';
     859                }
     860        }
    788861
    789                                 $this->comments_bubble( $post->ID, $pending_comments );
    790                         ?>
    791                         </div></td>
    792                         <?php
    793                         break;
     862        /**
     863         * Display a custom column for the post
     864         *
     865         * In the event of a taxonomy column in the form of "taxonomy-$taxonomy", output_taxonomy_column() is called.
     866         *
     867         * @param  WP_Post $post
     868         * @param  string  $column_name
     869         * @return null
     870         */
     871        public function column_default( $post, $column_name ) {
    794872
    795                         case 'author':
    796                         ?>
    797                         <td <?php echo $attributes ?>><?php
    798                                 printf( '<a href="%s">%s</a>',
    799                                         esc_url( add_query_arg( array( 'post_type' => $post->post_type, 'author' => get_the_author_meta( 'ID' ) ), 'edit.php' )),
    800                                         get_the_author()
    801                                 );
    802                         ?></td>
    803                         <?php
    804                         break;
     873                if ( 0 === strpos( $column_name, 'taxonomy-' ) ) {
     874                        return $this->output_taxonomy_column( $post, substr( $column_name, 9 ) );
     875                }
    805876
    806                         default:
    807                                 if ( 'categories' == $column_name )
    808                                         $taxonomy = 'category';
    809                                 elseif ( 'tags' == $column_name )
    810                                         $taxonomy = 'post_tag';
    811                                 elseif ( 0 === strpos( $column_name, 'taxonomy-' ) )
    812                                         $taxonomy = substr( $column_name, 9 );
    813                                 else
    814                                         $taxonomy = false;
     877                if ( is_post_type_hierarchical( $post->post_type ) ) {
    815878
    816                                 if ( $taxonomy ) {
    817                                         $taxonomy_object = get_taxonomy( $taxonomy );
    818                                         echo '<td ' . $attributes . '>';
    819                                         if ( $terms = get_the_terms( $post->ID, $taxonomy ) ) {
    820                                                 $out = array();
    821                                                 foreach ( $terms as $t ) {
    822                                                         $posts_in_term_qv = array();
    823                                                         if ( 'post' != $post->post_type )
    824                                                                 $posts_in_term_qv['post_type'] = $post->post_type;
    825                                                         if ( $taxonomy_object->query_var ) {
    826                                                                 $posts_in_term_qv[ $taxonomy_object->query_var ] = $t->slug;
    827                                                         } else {
    828                                                                 $posts_in_term_qv['taxonomy'] = $taxonomy;
    829                                                                 $posts_in_term_qv['term'] = $t->slug;
    830                                                         }
     879                        /**
     880                         * Fires in each custom column on the Posts list table.
     881                         *
     882                         * This hook only fires if the current post type is hierarchical,
     883                         * such as pages.
     884                         *
     885                         * @since 2.5.0
     886                         *
     887                         * @param string $column_name The name of the column to display.
     888                         * @param int    $post_id     The current post ID.
     889                         */
     890                        do_action( 'manage_pages_custom_column', $column_name, $post->ID );
     891                } else {
    831892
    832                                                         $out[] = sprintf( '<a href="%s">%s</a>',
    833                                                                 esc_url( add_query_arg( $posts_in_term_qv, 'edit.php' ) ),
    834                                                                 esc_html( sanitize_term_field( 'name', $t->name, $t->term_id, $taxonomy, 'display' ) )
    835                                                         );
    836                                                 }
    837                                                 /* translators: used between list items, there is a space after the comma */
    838                                                 echo join( __( ', ' ), $out );
    839                                         } else {
    840                                                 echo '&#8212;';
    841                                         }
    842                                         echo '</td>';
    843                                         break;
    844                                 }
    845                         ?>
    846                         <td <?php echo $attributes ?>><?php
    847                                 if ( is_post_type_hierarchical( $post->post_type ) ) {
     893                        /**
     894                         * Fires in each custom column in the Posts list table.
     895                         *
     896                         * This hook only fires if the current post type is non-hierarchical,
     897                         * such as posts.
     898                         *
     899                         * @since 1.5.0
     900                         *
     901                         * @param string $column_name The name of the column to display.
     902                         * @param int    $post_id     The current post ID.
     903                         */
     904                        do_action( 'manage_posts_custom_column', $column_name, $post->ID );
     905                }
    848906
    849                                         /**
    850                                          * Fires in each custom column on the Posts list table.
    851                                          *
    852                                          * This hook only fires if the current post type is hierarchical,
    853                                          * such as pages.
    854                                          *
    855                                          * @since 2.5.0
    856                                          *
    857                                          * @param string $column_name The name of the column to display.
    858                                          * @param int    $post_id     The current post ID.
    859                                          */
    860                                         do_action( 'manage_pages_custom_column', $column_name, $post->ID );
    861                                 } else {
     907                /**
     908                 * Fires for each custom column of a specific post type in the Posts list table.
     909                 *
     910                 * The dynamic portion of the hook name, $post->post_type, refers to the post type.
     911                 *
     912                 * @since 3.1.0
     913                 *
     914                 * @param string $column_name The name of the column to display.
     915                 * @param int    $post_id     The current post ID.
     916                 */
     917                do_action( "manage_{$post->post_type}_posts_custom_column", $column_name, $post->ID );
     918        }
    862919
    863                                         /**
    864                                          * Fires in each custom column in the Posts list table.
    865                                          *
    866                                          * This hook only fires if the current post type is non-hierarchical,
    867                                          * such as posts.
    868                                          *
    869                                          * @since 1.5.0
    870                                          *
    871                                          * @param string $column_name The name of the column to display.
    872                                          * @param int    $post_id     The current post ID.
    873                                          */
    874                                         do_action( 'manage_posts_custom_column', $column_name, $post->ID );
    875                                 }
     920        public function single_row( $post, $level = 0 ) {
     921                global $mode;
     922                static $alternate;
    876923
    877                                 /**
    878                                  * Fires for each custom column of a specific post type in the Posts list table.
    879                                  *
    880                                  * The dynamic portion of the hook name, $post->post_type, refers to the post type.
    881                                  *
    882                                  * @since 3.1.0
    883                                  *
    884                                  * @param string $column_name The name of the column to display.
    885                                  * @param int    $post_id     The current post ID.
    886                                  */
    887                                 do_action( "manage_{$post->post_type}_posts_custom_column", $column_name, $post->ID );
    888                         ?></td>
    889                         <?php
    890                         break;
    891                         }
     924                $this->row_level = $level;
     925
     926                $global_post = get_post();
     927                $GLOBALS['post'] = $post;
     928                setup_postdata( $post );
     929
     930                $edit_link = get_edit_post_link( $post->ID );
     931                $title = _draft_or_post_title();
     932                $post_type_object = get_post_type_object( $post->post_type );
     933                $can_edit_post = current_user_can( 'edit_post', $post->ID );
     934
     935                $alternate = 'alternate' == $alternate ? '' : 'alternate';
     936                $classes = $alternate . ' iedit author-' . ( get_current_user_id() == $post->post_author ? 'self' : 'other' );
     937
     938                $lock_holder = wp_check_post_lock( $post->ID );
     939                if ( $lock_holder ) {
     940                        $classes .= ' wp-locked';
     941                        $lock_holder = get_userdata( $lock_holder );
    892942                }
    893         ?>
     943
     944                if ( $post->post_parent ) {
     945                    $count = count( get_post_ancestors( $post->ID ) );
     946                    $classes .= ' level-'. $count;
     947                } else {
     948                    $classes .= ' level-0';
     949                }
     950
     951                ?>
     952                <tr id="post-<?php echo $post->ID; ?>" class="<?php echo implode( ' ', get_post_class( $classes, $post->ID ) ); ?>">
     953
     954                        <?php $this->single_row_columns( $post ); ?>
    894955                </tr>
    895         <?php
     956                <?php
    896957                $GLOBALS['post'] = $global_post;
    897958        }
    898959
    899960        /**
     961         * Generates the columns for a single row of the table
     962         *
     963         * @since 3.1.0
     964         * @access protected
     965         *
     966         * @param object $item The current item
     967         */
     968        protected function single_row_columns( $item ) {
     969                list( $columns, $hidden ) = $this->get_column_info();
     970
     971                foreach ( $columns as $column_name => $column_display_name ) {
     972
     973                        // backwards compatibility for the title column,
     974                        // it has some one-off custom class names.
     975                        if ( 'title' === $column_name ) {
     976                                $class_extra = "post-title page-title";
     977                        } else {
     978                                $class_extra = '';
     979                        }
     980
     981                        $class = "class='$column_name column-$column_name $class_extra'";
     982
     983                        $style = '';
     984                        if ( in_array( $column_name, $hidden ) )
     985                                $style = ' style="display:none;"';
     986
     987                        $attributes = "$class$style";
     988
     989                        if ( 'cb' == $column_name ) {
     990                                echo '<th scope="row" class="check-column">';
     991                                echo $this->column_cb( $item );
     992                                echo '</th>';
     993                        }
     994                        elseif ( method_exists( $this, 'column_' . $column_name ) ) {
     995                                echo "<td $attributes>";
     996                                echo call_user_func( array( $this, 'column_' . $column_name ), $item );
     997                                echo "</td>";
     998                        }
     999                        else {
     1000                                echo "<td $attributes>";
     1001                                echo $this->column_default( $item, $column_name );
     1002                                echo "</td>";
     1003                        }
     1004                }
     1005        }
     1006
     1007        /**
    9001008         * Outputs the hidden row displayed when inline editing
    9011009         *
    9021010         * @since 3.1.0