home *** CD-ROM | disk | FTP | other *** search
/ HTML Examples / WP.iso / wordpress / wp-admin / includes / class-wp-comments-list-table.php < prev    next >
Encoding:
PHP Script  |  2017-10-02  |  25.0 KB  |  797 lines

  1. <?php
  2. /**
  3.  * List Table API: WP_Comments_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 comments in a list table.
  12.  *
  13.  * @since 3.1.0
  14.  * @access private
  15.  *
  16.  * @see WP_List_Table
  17.  */
  18. class WP_Comments_List_Table extends WP_List_Table {
  19.  
  20.     public $checkbox = true;
  21.  
  22.     public $pending_count = array();
  23.  
  24.     public $extra_items;
  25.  
  26.     private $user_can;
  27.  
  28.     /**
  29.      * Constructor.
  30.      *
  31.      * @since 3.1.0
  32.      *
  33.      * @see WP_List_Table::__construct() for more information on default arguments.
  34.      *
  35.      * @global int $post_id
  36.      *
  37.      * @param array $args An associative array of arguments.
  38.      */
  39.     public function __construct( $args = array() ) {
  40.         global $post_id;
  41.  
  42.         $post_id = isset( $_REQUEST['p'] ) ? absint( $_REQUEST['p'] ) : 0;
  43.  
  44.         if ( get_option( 'show_avatars' ) ) {
  45.             add_filter( 'comment_author', array( $this, 'floated_admin_avatar' ), 10, 2 );
  46.         }
  47.  
  48.         parent::__construct( array(
  49.             'plural' => 'comments',
  50.             'singular' => 'comment',
  51.             'ajax' => true,
  52.             'screen' => isset( $args['screen'] ) ? $args['screen'] : null,
  53.         ) );
  54.     }
  55.  
  56.     public function floated_admin_avatar( $name, $comment_ID ) {
  57.         $comment = get_comment( $comment_ID );
  58.         $avatar = get_avatar( $comment, 32, 'mystery' );
  59.         return "$avatar $name";
  60.     }
  61.  
  62.     /**
  63.      * @return bool
  64.      */
  65.     public function ajax_user_can() {
  66.         return current_user_can('edit_posts');
  67.     }
  68.  
  69.     /**
  70.      *
  71.      * @global int    $post_id
  72.      * @global string $comment_status
  73.      * @global string $search
  74.      * @global string $comment_type
  75.      */
  76.     public function prepare_items() {
  77.         global $post_id, $comment_status, $search, $comment_type;
  78.  
  79.         $comment_status = isset( $_REQUEST['comment_status'] ) ? $_REQUEST['comment_status'] : 'all';
  80.         if ( !in_array( $comment_status, array( 'all', 'moderated', 'approved', 'spam', 'trash' ) ) )
  81.             $comment_status = 'all';
  82.  
  83.         $comment_type = !empty( $_REQUEST['comment_type'] ) ? $_REQUEST['comment_type'] : '';
  84.  
  85.         $search = ( isset( $_REQUEST['s'] ) ) ? $_REQUEST['s'] : '';
  86.  
  87.         $post_type = ( isset( $_REQUEST['post_type'] ) ) ? sanitize_key( $_REQUEST['post_type'] ) : '';
  88.  
  89.         $user_id = ( isset( $_REQUEST['user_id'] ) ) ? $_REQUEST['user_id'] : '';
  90.  
  91.         $orderby = ( isset( $_REQUEST['orderby'] ) ) ? $_REQUEST['orderby'] : '';
  92.         $order = ( isset( $_REQUEST['order'] ) ) ? $_REQUEST['order'] : '';
  93.  
  94.         $comments_per_page = $this->get_per_page( $comment_status );
  95.  
  96.         $doing_ajax = wp_doing_ajax();
  97.  
  98.         if ( isset( $_REQUEST['number'] ) ) {
  99.             $number = (int) $_REQUEST['number'];
  100.         }
  101.         else {
  102.             $number = $comments_per_page + min( 8, $comments_per_page ); // Grab a few extra
  103.         }
  104.  
  105.         $page = $this->get_pagenum();
  106.  
  107.         if ( isset( $_REQUEST['start'] ) ) {
  108.             $start = $_REQUEST['start'];
  109.         } else {
  110.             $start = ( $page - 1 ) * $comments_per_page;
  111.         }
  112.  
  113.         if ( $doing_ajax && isset( $_REQUEST['offset'] ) ) {
  114.             $start += $_REQUEST['offset'];
  115.         }
  116.  
  117.         $status_map = array(
  118.             'moderated' => 'hold',
  119.             'approved' => 'approve',
  120.             'all' => '',
  121.         );
  122.  
  123.         $args = array(
  124.             'status' => isset( $status_map[$comment_status] ) ? $status_map[$comment_status] : $comment_status,
  125.             'search' => $search,
  126.             'user_id' => $user_id,
  127.             'offset' => $start,
  128.             'number' => $number,
  129.             'post_id' => $post_id,
  130.             'type' => $comment_type,
  131.             'orderby' => $orderby,
  132.             'order' => $order,
  133.             'post_type' => $post_type,
  134.         );
  135.  
  136.         $_comments = get_comments( $args );
  137.         if ( is_array( $_comments ) ) {
  138.             update_comment_cache( $_comments );
  139.  
  140.             $this->items = array_slice( $_comments, 0, $comments_per_page );
  141.             $this->extra_items = array_slice( $_comments, $comments_per_page );
  142.  
  143.             $_comment_post_ids = array_unique( wp_list_pluck( $_comments, 'comment_post_ID' ) );
  144.  
  145.             $this->pending_count = get_pending_comments_num( $_comment_post_ids );
  146.         }
  147.  
  148.         $total_comments = get_comments( array_merge( $args, array(
  149.             'count' => true,
  150.             'offset' => 0,
  151.             'number' => 0
  152.         ) ) );
  153.  
  154.         $this->set_pagination_args( array(
  155.             'total_items' => $total_comments,
  156.             'per_page' => $comments_per_page,
  157.         ) );
  158.     }
  159.  
  160.     /**
  161.      *
  162.      * @param string $comment_status
  163.      * @return int
  164.      */
  165.     public function get_per_page( $comment_status = 'all' ) {
  166.         $comments_per_page = $this->get_items_per_page( 'edit_comments_per_page' );
  167.         /**
  168.          * Filters the number of comments listed per page in the comments list table.
  169.          *
  170.          * @since 2.6.0
  171.          *
  172.          * @param int    $comments_per_page The number of comments to list per page.
  173.          * @param string $comment_status    The comment status name. Default 'All'.
  174.          */
  175.         return apply_filters( 'comments_per_page', $comments_per_page, $comment_status );
  176.     }
  177.  
  178.     /**
  179.      *
  180.      * @global string $comment_status
  181.      */
  182.     public function no_items() {
  183.         global $comment_status;
  184.  
  185.         if ( 'moderated' === $comment_status ) {
  186.             _e( 'No comments awaiting moderation.' );
  187.         } else {
  188.             _e( 'No comments found.' );
  189.         }
  190.     }
  191.  
  192.     /**
  193.      *
  194.      * @global int $post_id
  195.      * @global string $comment_status
  196.      * @global string $comment_type
  197.      */
  198.     protected function get_views() {
  199.         global $post_id, $comment_status, $comment_type;
  200.  
  201.         $status_links = array();
  202.         $num_comments = ( $post_id ) ? wp_count_comments( $post_id ) : wp_count_comments();
  203.  
  204.         $stati = array(
  205.             /* translators: %s: all comments count */
  206.             'all' => _nx_noop(
  207.                 'All <span class="count">(%s)</span>',
  208.                 'All <span class="count">(%s)</span>',
  209.                 'comments'
  210.             ), // singular not used
  211.  
  212.             /* translators: %s: pending comments count */
  213.             'moderated' => _nx_noop(
  214.                 'Pending <span class="count">(%s)</span>',
  215.                 'Pending <span class="count">(%s)</span>',
  216.                 'comments'
  217.             ),
  218.  
  219.             /* translators: %s: approved comments count */
  220.             'approved' => _nx_noop(
  221.                 'Approved <span class="count">(%s)</span>',
  222.                 'Approved <span class="count">(%s)</span>',
  223.                 'comments'
  224.             ),
  225.  
  226.             /* translators: %s: spam comments count */
  227.             'spam' => _nx_noop(
  228.                 'Spam <span class="count">(%s)</span>',
  229.                 'Spam <span class="count">(%s)</span>',
  230.                 'comments'
  231.             ),
  232.  
  233.             /* translators: %s: trashed comments count */
  234.             'trash' => _nx_noop(
  235.                 'Trash <span class="count">(%s)</span>',
  236.                 'Trash <span class="count">(%s)</span>',
  237.                 'comments'
  238.             )
  239.         );
  240.  
  241.         if ( !EMPTY_TRASH_DAYS )
  242.             unset($stati['trash']);
  243.  
  244.         $link = admin_url( 'edit-comments.php' );
  245.         if ( !empty($comment_type) && 'all' != $comment_type )
  246.             $link = add_query_arg( 'comment_type', $comment_type, $link );
  247.  
  248.         foreach ( $stati as $status => $label ) {
  249.             $current_link_attributes = '';
  250.  
  251.             if ( $status === $comment_status ) {
  252.                 $current_link_attributes = ' class="current" aria-current="page"';
  253.             }
  254.  
  255.             if ( !isset( $num_comments->$status ) )
  256.                 $num_comments->$status = 10;
  257.             $link = add_query_arg( 'comment_status', $status, $link );
  258.             if ( $post_id )
  259.                 $link = add_query_arg( 'p', absint( $post_id ), $link );
  260.             /*
  261.             // I toyed with this, but decided against it. Leaving it in here in case anyone thinks it is a good idea. ~ Mark
  262.             if ( !empty( $_REQUEST['s'] ) )
  263.                 $link = add_query_arg( 's', esc_attr( wp_unslash( $_REQUEST['s'] ) ), $link );
  264.             */
  265.             $status_links[ $status ] = "<a href='$link'$current_link_attributes>" . sprintf(
  266.                 translate_nooped_plural( $label, $num_comments->$status ),
  267.                 sprintf( '<span class="%s-count">%s</span>',
  268.                     ( 'moderated' === $status ) ? 'pending' : $status,
  269.                     number_format_i18n( $num_comments->$status )
  270.                 )
  271.             ) . '</a>';
  272.         }
  273.  
  274.         /**
  275.          * Filters the comment status links.
  276.          *
  277.          * @since 2.5.0
  278.          *
  279.          * @param array $status_links An array of fully-formed status links. Default 'All'.
  280.          *                            Accepts 'All', 'Pending', 'Approved', 'Spam', and 'Trash'.
  281.          */
  282.         return apply_filters( 'comment_status_links', $status_links );
  283.     }
  284.  
  285.     /**
  286.      *
  287.      * @global string $comment_status
  288.      *
  289.      * @return array
  290.      */
  291.     protected function get_bulk_actions() {
  292.         global $comment_status;
  293.  
  294.         $actions = array();
  295.         if ( in_array( $comment_status, array( 'all', 'approved' ) ) )
  296.             $actions['unapprove'] = __( 'Unapprove' );
  297.         if ( in_array( $comment_status, array( 'all', 'moderated' ) ) )
  298.             $actions['approve'] = __( 'Approve' );
  299.         if ( in_array( $comment_status, array( 'all', 'moderated', 'approved', 'trash' ) ) )
  300.             $actions['spam'] = _x( 'Mark as Spam', 'comment' );
  301.  
  302.         if ( 'trash' === $comment_status ) {
  303.             $actions['untrash'] = __( 'Restore' );
  304.         } elseif ( 'spam' === $comment_status ) {
  305.             $actions['unspam'] = _x( 'Not Spam', 'comment' );
  306.         }
  307.  
  308.         if ( in_array( $comment_status, array( 'trash', 'spam' ) ) || !EMPTY_TRASH_DAYS )
  309.             $actions['delete'] = __( 'Delete Permanently' );
  310.         else
  311.             $actions['trash'] = __( 'Move to Trash' );
  312.  
  313.         return $actions;
  314.     }
  315.  
  316.     /**
  317.      *
  318.      * @global string $comment_status
  319.      * @global string $comment_type
  320.      *
  321.      * @param string $which
  322.      */
  323.     protected function extra_tablenav( $which ) {
  324.         global $comment_status, $comment_type;
  325.         static $has_items;
  326.  
  327.         if ( ! isset( $has_items ) ) {
  328.             $has_items = $this->has_items();
  329.         }
  330. ?>
  331.         <div class="alignleft actions">
  332. <?php
  333.         if ( 'top' === $which ) {
  334. ?>
  335.             <label class="screen-reader-text" for="filter-by-comment-type"><?php _e( 'Filter by comment type' ); ?></label>
  336.             <select id="filter-by-comment-type" name="comment_type">
  337.                 <option value=""><?php _e( 'All comment types' ); ?></option>
  338. <?php
  339.                 /**
  340.                  * Filters the comment types dropdown menu.
  341.                  *
  342.                  * @since 2.7.0
  343.                  *
  344.                  * @param array $comment_types An array of comment types. Accepts 'Comments', 'Pings'.
  345.                  */
  346.                 $comment_types = apply_filters( 'admin_comment_types_dropdown', array(
  347.                     'comment' => __( 'Comments' ),
  348.                     'pings' => __( 'Pings' ),
  349.                 ) );
  350.  
  351.                 foreach ( $comment_types as $type => $label )
  352.                     echo "\t" . '<option value="' . esc_attr( $type ) . '"' . selected( $comment_type, $type, false ) . ">$label</option>\n";
  353.             ?>
  354.             </select>
  355. <?php
  356.             /**
  357.              * Fires just before the Filter submit button for comment types.
  358.              *
  359.              * @since 3.5.0
  360.              */
  361.             do_action( 'restrict_manage_comments' );
  362.             submit_button( __( 'Filter' ), '', 'filter_action', false, array( 'id' => 'post-query-submit' ) );
  363.         }
  364.  
  365.         if ( ( 'spam' === $comment_status || 'trash' === $comment_status ) && current_user_can( 'moderate_comments' ) && $has_items ) {
  366.             wp_nonce_field( 'bulk-destroy', '_destroy_nonce' );
  367.             $title = ( 'spam' === $comment_status ) ? esc_attr__( 'Empty Spam' ) : esc_attr__( 'Empty Trash' );
  368.             submit_button( $title, 'apply', 'delete_all', false );
  369.         }
  370.         /**
  371.          * Fires after the Filter submit button for comment types.
  372.          *
  373.          * @since 2.5.0
  374.          *
  375.          * @param string $comment_status The comment status name. Default 'All'.
  376.          */
  377.         do_action( 'manage_comments_nav', $comment_status );
  378.         echo '</div>';
  379.     }
  380.  
  381.     /**
  382.      * @return string|false
  383.      */
  384.     public function current_action() {
  385.         if ( isset( $_REQUEST['delete_all'] ) || isset( $_REQUEST['delete_all2'] ) )
  386.             return 'delete_all';
  387.  
  388.         return parent::current_action();
  389.     }
  390.  
  391.     /**
  392.      *
  393.      * @global int $post_id
  394.      *
  395.      * @return array
  396.      */
  397.     public function get_columns() {
  398.         global $post_id;
  399.  
  400.         $columns = array();
  401.  
  402.         if ( $this->checkbox )
  403.             $columns['cb'] = '<input type="checkbox" />';
  404.  
  405.         $columns['author'] = __( 'Author' );
  406.         $columns['comment'] = _x( 'Comment', 'column name' );
  407.  
  408.         if ( ! $post_id ) {
  409.             /* translators: column name or table row header */
  410.             $columns['response'] = __( 'In Response To' );
  411.         }
  412.  
  413.         $columns['date'] = _x( 'Submitted On', 'column name' );
  414.  
  415.         return $columns;
  416.     }
  417.  
  418.     /**
  419.      *
  420.      * @return array
  421.      */
  422.     protected function get_sortable_columns() {
  423.         return array(
  424.             'author'   => 'comment_author',
  425.             'response' => 'comment_post_ID',
  426.             'date'     => 'comment_date'
  427.         );
  428.     }
  429.  
  430.     /**
  431.      * Get the name of the default primary column.
  432.      *
  433.      * @since 4.3.0
  434.      *
  435.      * @return string Name of the default primary column, in this case, 'comment'.
  436.      */
  437.     protected function get_default_primary_column_name() {
  438.         return 'comment';
  439.     }
  440.  
  441.     /**
  442.      */
  443.     public function display() {
  444.         wp_nonce_field( "fetch-list-" . get_class( $this ), '_ajax_fetch_list_nonce' );
  445.  
  446.         $this->display_tablenav( 'top' );
  447.  
  448.         $this->screen->render_screen_reader_content( 'heading_list' );
  449.  
  450. ?>
  451. <table class="wp-list-table <?php echo implode( ' ', $this->get_table_classes() ); ?>">
  452.     <thead>
  453.     <tr>
  454.         <?php $this->print_column_headers(); ?>
  455.     </tr>
  456.     </thead>
  457.  
  458.     <tbody id="the-comment-list" data-wp-lists="list:comment">
  459.         <?php $this->display_rows_or_placeholder(); ?>
  460.     </tbody>
  461.  
  462.     <tbody id="the-extra-comment-list" data-wp-lists="list:comment" style="display: none;">
  463.         <?php
  464.             $this->items = $this->extra_items;
  465.             $this->display_rows_or_placeholder();
  466.         ?>
  467.     </tbody>
  468.  
  469.     <tfoot>
  470.     <tr>
  471.         <?php $this->print_column_headers( false ); ?>
  472.     </tr>
  473.     </tfoot>
  474.  
  475. </table>
  476. <?php
  477.  
  478.         $this->display_tablenav( 'bottom' );
  479.     }
  480.  
  481.     /**
  482.      * @global WP_Post    $post
  483.      * @global WP_Comment $comment
  484.      *
  485.      * @param WP_Comment $item
  486.      */
  487.     public function single_row( $item ) {
  488.         global $post, $comment;
  489.  
  490.         $comment = $item;
  491.  
  492.         $the_comment_class = wp_get_comment_status( $comment );
  493.         if ( ! $the_comment_class ) {
  494.             $the_comment_class = '';
  495.         }
  496.         $the_comment_class = join( ' ', get_comment_class( $the_comment_class, $comment, $comment->comment_post_ID ) );
  497.  
  498.         if ( $comment->comment_post_ID > 0 ) {
  499.             $post = get_post( $comment->comment_post_ID );
  500.         }
  501.         $this->user_can = current_user_can( 'edit_comment', $comment->comment_ID );
  502.  
  503.         echo "<tr id='comment-$comment->comment_ID' class='$the_comment_class'>";
  504.         $this->single_row_columns( $comment );
  505.         echo "</tr>\n";
  506.  
  507.         unset( $GLOBALS['post'], $GLOBALS['comment'] );
  508.     }
  509.  
  510.      /**
  511.       * Generate and display row actions links.
  512.       *
  513.       * @since 4.3.0
  514.       *
  515.       * @global string $comment_status Status for the current listed comments.
  516.       *
  517.       * @param WP_Comment $comment     The comment object.
  518.       * @param string     $column_name Current column name.
  519.       * @param string     $primary     Primary column name.
  520.       * @return string|void Comment row actions output.
  521.       */
  522.      protected function handle_row_actions( $comment, $column_name, $primary ) {
  523.          global $comment_status;
  524.  
  525.         if ( $primary !== $column_name ) {
  526.             return '';
  527.         }
  528.  
  529.          if ( ! $this->user_can ) {
  530.              return;
  531.         }
  532.  
  533.         $the_comment_status = wp_get_comment_status( $comment );
  534.  
  535.         $out = '';
  536.  
  537.         $del_nonce = esc_html( '_wpnonce=' . wp_create_nonce( "delete-comment_$comment->comment_ID" ) );
  538.         $approve_nonce = esc_html( '_wpnonce=' . wp_create_nonce( "approve-comment_$comment->comment_ID" ) );
  539.  
  540.         $url = "comment.php?c=$comment->comment_ID";
  541.  
  542.         $approve_url = esc_url( $url . "&action=approvecomment&$approve_nonce" );
  543.         $unapprove_url = esc_url( $url . "&action=unapprovecomment&$approve_nonce" );
  544.         $spam_url = esc_url( $url . "&action=spamcomment&$del_nonce" );
  545.         $unspam_url = esc_url( $url . "&action=unspamcomment&$del_nonce" );
  546.         $trash_url = esc_url( $url . "&action=trashcomment&$del_nonce" );
  547.         $untrash_url = esc_url( $url . "&action=untrashcomment&$del_nonce" );
  548.         $delete_url = esc_url( $url . "&action=deletecomment&$del_nonce" );
  549.  
  550.         // Preorder it: Approve | Reply | Quick Edit | Edit | Spam | Trash.
  551.         $actions = array(
  552.             'approve' => '', 'unapprove' => '',
  553.             'reply' => '',
  554.             'quickedit' => '',
  555.             'edit' => '',
  556.             'spam' => '', 'unspam' => '',
  557.             'trash' => '', 'untrash' => '', 'delete' => ''
  558.         );
  559.  
  560.         // Not looking at all comments.
  561.         if ( $comment_status && 'all' != $comment_status ) {
  562.             if ( 'approved' === $the_comment_status ) {
  563.                 $actions['unapprove'] = "<a href='$unapprove_url' data-wp-lists='delete:the-comment-list:comment-$comment->comment_ID:e7e7d3:action=dim-comment&new=unapproved' class='vim-u vim-destructive' aria-label='" . esc_attr__( 'Unapprove this comment' ) . "'>" . __( 'Unapprove' ) . '</a>';
  564.             } elseif ( 'unapproved' === $the_comment_status ) {
  565.                 $actions['approve'] = "<a href='$approve_url' data-wp-lists='delete:the-comment-list:comment-$comment->comment_ID:e7e7d3:action=dim-comment&new=approved' class='vim-a vim-destructive' aria-label='" . esc_attr__( 'Approve this comment' ) . "'>" . __( 'Approve' ) . '</a>';
  566.             }
  567.         } else {
  568.             $actions['approve'] = "<a href='$approve_url' data-wp-lists='dim:the-comment-list:comment-$comment->comment_ID:unapproved:e7e7d3:e7e7d3:new=approved' class='vim-a' aria-label='" . esc_attr__( 'Approve this comment' ) . "'>" . __( 'Approve' ) . '</a>';
  569.             $actions['unapprove'] = "<a href='$unapprove_url' data-wp-lists='dim:the-comment-list:comment-$comment->comment_ID:unapproved:e7e7d3:e7e7d3:new=unapproved' class='vim-u' aria-label='" . esc_attr__( 'Unapprove this comment' ) . "'>" . __( 'Unapprove' ) . '</a>';
  570.         }
  571.  
  572.         if ( 'spam' !== $the_comment_status ) {
  573.             $actions['spam'] = "<a href='$spam_url' data-wp-lists='delete:the-comment-list:comment-$comment->comment_ID::spam=1' class='vim-s vim-destructive' aria-label='" . esc_attr__( 'Mark this comment as spam' ) . "'>" . /* translators: mark as spam link */ _x( 'Spam', 'verb' ) . '</a>';
  574.         } elseif ( 'spam' === $the_comment_status ) {
  575.             $actions['unspam'] = "<a href='$unspam_url' data-wp-lists='delete:the-comment-list:comment-$comment->comment_ID:66cc66:unspam=1' class='vim-z vim-destructive' aria-label='" . esc_attr__( 'Restore this comment from the spam' ) . "'>" . _x( 'Not Spam', 'comment' ) . '</a>';
  576.         }
  577.  
  578.         if ( 'trash' === $the_comment_status ) {
  579.             $actions['untrash'] = "<a href='$untrash_url' data-wp-lists='delete:the-comment-list:comment-$comment->comment_ID:66cc66:untrash=1' class='vim-z vim-destructive' aria-label='" . esc_attr__( 'Restore this comment from the Trash' ) . "'>" . __( 'Restore' ) . '</a>';
  580.         }
  581.  
  582.         if ( 'spam' === $the_comment_status || 'trash' === $the_comment_status || !EMPTY_TRASH_DAYS ) {
  583.             $actions['delete'] = "<a href='$delete_url' data-wp-lists='delete:the-comment-list:comment-$comment->comment_ID::delete=1' class='delete vim-d vim-destructive' aria-label='" . esc_attr__( 'Delete this comment permanently' ) . "'>" . __( 'Delete Permanently' ) . '</a>';
  584.         } else {
  585.             $actions['trash'] = "<a href='$trash_url' data-wp-lists='delete:the-comment-list:comment-$comment->comment_ID::trash=1' class='delete vim-d vim-destructive' aria-label='" . esc_attr__( 'Move this comment to the Trash' ) . "'>" . _x( 'Trash', 'verb' ) . '</a>';
  586.         }
  587.  
  588.         if ( 'spam' !== $the_comment_status && 'trash' !== $the_comment_status ) {
  589.             $actions['edit'] = "<a href='comment.php?action=editcomment&c={$comment->comment_ID}' aria-label='" . esc_attr__( 'Edit this comment' ) . "'>". __( 'Edit' ) . '</a>';
  590.  
  591.             $format = '<a data-comment-id="%d" data-post-id="%d" data-action="%s" class="%s" aria-label="%s" href="#">%s</a>';
  592.  
  593.             $actions['quickedit'] = sprintf( $format, $comment->comment_ID, $comment->comment_post_ID, 'edit', 'vim-q comment-inline', esc_attr__( 'Quick edit this comment inline' ), __( 'Quick Edit' ) );
  594.  
  595.             $actions['reply'] = sprintf( $format, $comment->comment_ID, $comment->comment_post_ID, 'replyto', 'vim-r comment-inline', esc_attr__( 'Reply to this comment' ), __( 'Reply' ) );
  596.         }
  597.  
  598.         /** This filter is documented in wp-admin/includes/dashboard.php */
  599.         $actions = apply_filters( 'comment_row_actions', array_filter( $actions ), $comment );
  600.  
  601.         $i = 0;
  602.         $out .= '<div class="row-actions">';
  603.         foreach ( $actions as $action => $link ) {
  604.             ++$i;
  605.             ( ( ( 'approve' === $action || 'unapprove' === $action ) && 2 === $i ) || 1 === $i ) ? $sep = '' : $sep = ' | ';
  606.  
  607.             // Reply and quickedit need a hide-if-no-js span when not added with ajax
  608.             if ( ( 'reply' === $action || 'quickedit' === $action ) && ! wp_doing_ajax() )
  609.                 $action .= ' hide-if-no-js';
  610.             elseif ( ( $action === 'untrash' && $the_comment_status === 'trash' ) || ( $action === 'unspam' && $the_comment_status === 'spam' ) ) {
  611.                 if ( '1' == get_comment_meta( $comment->comment_ID, '_wp_trash_meta_status', true ) )
  612.                     $action .= ' approve';
  613.                 else
  614.                     $action .= ' unapprove';
  615.             }
  616.  
  617.             $out .= "<span class='$action'>$sep$link</span>";
  618.         }
  619.         $out .= '</div>';
  620.  
  621.         $out .= '<button type="button" class="toggle-row"><span class="screen-reader-text">' . __( 'Show more details' ) . '</span></button>';
  622.  
  623.         return $out;
  624.     }
  625.  
  626.     /**
  627.      *
  628.      * @param WP_Comment $comment The comment object.
  629.      */
  630.     public function column_cb( $comment ) {
  631.         if ( $this->user_can ) { ?>
  632.         <label class="screen-reader-text" for="cb-select-<?php echo $comment->comment_ID; ?>"><?php _e( 'Select comment' ); ?></label>
  633.         <input id="cb-select-<?php echo $comment->comment_ID; ?>" type="checkbox" name="delete_comments[]" value="<?php echo $comment->comment_ID; ?>" />
  634.         <?php
  635.         }
  636.     }
  637.  
  638.     /**
  639.      * @param WP_Comment $comment The comment object.
  640.      */
  641.     public function column_comment( $comment ) {
  642.         echo '<div class="comment-author">';
  643.             $this->column_author( $comment );
  644.         echo '</div>';
  645.  
  646.         if ( $comment->comment_parent ) {
  647.             $parent = get_comment( $comment->comment_parent );
  648.             if ( $parent ) {
  649.                 $parent_link = esc_url( get_comment_link( $parent ) );
  650.                 $name = get_comment_author( $parent );
  651.                 printf(
  652.                     /* translators: %s: comment link */
  653.                     __( 'In reply to %s.' ),
  654.                     '<a href="' . $parent_link . '">' . $name . '</a>'
  655.                 );
  656.             }
  657.         }
  658.  
  659.         comment_text( $comment );
  660.         if ( $this->user_can ) { ?>
  661.         <div id="inline-<?php echo $comment->comment_ID; ?>" class="hidden">
  662.         <textarea class="comment" rows="1" cols="1"><?php
  663.             /** This filter is documented in wp-admin/includes/comment.php */
  664.             echo esc_textarea( apply_filters( 'comment_edit_pre', $comment->comment_content ) );
  665.         ?></textarea>
  666.         <div class="author-email"><?php echo esc_attr( $comment->comment_author_email ); ?></div>
  667.         <div class="author"><?php echo esc_attr( $comment->comment_author ); ?></div>
  668.         <div class="author-url"><?php echo esc_attr( $comment->comment_author_url ); ?></div>
  669.         <div class="comment_status"><?php echo $comment->comment_approved; ?></div>
  670.         </div>
  671.         <?php
  672.         }
  673.     }
  674.  
  675.     /**
  676.      *
  677.      * @global string $comment_status
  678.      *
  679.      * @param WP_Comment $comment The comment object.
  680.      */
  681.     public function column_author( $comment ) {
  682.         global $comment_status;
  683.  
  684.         $author_url = get_comment_author_url( $comment );
  685.  
  686.         $author_url_display = untrailingslashit( preg_replace( '|^http(s)?://(www\.)?|i', '', $author_url ) );
  687.         if ( strlen( $author_url_display ) > 50 ) {
  688.             $author_url_display = wp_html_excerpt( $author_url_display, 49, '…' );
  689.         }
  690.  
  691.         echo "<strong>"; comment_author( $comment ); echo '</strong><br />';
  692.         if ( ! empty( $author_url_display ) ) {
  693.             printf( '<a href="%s">%s</a><br />', esc_url( $author_url ), esc_html( $author_url_display ) );
  694.         }
  695.  
  696.         if ( $this->user_can ) {
  697.             if ( ! empty( $comment->comment_author_email ) ) {
  698.                 /** This filter is documented in wp-includes/comment-template.php */
  699.                 $email = apply_filters( 'comment_email', $comment->comment_author_email, $comment );
  700.  
  701.                 if ( ! empty( $email ) && '@' !== $email ) {
  702.                     printf( '<a href="%1$s">%2$s</a><br />', esc_url( 'mailto:' . $email ), esc_html( $email ) );
  703.                 }
  704.             }
  705.  
  706.             $author_ip = get_comment_author_IP( $comment );
  707.             if ( $author_ip ) {
  708.                 $author_ip_url = add_query_arg( array( 's' => $author_ip, 'mode' => 'detail' ), admin_url( 'edit-comments.php' ) );
  709.                 if ( 'spam' === $comment_status ) {
  710.                     $author_ip_url = add_query_arg( 'comment_status', 'spam', $author_ip_url );
  711.                 }
  712.                 printf( '<a href="%1$s">%2$s</a>', esc_url( $author_ip_url ), esc_html( $author_ip ) );
  713.             }
  714.         }
  715.     }
  716.  
  717.     /**
  718.      *
  719.      * @param WP_Comment $comment The comment object.
  720.      */
  721.     public function column_date( $comment ) {
  722.         /* translators: 1: comment date, 2: comment time */
  723.         $submitted = sprintf( __( '%1$s at %2$s' ),
  724.             /* translators: comment date format. See https://secure.php.net/date */
  725.             get_comment_date( __( 'Y/m/d' ), $comment ),
  726.             get_comment_date( __( 'g:i a' ), $comment )
  727.         );
  728.  
  729.         echo '<div class="submitted-on">';
  730.         if ( 'approved' === wp_get_comment_status( $comment ) && ! empty ( $comment->comment_post_ID ) ) {
  731.             printf(
  732.                 '<a href="%s">%s</a>',
  733.                 esc_url( get_comment_link( $comment ) ),
  734.                 $submitted
  735.             );
  736.         } else {
  737.             echo $submitted;
  738.         }
  739.         echo '</div>';
  740.     }
  741.  
  742.     /**
  743.      *
  744.      * @param WP_Comment $comment The comment object.
  745.      */
  746.     public function column_response( $comment ) {
  747.         $post = get_post();
  748.  
  749.         if ( ! $post ) {
  750.             return;
  751.         }
  752.  
  753.         if ( isset( $this->pending_count[$post->ID] ) ) {
  754.             $pending_comments = $this->pending_count[$post->ID];
  755.         } else {
  756.             $_pending_count_temp = get_pending_comments_num( array( $post->ID ) );
  757.             $pending_comments = $this->pending_count[$post->ID] = $_pending_count_temp[$post->ID];
  758.         }
  759.  
  760.         if ( current_user_can( 'edit_post', $post->ID ) ) {
  761.             $post_link = "<a href='" . get_edit_post_link( $post->ID ) . "' class='comments-edit-item-link'>";
  762.             $post_link .= esc_html( get_the_title( $post->ID ) ) . '</a>';
  763.         } else {
  764.             $post_link = esc_html( get_the_title( $post->ID ) );
  765.         }
  766.  
  767.         echo '<div class="response-links">';
  768.         if ( 'attachment' === $post->post_type && ( $thumb = wp_get_attachment_image( $post->ID, array( 80, 60 ), true ) ) ) {
  769.             echo $thumb;
  770.         }
  771.         echo $post_link;
  772.         $post_type_object = get_post_type_object( $post->post_type );
  773.         echo "<a href='" . get_permalink( $post->ID ) . "' class='comments-view-item-link'>" . $post_type_object->labels->view_item . '</a>';
  774.         echo '<span class="post-com-count-wrapper post-com-count-', $post->ID, '">';
  775.         $this->comments_bubble( $post->ID, $pending_comments );
  776.         echo '</span> ';
  777.         echo '</div>';
  778.     }
  779.  
  780.     /**
  781.      *
  782.      * @param WP_Comment $comment     The comment object.
  783.      * @param string     $column_name The custom column's name.
  784.      */
  785.     public function column_default( $comment, $column_name ) {
  786.         /**
  787.          * Fires when the default column output is displayed for a single row.
  788.          *
  789.          * @since 2.8.0
  790.          *
  791.          * @param string $column_name         The custom column's name.
  792.          * @param int    $comment->comment_ID The custom column's unique ID number.
  793.          */
  794.         do_action( 'manage_comments_custom_column', $column_name, $comment->comment_ID );
  795.     }
  796. }
  797.