[ Index ] |
PHP Cross Reference of BuddyPress |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * BuddyPress Activity component admin list table. 4 * 5 * Props to WordPress core for the Comments admin screen, and its contextual 6 * help text, on which this implementation is heavily based. 7 * 8 * @package BuddyPress 9 * @subpackage ActivityAdmin 10 * @since 1.6.0 11 */ 12 13 // Exit if accessed directly. 14 defined( 'ABSPATH' ) || exit; 15 16 /** 17 * List table class for the Activity component admin page. 18 * 19 * @since 1.6.0 20 */ 21 class BP_Activity_List_Table extends WP_List_Table { 22 23 /** 24 * What type of view is being displayed? 25 * 26 * E.g. "all", "pending", "approved", "spam"... 27 * 28 * @since 1.6.0 29 * @var string $view 30 */ 31 public $view = 'all'; 32 33 /** 34 * How many activity items have been marked as spam. 35 * 36 * @since 1.6.0 37 * @var int $spam_count 38 */ 39 public $spam_count = 0; 40 41 /** 42 * Total number of activities. 43 * 44 * @since 6.0.0 45 * @var int $all_count 46 */ 47 public $all_count = 0; 48 49 /** 50 * Store activity-to-user-ID mappings for use in the In Response To column. 51 * 52 * @since 1.6.0 53 * @var array $activity_user_id 54 */ 55 protected $activity_user_id = array(); 56 57 /** 58 * If users can comment on post and comment activity items. 59 * 60 * @link https://buddypress.trac.wordpress.org/ticket/6277 61 * 62 * @since 2.2.2 63 * @var bool $disable_blogforum_comments 64 */ 65 public $disable_blogforum_comments = false; 66 67 /** 68 * Constructor. 69 * 70 * @since 1.6.0 71 */ 72 public function __construct() { 73 74 // See if activity commenting is enabled for post/comment activity items. 75 $this->disable_blogforum_comments = bp_disable_blogforum_comments(); 76 77 // Define singular and plural labels, as well as whether we support AJAX. 78 parent::__construct( array( 79 'ajax' => false, 80 'plural' => 'activities', 81 'singular' => 'activity', 82 'screen' => get_current_screen(), 83 ) ); 84 } 85 86 /** 87 * Handle filtering of data, sorting, pagination, and any other data manipulation prior to rendering. 88 * 89 * @since 1.6.0 90 */ 91 function prepare_items() { 92 93 // Option defaults. 94 $filter = array(); 95 $filter_query = false; 96 $include_id = false; 97 $search_terms = false; 98 $sort = 'DESC'; 99 $spam = 'ham_only'; 100 101 // Set current page. 102 $page = $this->get_pagenum(); 103 104 // Set per page from the screen options. 105 $per_page = $this->get_items_per_page( str_replace( '-', '_', "{$this->screen->id}_per_page" ) ); 106 107 // Check if we're on the "Spam" view. 108 if ( ! empty( $_REQUEST['activity_status'] ) && 'spam' === $_REQUEST['activity_status'] ) { 109 $spam = 'spam_only'; 110 $this->view = 'spam'; 111 } 112 113 // Filter. 114 if ( ! empty( $_REQUEST['activity_type'] ) ) { 115 $filter = array( 'action' => $_REQUEST['activity_type'] ); 116 117 // Set the view as a filtered one. 118 $this->view = 'filtered'; 119 120 /** 121 * Filter here to override the filter with a filter query 122 * 123 * @since 2.5.0 124 * 125 * @param array $filter 126 */ 127 $has_filter_query = apply_filters( 'bp_activity_list_table_filter_activity_type_items', $filter ); 128 129 if ( ! empty( $has_filter_query['filter_query'] ) ) { 130 // Reset the filter. 131 $filter = array(); 132 133 // And use the filter query instead. 134 $filter_query = $has_filter_query['filter_query']; 135 } 136 } 137 138 // Are we doing a search? 139 if ( ! empty( $_REQUEST['s'] ) ) { 140 $search_terms = $_REQUEST['s']; 141 142 // Set the view as a search request. 143 $this->view = 'search'; 144 } 145 146 // Check if user has clicked on a specific activity (if so, fetch only that, and any related, activity). 147 if ( ! empty( $_REQUEST['aid'] ) ) { 148 $include_id = (int) $_REQUEST['aid']; 149 150 // Set the view as a single activity. 151 $this->view = 'single'; 152 } 153 154 // Get the spam total (ignoring any search query or filter). 155 $spams = bp_activity_get( array( 156 'display_comments' => 'stream', 157 'show_hidden' => true, 158 'spam' => 'spam_only', 159 'count_total_only' => true, 160 ) ); 161 $this->spam_count = $spams['total']; 162 unset( $spams ); 163 164 // Get the activities from the database. 165 $activities = bp_activity_get( array( 166 'display_comments' => 'stream', 167 'filter' => $filter, 168 'in' => $include_id, 169 'page' => $page, 170 'per_page' => $per_page, 171 'search_terms' => $search_terms, 172 'filter_query' => $filter_query, 173 'show_hidden' => true, 174 'spam' => $spam, 175 'count_total' => 'count_query', 176 ) ); 177 178 // If we're viewing a specific activity, flatten all activities into a single array. 179 if ( $include_id ) { 180 $activities['activities'] = BP_Activity_List_Table::flatten_activity_array( $activities['activities'] ); 181 $activities['total'] = count( $activities['activities'] ); 182 183 // Sort the array by the activity object's date_recorded value. 184 usort( $activities['activities'], function( $a, $b ) { return $a->date_recorded > $b->date_recorded; } ); 185 } 186 187 // The bp_activity_get function returns an array of objects; cast these to arrays for WP_List_Table. 188 $new_activities = array(); 189 foreach ( $activities['activities'] as $activity_item ) { 190 $new_activities[] = (array) $activity_item; 191 192 // Build an array of activity-to-user ID mappings for better efficiency in the In Response To column. 193 $this->activity_user_id[$activity_item->id] = $activity_item->user_id; 194 } 195 196 // Set raw data to display. 197 $this->items = $new_activities; 198 199 // Store information needed for handling table pagination. 200 $this->set_pagination_args( array( 201 'per_page' => $per_page, 202 'total_items' => $activities['total'], 203 'total_pages' => ceil( $activities['total'] / $per_page ) 204 ) ); 205 206 // Don't truncate activity items; bp_activity_truncate_entry() needs to be used inside a BP_Activity_Template loop. 207 remove_filter( 'bp_get_activity_content_body', 'bp_activity_truncate_entry', 5 ); 208 209 // Set the Total number of activities. 210 if ( 'all' === $this->view ) { 211 $this->all_count = (int) $activities['total']; 212 213 // Only perform a query if not on the main list view. 214 } elseif ( 'single' !== $this->view ) { 215 $count_activities = bp_activity_get( 216 array( 217 'fields' => 'ids', 218 'show_hidden' => true, 219 'count_total_only' => true, 220 ) 221 ); 222 223 if ( $count_activities['total'] ) { 224 $this->all_count = (int) $count_activities['total']; 225 } 226 } 227 } 228 229 /** 230 * Get an array of all the columns on the page. 231 * 232 * @since 1.6.0 233 * 234 * @return array Column headers. 235 */ 236 function get_column_info() { 237 $this->_column_headers = array( 238 $this->get_columns(), 239 array(), 240 $this->get_sortable_columns(), 241 $this->get_default_primary_column_name(), 242 ); 243 244 return $this->_column_headers; 245 } 246 247 /** 248 * Get name of default primary column 249 * 250 * @since 2.3.3 251 * 252 * @return string 253 */ 254 protected function get_default_primary_column_name() { 255 return 'author'; 256 } 257 258 /** 259 * Display a message on screen when no items are found (e.g. no search matches). 260 * 261 * @since 1.6.0 262 */ 263 function no_items() { 264 _e( 'No activities found.', 'buddypress' ); 265 } 266 267 /** 268 * Output the Activity data table. 269 * 270 * @since 1.6.0 271 */ 272 function display() { 273 $this->display_tablenav( 'top' ); ?> 274 275 <h2 class="screen-reader-text"><?php 276 /* translators: accessibility text */ 277 _e( 'Activities list', 'buddypress' ); 278 ?></h2> 279 280 <table class="wp-list-table <?php echo implode( ' ', $this->get_table_classes() ); ?>" cellspacing="0"> 281 <thead> 282 <tr> 283 <?php $this->print_column_headers(); ?> 284 </tr> 285 </thead> 286 287 <tbody id="the-comment-list"> 288 <?php $this->display_rows_or_placeholder(); ?> 289 </tbody> 290 291 <tfoot> 292 <tr> 293 <?php $this->print_column_headers( false ); ?> 294 </tr> 295 </tfoot> 296 </table> 297 <?php 298 299 $this->display_tablenav( 'bottom' ); 300 } 301 302 /** 303 * Generate content for a single row of the table. 304 * 305 * @since 1.6.0 306 * 307 * @param object $item The current item. 308 */ 309 function single_row( $item ) { 310 static $even = false; 311 312 if ( $even ) { 313 $row_class = ' class="even"'; 314 } else { 315 $row_class = ' class="alternate odd"'; 316 } 317 318 if ( 'activity_comment' === $item['type'] ) { 319 $root_id = $item['item_id']; 320 } else { 321 $root_id = $item['id']; 322 } 323 324 echo '<tr' . $row_class . ' id="activity-' . esc_attr( $item['id'] ) . '" data-parent_id="' . esc_attr( $item['id'] ) . '" data-root_id="' . esc_attr( $root_id ) . '">'; 325 echo $this->single_row_columns( $item ); 326 echo '</tr>'; 327 328 $even = ! $even; 329 } 330 331 /** 332 * Get the list of views available on this table (e.g. "all", "spam"). 333 * 334 * @since 1.6.0 335 */ 336 function get_views() { 337 $url_base = add_query_arg( array( 'page' => 'bp-activity' ), bp_get_admin_url( 'admin.php' ) ); ?> 338 339 <h2 class="screen-reader-text"><?php 340 /* translators: accessibility text */ 341 esc_html_e( 'Filter activities list', 'buddypress' ); 342 ?></h2> 343 344 <ul class="subsubsub"> 345 <li class="all"> 346 <a href="<?php echo esc_url( $url_base ); ?>" class="<?php if ( 'all' === $this->view ) echo 'current'; ?>"> 347 <?php printf( 348 /* translators: %s is the placeholder for the count html tag `<span class="count"/>` */ 349 esc_html__( 'All %s', 'buddypress' ), 350 sprintf( 351 '<span class="count">(%s)</span>', 352 number_format_i18n( $this->all_count ) 353 ) 354 ); ?> 355 </a> | 356 </li> 357 <li class="spam"> 358 <a href="<?php echo esc_url( add_query_arg( array( 'activity_status' => 'spam' ), $url_base ) ); ?>" class="<?php if ( 'spam' === $this->view ) echo 'current'; ?>"> 359 <?php printf( 360 /* translators: %s is the placeholder for the count html tag `<span class="count"/>` */ 361 esc_html__( 'Spam %s', 'buddypress' ), 362 sprintf( 363 '<span class="count">(%s)</span>', 364 number_format_i18n( $this->spam_count ) 365 ) 366 ); ?> 367 </a> 368 </li> 369 370 <?php 371 372 /** 373 * Fires inside listing of views so plugins can add their own. 374 * 375 * @since 1.6.0 376 * 377 * @param string $url_base Current URL base for view. 378 * @param string $view Current view being displayed. 379 */ 380 do_action( 'bp_activity_list_table_get_views', $url_base, $this->view ); ?> 381 </ul> 382 <?php 383 } 384 385 /** 386 * Get bulk actions. 387 * 388 * @since 1.6.0 389 * 390 * @return array Key/value pairs for the bulk actions dropdown. 391 */ 392 public function get_bulk_actions() { 393 394 /** 395 * Filters the default bulk actions so plugins can add custom actions. 396 * 397 * @since 1.6.0 398 * 399 * @param array $actions Default available actions for bulk operations. 400 */ 401 return apply_filters( 'bp_activity_list_table_get_bulk_actions', array( 402 'bulk_spam' => __( 'Mark as Spam', 'buddypress' ), 403 'bulk_ham' => __( 'Not Spam', 'buddypress' ), 404 'bulk_delete' => __( 'Delete Permanently', 'buddypress' ), 405 ) ); 406 } 407 408 /** 409 * Get the table column titles. 410 * 411 * @since 1.6.0 412 * 413 * @see WP_List_Table::single_row_columns() 414 * 415 * @return array The columns to appear in the Activity list table. 416 */ 417 function get_columns() { 418 419 /** 420 * Filters the titles for the columns for the activity list table. 421 * 422 * @since 2.4.0 423 * 424 * @param array $value Array of slugs and titles for the columns. 425 */ 426 return apply_filters( 'bp_activity_list_table_get_columns', array( 427 'cb' => '<input name type="checkbox" />', 428 'author' => _x( 'Author', 'Admin SWA column header', 'buddypress' ), 429 'comment' => _x( 'Activity', 'Admin SWA column header', 'buddypress' ), 430 'action' => _x( 'Action', 'Admin SWA column header', 'buddypress' ), 431 'response' => _x( 'In Response To', 'Admin SWA column header', 'buddypress' ), 432 ) ); 433 } 434 435 /** 436 * Get the column names for sortable columns. 437 * 438 * @since 1.6.0 439 * 440 * @return array The columns that can be sorted on the Activity screen. 441 */ 442 public function get_sortable_columns() { 443 444 /** 445 * Filters the column names for the sortable columns. 446 * 447 * @since 5.0.0 448 * 449 * @param array $value Array of column names. 450 */ 451 return apply_filters( 'bp_activity_list_table_get_sortable_columns', array() ); 452 } 453 454 /** 455 * Markup for the "filter" part of the form (i.e. which activity type to display). 456 * 457 * @since 1.6.0 458 * 459 * @param string $which 'top' or 'bottom'. 460 */ 461 function extra_tablenav( $which ) { 462 463 // Bail on bottom table nav. 464 if ( 'bottom' === $which ) { 465 return; 466 } 467 468 // Is any filter currently selected? 469 $selected = ( ! empty( $_REQUEST['activity_type'] ) ) ? $_REQUEST['activity_type'] : ''; 470 471 // Get the actions. 472 $activity_actions = bp_activity_get_actions(); ?> 473 474 <div class="alignleft actions"> 475 <label for="activity-type" class="screen-reader-text"><?php 476 /* translators: accessibility text */ 477 _e( 'Filter by activity type', 'buddypress' ); 478 ?></label> 479 <select name="activity_type" id="activity-type"> 480 <option value="" <?php selected( ! $selected ); ?>><?php _e( 'View all actions', 'buddypress' ); ?></option> 481 482 <?php foreach ( $activity_actions as $component => $actions ) : ?> 483 <?php 484 // Older avatar activity items use 'profile' for component. See r4273. 485 if ( $component === 'profile' ) { 486 $component = 'xprofile'; 487 } 488 489 // The 'activity_update' filter is already used by the Activity component. 490 if ( isset( $actions->activity_update ) && 'bp_groups_format_activity_action_group_activity_update' === $actions->activity_update['format_callback'] ) { 491 unset( $actions->activity_update ); 492 } 493 494 if ( bp_is_active( $component ) ) { 495 if ( $component === 'xprofile' ) { 496 $component_name = buddypress()->profile->name; 497 } else { 498 $component_name = buddypress()->$component->name; 499 } 500 501 } else { 502 // Prevent warnings by other plugins if a component is disabled but the activity type has been registered. 503 $component_name = ucfirst( $component ); 504 } 505 ?> 506 507 <optgroup label="<?php echo esc_html( $component_name ); ?>"> 508 509 <?php foreach ( $actions as $action_key => $action_values ) : ?> 510 511 <?php 512 513 // Skip the incorrectly named pre-1.6 action. 514 if ( 'friends_register_activity_action' !== $action_key ) : ?> 515 516 <option value="<?php echo esc_attr( $action_key ); ?>" <?php selected( $action_key, $selected ); ?>><?php echo esc_html( $action_values[ 'value' ] ); ?></option> 517 518 <?php endif; ?> 519 520 <?php endforeach; ?> 521 522 </optgroup> 523 524 <?php endforeach; ?> 525 526 </select> 527 528 <?php submit_button( __( 'Filter', 'buddypress' ), 'secondary', false, false, array( 'id' => 'post-query-submit' ) ); ?> 529 </div> 530 531 <?php 532 } 533 534 /** 535 * Override WP_List_Table::row_actions(). 536 * 537 * Basically a duplicate of the row_actions() method, but removes the 538 * unnecessary <button> addition. 539 * 540 * @since 2.3.3 541 * @since 2.3.4 Visibility set to public for compatibility with WP < 4.0.0. 542 * 543 * @param array $actions The list of actions. 544 * @param bool $always_visible Whether the actions should be always visible. 545 * @return string 546 */ 547 public function row_actions( $actions, $always_visible = false ) { 548 $action_count = count( $actions ); 549 $i = 0; 550 551 if ( !$action_count ) 552 return ''; 553 554 $out = '<div class="' . ( $always_visible ? 'row-actions visible' : 'row-actions' ) . '">'; 555 foreach ( $actions as $action => $link ) { 556 ++$i; 557 ( $i == $action_count ) ? $sep = '' : $sep = ' | '; 558 $out .= "<span class='$action'>$link$sep</span>"; 559 } 560 $out .= '</div>'; 561 562 return $out; 563 } 564 565 /** 566 * Checkbox column markup. 567 * 568 * @since 1.6.0 569 * 570 * @see WP_List_Table::single_row_columns() 571 * 572 * @param array $item A singular item (one full row). 573 */ 574 function column_cb( $item ) { 575 /* translators: accessibility text */ 576 printf( '<label class="screen-reader-text" for="aid-%1$d">' . __( 'Select activity item %1$d', 'buddypress' ) . '</label><input type="checkbox" name="aid[]" value="%1$d" id="aid-%1$d" />', $item['id'] ); 577 } 578 579 /** 580 * Author column markup. 581 * 582 * @since 1.6.0 583 * 584 * @see WP_List_Table::single_row_columns() 585 * 586 * @param array $item A singular item (one full row). 587 */ 588 function column_author( $item ) { 589 echo '<strong>' . get_avatar( $item['user_id'], '32' ) . ' ' . bp_core_get_userlink( $item['user_id'] ) . '</strong>'; 590 } 591 592 /** 593 * Action column markup. 594 * 595 * @since 2.0.0 596 * 597 * @see WP_List_Table::single_row_columns() 598 * 599 * @param array $item A singular item (one full row). 600 */ 601 function column_action( $item ) { 602 $actions = bp_activity_admin_get_activity_actions(); 603 604 if ( isset( $actions[ $item['type'] ] ) ) { 605 echo $actions[ $item['type'] ]; 606 } else { 607 /* translators: %s: the name of the activity type */ 608 printf( __( 'Unregistered action - %s', 'buddypress' ), $item['type'] ); 609 } 610 } 611 612 /** 613 * Content column, and "quick admin" rollover actions. 614 * 615 * Called "comment" in the CSS so we can re-use some WP core CSS. 616 * 617 * @since 1.6.0 618 * 619 * @see WP_List_Table::single_row_columns() 620 * 621 * @param array $item A singular item (one full row). 622 */ 623 function column_comment( $item ) { 624 // Determine what type of item (row) we're dealing with. 625 if ( $item['is_spam'] ) 626 $item_status = 'spam'; 627 else 628 $item_status = 'all'; 629 630 // Preorder items: Reply | Edit | Spam | Delete Permanently. 631 $actions = array( 632 'reply' => '', 633 'edit' => '', 634 'spam' => '', 'unspam' => '', 635 'delete' => '', 636 ); 637 638 // Build actions URLs. 639 $base_url = bp_get_admin_url( 'admin.php?page=bp-activity&aid=' . $item['id'] ); 640 $spam_nonce = esc_html( '_wpnonce=' . wp_create_nonce( 'spam-activity_' . $item['id'] ) ); 641 642 $delete_url = $base_url . "&action=delete&$spam_nonce"; 643 $edit_url = $base_url . '&action=edit'; 644 $ham_url = $base_url . "&action=ham&$spam_nonce"; 645 $spam_url = $base_url . "&action=spam&$spam_nonce"; 646 647 // Rollover actions. 648 // Reply - JavaScript only; implemented by AJAX. 649 if ( 'spam' != $item_status ) { 650 if ( $this->can_comment( $item ) ) { 651 $actions['reply'] = sprintf( '<a href="#" class="reply hide-if-no-js">%s</a>', esc_html__( 'Reply', 'buddypress' ) ); 652 } else { 653 $actions['reply'] = sprintf( '<span class="form-input-tip">%s</span>', esc_html__( 'Replies disabled', 'buddypress' ) ); 654 } 655 656 // Edit. 657 $actions['edit'] = sprintf( '<a href="%s">%s</a>', esc_url( $edit_url ), esc_html__( 'Edit', 'buddypress' ) ); 658 } 659 660 // Spam/unspam. 661 if ( 'spam' == $item_status ) { 662 $actions['unspam'] = sprintf( '<a href="%s">%s</a>', esc_url( $ham_url ), esc_html__( 'Not Spam', 'buddypress' ) ); 663 } else { 664 $actions['spam'] = sprintf( '<a href="%s">%s</a>', esc_url( $spam_url ), esc_html__( 'Spam', 'buddypress' ) ); 665 } 666 667 // Delete. 668 $actions['delete'] = sprintf( '<a href="%1$s">%2$s</a>', esc_url( $delete_url ), esc_html__( 'Delete Permanently', 'buddypress' ) ); 669 670 // Start timestamp. 671 echo '<div class="submitted-on">'; 672 673 /** 674 * Filters available actions for plugins to alter. 675 * 676 * @since 1.6.0 677 * 678 * @param array $actions Array of available actions user could use. 679 * @param array $item Current item being added to page. 680 */ 681 $actions = apply_filters( 'bp_activity_admin_comment_row_actions', array_filter( $actions ), $item ); 682 683 printf( 684 /* translators: %s: activity date and time */ 685 __( 'Submitted on %s', 'buddypress' ), 686 sprintf( 687 '<a href="%1$s">%2$s</a>', 688 bp_activity_get_permalink( $item['id'] ), 689 sprintf( 690 /* translators: 1: activity date, 2: activity time */ 691 __( '%1$s at %2$s', 'buddypress' ), 692 date_i18n( bp_get_option( 'date_format' ), strtotime( $item['date_recorded'] ) ), 693 get_date_from_gmt( $item['date_recorded'], bp_get_option( 'time_format' ) ) 694 ) 695 ) 696 ); 697 698 // End timestamp. 699 echo '</div>'; 700 701 $activity = new BP_Activity_Activity( $item['id'] ); 702 703 // Get activity content - if not set, use the action. 704 if ( ! empty( $item['content'] ) ) { 705 /** This filter is documented in bp-activity/bp-activity-template.php */ 706 $content = apply_filters_ref_array( 'bp_get_activity_content_body', array( $item['content'], &$activity ) ); 707 } else { 708 // Emulate bp_get_activity_action(). 709 $r = array( 710 'no_timestamp' => false, 711 ); 712 713 /** This filter is documented in bp-activity/bp-activity-template.php */ 714 $content = apply_filters_ref_array( 'bp_get_activity_action', array( $item['action'], &$activity, $r ) ); 715 } 716 717 /** 718 * Filter here to add extra output to the activity content into the Administration. 719 * 720 * @since 2.4.0 721 * 722 * @param string $content The activity content. 723 * @param array $item The activity object converted into an array. 724 */ 725 echo apply_filters( 'bp_activity_admin_comment_content', $content, $item ) . ' ' . $this->row_actions( $actions ); 726 } 727 728 /** 729 * "In response to" column markup. 730 * 731 * @since 1.6.0 732 * 733 * @see WP_List_Table::single_row_columns() 734 * 735 * @param array $item A singular item (one full row). 736 */ 737 function column_response( $item ) { 738 739 // Is $item is a root activity? 740 ?> 741 742 <div class="response-links"> 743 744 <?php 745 // Activity permalink. 746 $activity_permalink = ''; 747 if ( ! $item['is_spam'] ) { 748 $activity_permalink = '<a href="' . bp_activity_get_permalink( $item['id'], (object) $item ) . '" class="comments-view-item-link">' . __( 'View Activity', 'buddypress' ) . '</a>'; 749 } 750 751 /** 752 * Filters default list of default root activity types. 753 * 754 * @since 1.6.0 755 * 756 * @param array $value Array of default activity types. 757 * @param array $item Current item being displayed. 758 */ 759 if ( empty( $item['item_id'] ) || ! in_array( $item['type'], apply_filters( 'bp_activity_admin_root_activity_types', array( 'activity_comment' ), $item ) ) ) { 760 echo $activity_permalink; 761 762 $comment_count = !empty( $item['children'] ) ? bp_activity_recurse_comment_count( (object) $item ) : 0; 763 $root_activity_url = bp_get_admin_url( 'admin.php?page=bp-activity&aid=' . $item['id'] ); 764 765 // If the activity has comments, display a link to the activity's permalink, with its comment count in a speech bubble. 766 if ( $comment_count ) { 767 printf( '<a href="%1$s" class="post-com-count post-com-count-approved"><span class="comment-count comment-count-approved">%2$s</span></a>', esc_url( $root_activity_url ), number_format_i18n( $comment_count ) ); 768 } 769 770 // For non-root activities, display a link to the replied-to activity's author's profile. 771 } else { 772 echo '<strong>' . get_avatar( $this->get_activity_user_id( $item['item_id'] ), '32' ) . ' ' . bp_core_get_userlink( $this->get_activity_user_id( $item['item_id'] ) ) . '</strong><br />'; 773 echo $activity_permalink; 774 } 775 ?> 776 777 </div> 778 779 <?php 780 } 781 782 /** 783 * Allow plugins to add their custom column. 784 * 785 * @since 2.4.0 786 * 787 * @param array $item Information about the current row. 788 * @param string $column_name The column name. 789 * @return string 790 */ 791 public function column_default( $item = array(), $column_name = '' ) { 792 793 /** 794 * Filters a string to allow plugins to add custom column content. 795 * 796 * @since 2.4.0 797 * 798 * @param string $value Empty string. 799 * @param string $column_name Name of the column being rendered. 800 * @param array $item The current activity item in the loop. 801 */ 802 return apply_filters( 'bp_activity_admin_get_custom_column', '', $column_name, $item ); 803 } 804 805 /** 806 * Get the user id associated with a given activity item. 807 * 808 * Wraps bp_activity_get_specific(), with some additional logic for 809 * avoiding duplicate queries. 810 * 811 * @since 1.6.0 812 * 813 * @param int $activity_id Activity ID to retrieve User ID for. 814 * @return int User ID of the activity item in question. 815 */ 816 protected function get_activity_user_id( $activity_id ) { 817 // If there is an existing activity/user ID mapping, just return the user ID. 818 if ( ! empty( $this->activity_user_id[$activity_id] ) ) { 819 return $this->activity_user_id[$activity_id]; 820 821 /* 822 * We don't have a mapping. This means the $activity_id is not on the current 823 * page of results, so fetch its details from the database. 824 */ 825 } else { 826 $activity = bp_activity_get_specific( array( 'activity_ids' => $activity_id, 'show_hidden' => true, 'spam' => 'all', ) ); 827 828 /* 829 * If, somehow, the referenced activity has been deleted, leaving its associated 830 * activities as orphans, use the logged in user's ID to avoid errors. 831 */ 832 if ( empty( $activity['activities'] ) ) 833 return bp_loggedin_user_id(); 834 835 // Store the new activity/user ID mapping for any later re-use. 836 $this->activity_user_id[ $activity['activities'][0]->id ] = $activity['activities'][0]->user_id; 837 838 // Return the user ID. 839 return $activity['activities'][0]->user_id; 840 } 841 } 842 843 /** 844 * Checks if an activity item can be replied to. 845 * 846 * This method merges functionality from {@link bp_activity_can_comment()} and 847 * {@link bp_blogs_disable_activity_commenting()}. This is done because the activity 848 * list table doesn't use a BuddyPress activity loop, which prevents those 849 * functions from working as intended. 850 * 851 * @since 2.0.0 852 * @since 2.5.0 Include Post type activities types 853 * 854 * @param array $item An array version of the BP_Activity_Activity object. 855 * @return bool $can_comment 856 */ 857 protected function can_comment( $item ) { 858 $can_comment = bp_activity_type_supports( $item['type'], 'comment-reply' ); 859 860 if ( ! $this->disable_blogforum_comments && bp_is_active( 'blogs' ) ) { 861 $parent_activity = false; 862 863 if ( bp_activity_type_supports( $item['type'], 'post-type-comment-tracking' ) ) { 864 $parent_activity = (object) $item; 865 } elseif ( 'activity_comment' === $item['type'] ) { 866 $parent_activity = new BP_Activity_Activity( $item['item_id'] ); 867 $can_comment = bp_activity_can_comment_reply( (object) $item ); 868 } 869 870 if ( isset( $parent_activity->type ) && bp_activity_post_type_get_tracking_arg( $parent_activity->type, 'post_type' ) ) { 871 // Fetch blog post comment depth and if the blog post's comments are open. 872 bp_blogs_setup_activity_loop_globals( $parent_activity ); 873 874 $can_comment = bp_blogs_can_comment_reply( true, $item ); 875 } 876 } 877 878 /** 879 * Filters if an activity item can be commented on or not. 880 * 881 * @since 2.0.0 882 * @since 2.5.0 Add a second parameter to include the activity item into the filter. 883 * 884 * @param bool $can_comment Whether an activity item can be commented on or not. 885 * @param array $item An array version of the BP_Activity_Activity object. 886 */ 887 return apply_filters( 'bp_activity_list_table_can_comment', $can_comment, $item ); 888 } 889 890 /** 891 * Flatten the activity array. 892 * 893 * In some cases, BuddyPress gives us a structured tree of activity 894 * items plus their comments. This method converts it to a flat array. 895 * 896 * @since 1.6.0 897 * 898 * @param array $tree Source array. 899 * @return array Flattened array. 900 */ 901 public static function flatten_activity_array( $tree ){ 902 foreach ( (array) $tree as $node ) { 903 if ( isset( $node->children ) ) { 904 905 foreach ( BP_Activity_List_Table::flatten_activity_array( $node->children ) as $child ) { 906 $tree[] = $child; 907 } 908 909 unset( $node->children ); 910 } 911 } 912 913 return $tree; 914 } 915 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Nov 21 01:00:57 2024 | Cross-referenced by PHPXref 0.7.1 |