[ Index ]

PHP Cross Reference of BuddyPress

title

Body

[close]

/src/bp-blogs/ -> bp-blogs-activity.php (source)

   1  <?php
   2  /**
   3   * BuddyPress Blogs Activity.
   4   *
   5   * @package BuddyPress
   6   * @subpackage BlogsActivity
   7   * @since 1.5.0
   8   */
   9  
  10  // Exit if accessed directly.
  11  defined( 'ABSPATH' ) || exit;
  12  
  13  /**
  14   * Register activity actions for the blogs component.
  15   *
  16   * @since 1.0.0
  17   *
  18   * @return bool|null Returns false if activity component is not active.
  19   */
  20  function bp_blogs_register_activity_actions() {
  21      if ( is_multisite() ) {
  22          bp_activity_set_action(
  23              buddypress()->blogs->id,
  24              'new_blog',
  25              __( 'New site created', 'buddypress' ),
  26              'bp_blogs_format_activity_action_new_blog',
  27              __( 'New Sites', 'buddypress' ),
  28              array( 'activity', 'member' ),
  29              0
  30          );
  31      }
  32  
  33      /**
  34       * Fires after the registry of the default blog component activity actions.
  35       *
  36       * @since 1.1.0
  37       */
  38      do_action( 'bp_blogs_register_activity_actions' );
  39  }
  40  add_action( 'bp_register_activity_actions', 'bp_blogs_register_activity_actions' );
  41  
  42  /**
  43   * Set up the tracking arguments for the 'post' post type.
  44   *
  45   * @since 2.5.0 This was moved out of the BP_Blogs_Component class.
  46   *
  47   * @see bp_activity_get_post_type_tracking_args() for information on parameters.
  48   *
  49   * @param object|null $params    Tracking arguments.
  50   * @param string|int  $post_type Post type to track.
  51   * @return object|null
  52   */
  53  function bp_blogs_register_post_tracking_args( $params = null, $post_type = 0 ) {
  54  
  55      /**
  56       * Filters the post types to track for the Blogs component.
  57       *
  58       * @since 1.5.0
  59       * @deprecated 2.3.0
  60       *
  61       * Make sure plugins still using 'bp_blogs_record_post_post_types'
  62       * to track their post types will generate new_blog_post activities
  63       * See https://buddypress.trac.wordpress.org/ticket/6306
  64       *
  65       * @param array $value Array of post types to track.
  66       */
  67      $post_types = apply_filters( 'bp_blogs_record_post_post_types', array( 'post' ) );
  68      $post_types_array = array_flip( $post_types );
  69  
  70      if ( ! isset( $post_types_array[ $post_type ] ) ) {
  71          return $params;
  72      }
  73  
  74      // Set specific params for the 'post' post type.
  75      $params->component_id    = buddypress()->blogs->id;
  76      $params->action_id       = 'new_blog_post';
  77      $params->admin_filter    = __( 'New post published', 'buddypress' );
  78      $params->format_callback = 'bp_blogs_format_activity_action_new_blog_post';
  79      $params->front_filter    = __( 'Posts', 'buddypress' );
  80      $params->contexts        = array( 'activity', 'member' );
  81      $params->position        = 5;
  82  
  83      if ( post_type_supports( $post_type, 'comments' ) ) {
  84          $params->comment_action_id = 'new_blog_comment';
  85  
  86          /**
  87           * Filters the post types to track for the Blogs component.
  88           *
  89           * @since 1.5.0
  90           * @deprecated 2.5.0
  91           *
  92           * Make sure plugins still using 'bp_blogs_record_comment_post_types'
  93           * to track comment about their post types will generate new_blog_comment activities
  94           * See https://buddypress.trac.wordpress.org/ticket/6306
  95           *
  96           * @param array $value Array of post types to track.
  97           */
  98          $comment_post_types = apply_filters( 'bp_blogs_record_comment_post_types', array( 'post' ) );
  99          $comment_post_types_array = array_flip( $comment_post_types );
 100  
 101          if ( isset( $comment_post_types_array[ $post_type ] ) ) {
 102              $params->comments_tracking = new stdClass();
 103              $params->comments_tracking->component_id    = buddypress()->blogs->id;
 104              $params->comments_tracking->action_id       = 'new_blog_comment';
 105              $params->comments_tracking->admin_filter    = __( 'New post comment posted', 'buddypress' );
 106              $params->comments_tracking->format_callback = 'bp_blogs_format_activity_action_new_blog_comment';
 107              $params->comments_tracking->front_filter    = __( 'Comments', 'buddypress' );
 108              $params->comments_tracking->contexts        = array( 'activity', 'member' );
 109              $params->comments_tracking->position        = 10;
 110          }
 111      }
 112  
 113      return $params;
 114  }
 115  add_filter( 'bp_activity_get_post_type_tracking_args', 'bp_blogs_register_post_tracking_args', 10, 2 );
 116  
 117  /**
 118   * Format 'new_blog' activity actions.
 119   *
 120   * @since 2.0.0
 121   *
 122   * @param string $action   Static activity action.
 123   * @param object $activity Activity data object.
 124   * @return string
 125   */
 126  function bp_blogs_format_activity_action_new_blog( $action, $activity ) {
 127      $blog_url  = bp_blogs_get_blogmeta( $activity->item_id, 'url' );
 128      $blog_name = bp_blogs_get_blogmeta( $activity->item_id, 'name' );
 129  
 130      $action = sprintf(
 131          /* translators: 1: the activity user link. 2: the blog link. */
 132          esc_html__( '%1$s created the site %2$s', 'buddypress' ),
 133          bp_core_get_userlink( $activity->user_id ),
 134          '<a href="' . esc_url( $blog_url ) . '">' . esc_html( $blog_name ) . '</a>'
 135      );
 136  
 137      // Legacy filter - requires the BP_Blogs_Blog object.
 138      if ( has_filter( 'bp_blogs_activity_created_blog_action' ) ) {
 139          $user_blog = BP_Blogs_Blog::get_user_blog( $activity->user_id, $activity->item_id );
 140          if ( $user_blog ) {
 141              $recorded_blog = new BP_Blogs_Blog( $user_blog );
 142          }
 143  
 144          if ( isset( $recorded_blog ) ) {
 145              $action = apply_filters( 'bp_blogs_activity_created_blog_action', $action, $recorded_blog, $blog_name, bp_blogs_get_blogmeta( $activity->item_id, 'description' ) );
 146          }
 147      }
 148  
 149      /**
 150       * Filters the new blog activity action for the new blog.
 151       *
 152       * @since 2.0.0
 153       *
 154       * @param string $action   Constructed activity action.
 155       * @param object $activity Activity data object.
 156       */
 157      return apply_filters( 'bp_blogs_format_activity_action_new_blog', $action, $activity );
 158  }
 159  
 160  /**
 161   * Format 'new_blog_post' activity actions.
 162   *
 163   * @since 2.0.0
 164   *
 165   * @param string $action   Static activity action.
 166   * @param object $activity Activity data object.
 167   * @return string Constructed activity action.
 168   */
 169  function bp_blogs_format_activity_action_new_blog_post( $action, $activity ) {
 170      $blog_url  = bp_blogs_get_blogmeta( $activity->item_id, 'url' );
 171      $blog_name = bp_blogs_get_blogmeta( $activity->item_id, 'name' );
 172  
 173      if ( empty( $blog_url ) || empty( $blog_name ) ) {
 174          $blog_url  = get_home_url( $activity->item_id );
 175          $blog_name = get_blog_option( $activity->item_id, 'blogname' );
 176  
 177          bp_blogs_update_blogmeta( $activity->item_id, 'url', $blog_url );
 178          bp_blogs_update_blogmeta( $activity->item_id, 'name', $blog_name );
 179      }
 180  
 181      /**
 182       * When the post is published we are faking an activity object
 183       * to which we add 2 properties :
 184       * - the post url
 185       * - the post title
 186       * This is done to build the 'post link' part of the activity
 187       * action string.
 188       * NB: in this case the activity has not yet been created.
 189       */
 190      if ( isset( $activity->post_url ) ) {
 191          $post_url = $activity->post_url;
 192  
 193      /**
 194       * The post_url property is not set, we need to build the url
 195       * thanks to the post id which is also saved as the secondary
 196       * item id property of the activity object.
 197       */
 198      } else {
 199          $post_url = add_query_arg( 'p', $activity->secondary_item_id, trailingslashit( $blog_url ) );
 200      }
 201  
 202      // Should be the case when the post has just been published.
 203      if ( isset( $activity->post_title ) ) {
 204          $post_title = $activity->post_title;
 205  
 206      // If activity already exists try to get the post title from activity meta.
 207      } else if ( ! empty( $activity->id ) ) {
 208          $post_title = bp_activity_get_meta( $activity->id, 'post_title' );
 209      }
 210  
 211      /**
 212       * In case the post was published without a title
 213       * or the activity meta was not found.
 214       */
 215      if ( empty( $post_title ) ) {
 216          // Defaults to no title.
 217          $post_title = __( '(no title)', 'buddypress' );
 218  
 219          switch_to_blog( $activity->item_id );
 220  
 221          $post = get_post( $activity->secondary_item_id );
 222          if ( is_a( $post, 'WP_Post' ) ) {
 223              // Does the post have a title ?
 224              if ( ! empty( $post->post_title ) ) {
 225                  $post_title = $post->post_title;
 226              }
 227  
 228              // Make sure the activity exists before saving the post title in activity meta.
 229              if ( ! empty( $activity->id ) ) {
 230                  bp_activity_update_meta( $activity->id, 'post_title', $post_title );
 231              }
 232          }
 233  
 234          restore_current_blog();
 235      }
 236  
 237      // Build the 'post link' part of the activity action string.
 238      $post_link = '<a href="' . esc_url( $post_url ) . '">' . esc_html( $post_title ) . '</a>';
 239  
 240      $user_link = bp_core_get_userlink( $activity->user_id );
 241  
 242      // Build the complete activity action string.
 243      if ( is_multisite() ) {
 244          $action = sprintf(
 245              /* translators: 1: the activity user link. 2: the post link. 3: the blog link. */
 246              esc_html_x( '%1$s wrote a new post, %2$s, on the site %3$s', '`new_blog_post` activity action', 'buddypress' ),
 247              $user_link,
 248              $post_link,
 249              '<a href="' . esc_url( $blog_url ) . '">' . esc_html( $blog_name ) . '</a>'
 250          );
 251      } else {
 252          $action = sprintf(
 253              /* translators: 1: the activity user link. 2: the post link. */
 254              esc_html_x( '%1$s wrote a new post, %2$s', '`new_blog_post` activity action', 'buddypress' ),
 255              $user_link,
 256              $post_link
 257          );
 258      }
 259  
 260      // Legacy filter - requires the post object.
 261      if ( has_filter( 'bp_blogs_activity_new_post_action' ) ) {
 262          switch_to_blog( $activity->item_id );
 263          $post = get_post( $activity->secondary_item_id );
 264          restore_current_blog();
 265  
 266          if ( ! empty( $post ) && ! is_wp_error( $post ) ) {
 267              $action = apply_filters( 'bp_blogs_activity_new_post_action', $action, $post, $post_url );
 268          }
 269      }
 270  
 271      /**
 272       * Filters the new blog post action for the new blog.
 273       *
 274       * @since 2.0.0
 275       *
 276       * @param string $action   Constructed activity action.
 277       * @param object $activity Activity data object.
 278       */
 279      return apply_filters( 'bp_blogs_format_activity_action_new_blog_post', $action, $activity );
 280  }
 281  
 282  /**
 283   * Format 'new_blog_comment' activity actions.
 284   *
 285   * @since 2.0.0
 286   *
 287   * @param string $action   Static activity action.
 288   * @param object $activity Activity data object.
 289   * @return string Constructed activity action.
 290   */
 291  function bp_blogs_format_activity_action_new_blog_comment( $action, $activity ) {
 292      /**
 293       * When the comment is published we are faking an activity object
 294       * to which we add 4 properties :
 295       * - the post url
 296       * - the post title
 297       * - the blog url
 298       * - the blog name
 299       * This is done to build the 'post link' part of the activity
 300       * action string.
 301       * NB: in this case the activity has not yet been created.
 302       */
 303  
 304      $blog_url = false;
 305  
 306      // Try to get the blog url from the activity object.
 307      if ( isset( $activity->blog_url ) ) {
 308          $blog_url = $activity->blog_url;
 309      } else {
 310          $blog_url = bp_blogs_get_blogmeta( $activity->item_id, 'url' );
 311      }
 312  
 313      $blog_name = false;
 314  
 315      // Try to get the blog name from the activity object.
 316      if ( isset( $activity->blog_name ) ) {
 317          $blog_name = $activity->blog_name;
 318      } else {
 319          $blog_name = bp_blogs_get_blogmeta( $activity->item_id, 'name' );
 320      }
 321  
 322      if ( empty( $blog_url ) || empty( $blog_name ) ) {
 323          $blog_url  = get_home_url( $activity->item_id );
 324          $blog_name = get_blog_option( $activity->item_id, 'blogname' );
 325  
 326          bp_blogs_update_blogmeta( $activity->item_id, 'url', $blog_url );
 327          bp_blogs_update_blogmeta( $activity->item_id, 'name', $blog_name );
 328      }
 329  
 330      $post_url = false;
 331  
 332      // Try to get the post url from the activity object.
 333      if ( isset( $activity->post_url ) ) {
 334          $post_url = $activity->post_url;
 335  
 336      /**
 337       * The post_url property is not set, we need to build the url
 338       * thanks to the post id which is also saved as the secondary
 339       * item id property of the activity object.
 340       */
 341      } elseif ( ! empty( $activity->id ) ) {
 342          $post_url = bp_activity_get_meta( $activity->id, 'post_url' );
 343      }
 344  
 345      $post_title = false;
 346  
 347      // Should be the case when the comment has just been published.
 348      if ( isset( $activity->post_title ) ) {
 349          $post_title = $activity->post_title;
 350  
 351      // If activity already exists try to get the post title from activity meta.
 352      } elseif ( ! empty( $activity->id ) ) {
 353          $post_title = bp_activity_get_meta( $activity->id, 'post_title' );
 354      }
 355  
 356      // Should only be empty at the time of post creation.
 357      if ( empty( $post_url ) || empty( $post_title ) ) {
 358          switch_to_blog( $activity->item_id );
 359  
 360          $comment = get_comment( $activity->secondary_item_id );
 361  
 362          if ( ! empty( $comment->comment_post_ID ) ) {
 363              $post_url = add_query_arg( 'p', $comment->comment_post_ID, trailingslashit( $blog_url ) );
 364              bp_activity_update_meta( $activity->id, 'post_url', $post_url );
 365  
 366              $post = get_post( $comment->comment_post_ID );
 367  
 368              if ( is_a( $post, 'WP_Post' ) ) {
 369                  $post_title = $post->post_title;
 370                  bp_activity_update_meta( $activity->id, 'post_title', $post_title );
 371              }
 372          }
 373  
 374          restore_current_blog();
 375      }
 376  
 377      $post_link = '<a href="' . esc_url( $post_url ) . '">' . esc_html( $post_title ) . '</a>';
 378      $user_link = bp_core_get_userlink( $activity->user_id );
 379  
 380      if ( is_multisite() ) {
 381          $action = sprintf(
 382              /* translators: 1: the activity user link. 2: the post link. 3: the blog link. */
 383              esc_html_x( '%1$s commented on the post, %2$s, on the site %3$s', '`new_blog_comment` activity action', 'buddypress' ),
 384              $user_link,
 385              $post_link,
 386              '<a href="' . esc_url( $blog_url ) . '">' . esc_html( $blog_name ) . '</a>'
 387          );
 388      } else {
 389          $action = sprintf(
 390              /* translators: 1: the activity user link. 2: the post link. */
 391              esc_html_x( '%1$s commented on the post, %2$s', '`new_blog_comment` activity action', 'buddypress' ),
 392              $user_link,
 393              $post_link
 394          );
 395      }
 396  
 397      // Legacy filter - requires the comment object.
 398      if ( has_filter( 'bp_blogs_activity_new_comment_action' ) ) {
 399          switch_to_blog( $activity->item_id );
 400          $comment = get_comment( $activity->secondary_item_id );
 401          restore_current_blog();
 402  
 403          if ( ! empty( $comment ) && ! is_wp_error( $comment ) ) {
 404              $action = apply_filters( 'bp_blogs_activity_new_comment_action', $action, $comment, $post_url . '#' . $activity->secondary_item_id );
 405          }
 406      }
 407  
 408      /**
 409       * Filters the new blog comment action for the new blog.
 410       *
 411       * @since 2.0.0
 412       *
 413       * @param string $action   Constructed activity action.
 414       * @param object $activity Activity data object.
 415       */
 416      return apply_filters( 'bp_blogs_format_activity_action_new_blog_comment', $action, $activity );
 417  }
 418  
 419  /**
 420   * Fetch data related to blogs at the beginning of an activity loop.
 421   *
 422   * This reduces database overhead during the activity loop.
 423   *
 424   * @since 2.0.0
 425   *
 426   * @param array $activities Array of activity items.
 427   * @return array
 428   */
 429  function bp_blogs_prefetch_activity_object_data( $activities ) {
 430      if ( empty( $activities ) ) {
 431          return $activities;
 432      }
 433  
 434      $blog_ids = array();
 435  
 436      foreach ( $activities as $activity ) {
 437          if ( buddypress()->blogs->id !== $activity->component ) {
 438              continue;
 439          }
 440  
 441          $blog_ids[] = $activity->item_id;
 442      }
 443  
 444      if ( ! empty( $blog_ids ) ) {
 445          bp_blogs_update_meta_cache( $blog_ids );
 446      }
 447  
 448      return $activities;
 449  }
 450  add_filter( 'bp_activity_prefetch_object_data', 'bp_blogs_prefetch_activity_object_data' );
 451  
 452  /**
 453   * Record blog-related activity to the activity stream.
 454   *
 455   * @since 1.0.0
 456   *
 457   * @see bp_activity_add() for description of parameters.
 458   *
 459   * @param array|string $args {
 460   *     See {@link bp_activity_add()} for complete description of arguments.
 461   *     The arguments listed here have different default values from
 462   *     bp_activity_add().
 463   *     @type string $component Default: 'blogs'.
 464   * }
 465   * @return WP_Error|bool|int On success, returns the activity ID. False on failure.
 466   */
 467  function bp_blogs_record_activity( $args = '' ) {
 468      $defaults = array(
 469          'user_id'           => bp_loggedin_user_id(),
 470          'action'            => '',
 471          'content'           => '',
 472          'primary_link'      => '',
 473          'component'         => buddypress()->blogs->id,
 474          'type'              => false,
 475          'item_id'           => false,
 476          'secondary_item_id' => false,
 477          'recorded_time'     => bp_core_current_time(),
 478          'hide_sitewide'     => false
 479      );
 480  
 481      $r = wp_parse_args( $args, $defaults );
 482  
 483      if ( ! empty( $r['action'] ) ) {
 484  
 485          /**
 486           * Filters the action associated with activity for activity stream.
 487           *
 488           * @since 1.2.0
 489           *
 490           * @param string $value Action for the activity stream.
 491           */
 492          $r['action'] = apply_filters( 'bp_blogs_record_activity_action', $r['action'] );
 493      }
 494  
 495      if ( ! empty( $r['content'] ) ) {
 496  
 497          /**
 498           * Filters the content associated with activity for activity stream.
 499           *
 500           * @since 1.2.0
 501           *
 502           * @param string $value Generated summary from content for the activity stream.
 503           * @param string $value Content for the activity stream.
 504           * @param array  $r     Array of arguments used for the activity stream item.
 505           */
 506          $r['content'] = apply_filters( 'bp_blogs_record_activity_content', bp_activity_create_summary( $r['content'], $r ), $r['content'], $r );
 507      }
 508  
 509      // Check for an existing entry and update if one exists.
 510      $id = bp_activity_get_activity_id( array(
 511          'user_id'           => $r['user_id'],
 512          'component'         => $r['component'],
 513          'type'              => $r['type'],
 514          'item_id'           => $r['item_id'],
 515          'secondary_item_id' => $r['secondary_item_id'],
 516      ) );
 517  
 518      return bp_activity_add( array( 'id' => $id, 'user_id' => $r['user_id'], 'action' => $r['action'], 'content' => $r['content'], 'primary_link' => $r['primary_link'], 'component' => $r['component'], 'type' => $r['type'], 'item_id' => $r['item_id'], 'secondary_item_id' => $r['secondary_item_id'], 'recorded_time' => $r['recorded_time'], 'hide_sitewide' => $r['hide_sitewide'] ) );
 519  }
 520  
 521  /**
 522   * Delete a blog-related activity stream item.
 523   *
 524   * @since 1.0.0
 525   *
 526   * @see bp_activity_delete() for description of parameters.
 527   *
 528   * @param array|string $args {
 529   *     See {@link bp_activity_delete()} for complete description of arguments.
 530   *     The arguments listed here have different default values from
 531   *     bp_activity_add().
 532   *     @type string $component Default: 'blogs'.
 533   * }
 534   * @return bool True on success, false on failure.
 535   */
 536  function bp_blogs_delete_activity( $args = '' ) {
 537      $r = bp_parse_args( $args, array(
 538          'item_id'           => false,
 539          'component'         => buddypress()->blogs->id,
 540          'type'              => false,
 541          'user_id'           => false,
 542          'secondary_item_id' => false
 543      ) );
 544  
 545      bp_activity_delete_by_item_id( $r );
 546  }
 547  
 548  /**
 549   * Check if a blog post's activity item should be closed from commenting.
 550   *
 551   * This mirrors the {@link comments_open()} and {@link _close_comments_for_old_post()}
 552   * functions, but for use with the BuddyPress activity stream to be as
 553   * lightweight as possible.
 554   *
 555   * By lightweight, we actually mirror a few of the blog's commenting settings
 556   * to blogmeta and checks the values in blogmeta instead.  This is to prevent
 557   * multiple {@link switch_to_blog()} calls in the activity stream.
 558   *
 559   * @since 2.0.0
 560   *
 561   * @param object $activity The BP_Activity_Activity object.
 562   * @return bool
 563   */
 564  function bp_blogs_comments_open( $activity ) {
 565      $open = true;
 566  
 567      $blog_id = $activity->item_id;
 568  
 569      // See if we've mirrored the close comments option before.
 570      $days_old = bp_blogs_get_blogmeta( $blog_id, 'close_comments_days_old' );
 571  
 572      // We've never cached these items before, so do it now.
 573      if ( '' === $days_old ) {
 574          switch_to_blog( $blog_id );
 575  
 576          // Use comments_open().
 577          remove_filter( 'comments_open', 'bp_comments_open', 10 );
 578          $open = comments_open( $activity->secondary_item_id );
 579          add_filter( 'comments_open', 'bp_comments_open', 10, 2 );
 580  
 581          // Might as well mirror values to blogmeta since we're here!
 582          $thread_depth = get_option( 'thread_comments' );
 583          if ( ! empty( $thread_depth ) ) {
 584              $thread_depth = get_option( 'thread_comments_depth' );
 585          } else {
 586              // Perhaps filter this?
 587              $thread_depth = 1;
 588          }
 589  
 590          bp_blogs_update_blogmeta( $blog_id, 'close_comments_for_old_posts', get_option( 'close_comments_for_old_posts' ) );
 591          bp_blogs_update_blogmeta( $blog_id, 'close_comments_days_old',      get_option( 'close_comments_days_old' ) );
 592          bp_blogs_update_blogmeta( $blog_id, 'thread_comments_depth',        $thread_depth );
 593  
 594          restore_current_blog();
 595  
 596      // Check blogmeta and manually check activity item.
 597      // Basically a copy of _close_comments_for_old_post().
 598      } else {
 599  
 600          // Comments are closed.
 601          if ( 'closed' == bp_activity_get_meta( $activity->id, 'post_comment_status' ) ) {
 602              return false;
 603          }
 604  
 605          if ( ! bp_blogs_get_blogmeta( $blog_id, 'close_comments_for_old_posts' ) ) {
 606              return $open;
 607          }
 608  
 609          $days_old = (int) $days_old;
 610          if ( ! $days_old ) {
 611              return $open;
 612          }
 613  
 614          /*
 615             Commenting out for now - needs some more thought...
 616             should we add the post type to activity meta?
 617  
 618          $post = get_post($post_id);
 619  
 620          // This filter is documented in wp-includes/comment.php
 621          $post_types = apply_filters( 'close_comments_for_post_types', array( 'post' ) );
 622          if ( ! in_array( $post->post_type, $post_types ) )
 623              return $open;
 624          */
 625  
 626          if ( time() - strtotime( $activity->date_recorded ) > ( $days_old * DAY_IN_SECONDS ) ) {
 627              return false;
 628          }
 629  
 630          return $open;
 631      }
 632  
 633      return $open;
 634  }
 635  
 636  /** SITE TRACKING *******************************************************/
 637  
 638  /**
 639   * Add an activity entry for a newly-created site.
 640   *
 641   * Hooked to the 'bp_blogs_new_blog' action.
 642   *
 643   * @since 2.6.0
 644   *
 645   * @param BP_Blogs_Blog $recorded_blog Current site being recorded. Passed by reference.
 646   * @param bool          $is_private    Whether the current site being recorded is private.
 647   * @param bool          $is_recorded   Whether the current site was recorded.
 648   */
 649  function bp_blogs_record_activity_on_site_creation( $recorded_blog, $is_private, $is_recorded, $no_activity ) {
 650      // Only record this activity if the blog is public.
 651      if ( ! $is_private && ! $no_activity && bp_blogs_is_blog_trackable( $recorded_blog->blog_id, $recorded_blog->user_id ) ) {
 652          bp_blogs_record_activity( array(
 653              'user_id'      => $recorded_blog->user_id,
 654  
 655              /**
 656               * Filters the activity created blog primary link.
 657               *
 658               * @since 1.1.0
 659               *
 660               * @param string $value Blog primary link.
 661               * @param int    $value Blog ID.
 662               */
 663              'primary_link' => apply_filters( 'bp_blogs_activity_created_blog_primary_link', bp_blogs_get_blogmeta( $recorded_blog->blog_id, 'url' ), $recorded_blog->blog_id ),
 664              'type'         => 'new_blog',
 665              'item_id'      => $recorded_blog->blog_id
 666          ) );
 667      }
 668  }
 669  add_action( 'bp_blogs_new_blog', 'bp_blogs_record_activity_on_site_creation', 10, 4 );
 670  
 671  /**
 672   * Deletes the 'new_blog' activity entry when a site is deleted.
 673   *
 674   * @since 2.6.0
 675   *
 676   * @param int $blog_id Site ID.
 677   */
 678  function bp_blogs_delete_new_blog_activity_for_site( $blog_id, $user_id = 0 ) {
 679      $args = array(
 680          'item_id'   => $blog_id,
 681          'component' => buddypress()->blogs->id,
 682          'type'      => 'new_blog'
 683      );
 684  
 685      /**
 686       * In the case a user is removed, make sure he is the author of the 'new_blog' activity
 687       * when trying to delete it.
 688       */
 689      if ( ! empty( $user_id ) ) {
 690          $args['user_id'] = $user_id;
 691      }
 692  
 693      bp_blogs_delete_activity( $args );
 694  }
 695  add_action( 'bp_blogs_remove_blog',          'bp_blogs_delete_new_blog_activity_for_site', 10, 1 );
 696  add_action( 'bp_blogs_remove_blog_for_user', 'bp_blogs_delete_new_blog_activity_for_site', 10, 2 );
 697  
 698  /**
 699   * Delete all 'blogs' activity items for a site when the site is deleted.
 700   *
 701   * @since 2.6.0
 702   *
 703   * @param int $blog_id Site ID.
 704   */
 705  function bp_blogs_delete_activity_for_site( $blog_id ) {
 706      bp_blogs_delete_activity( array(
 707          'item_id'   => $blog_id,
 708          'component' => buddypress()->blogs->id,
 709          'type'      => false
 710      ) );
 711  }
 712  add_action( 'bp_blogs_remove_data_for_blog', 'bp_blogs_delete_activity_for_site' );
 713  
 714  /**
 715   * Remove a blog post activity item from the activity stream.
 716   *
 717   * @since 1.0.0
 718   *
 719   * @param int $post_id ID of the post to be removed.
 720   * @param int $blog_id Optional. Defaults to current blog ID.
 721   * @param int $user_id Optional. Defaults to the logged-in user ID. This param
 722   *                     is currently unused in the function (but is passed to hooks).
 723   * @return bool
 724   */
 725  function bp_blogs_remove_post( $post_id, $blog_id = 0, $user_id = 0 ) {
 726      global $wpdb;
 727  
 728      if ( empty( $wpdb->blogid ) ) {
 729          return false;
 730      }
 731  
 732      $post_id = (int) $post_id;
 733  
 734      if ( ! $blog_id ) {
 735          $blog_id = (int) $wpdb->blogid;
 736      }
 737  
 738      if ( ! $user_id ) {
 739          $user_id = bp_loggedin_user_id();
 740      }
 741  
 742      /**
 743       * Fires before removal of a blog post activity item from the activity stream.
 744       *
 745       * @since 1.5.0
 746       *
 747       * @param int $blog_id ID of the blog associated with the post that was removed.
 748       * @param int $post_id ID of the post that was removed.
 749       * @param int $user_id ID of the user having the blog removed for.
 750       */
 751      do_action( 'bp_blogs_before_remove_post', $blog_id, $post_id, $user_id );
 752  
 753      bp_blogs_delete_activity( array(
 754          'item_id'           => $blog_id,
 755          'secondary_item_id' => $post_id,
 756          'component'         => buddypress()->blogs->id,
 757          'type'              => 'new_blog_post'
 758      ) );
 759  
 760      /**
 761       * Fires after removal of a blog post activity item from the activity stream.
 762       *
 763       * @since 1.0.0
 764       *
 765       * @param int $blog_id ID of the blog associated with the post that was removed.
 766       * @param int $post_id ID of the post that was removed.
 767       * @param int $user_id ID of the user having the blog removed for.
 768       */
 769      do_action( 'bp_blogs_remove_post', $blog_id, $post_id, $user_id );
 770  }
 771  add_action( 'delete_post', 'bp_blogs_remove_post' );
 772  
 773  /** POST COMMENT SYNCHRONIZATION ****************************************/
 774  
 775  /**
 776   * Syncs activity comments and posts them back as blog comments.
 777   *
 778   * Note: This is only a one-way sync - activity comments -> blog comment.
 779   *
 780   * For blog post -> activity comment, see {@link bp_activity_post_type_comment()}.
 781   *
 782   * @since 2.0.0
 783   * @since 2.5.0 Allow custom post types to sync their comments with activity ones
 784   *
 785   * @param int    $comment_id      The activity ID for the posted activity comment.
 786   * @param array  $params          Parameters for the activity comment.
 787   * @param object $parent_activity Parameters of the parent activity item (in this case, the blog post).
 788   */
 789  function bp_blogs_sync_add_from_activity_comment( $comment_id, $params, $parent_activity ) {
 790      // if parent activity isn't a post type having the buddypress-activity support, stop now!
 791      if ( ! bp_activity_type_supports( $parent_activity->type, 'post-type-comment-tracking' ) ) {
 792          return;
 793      }
 794  
 795      // If activity comments are disabled for blog posts, stop now!
 796      if ( bp_disable_blogforum_comments() ) {
 797          return;
 798      }
 799  
 800      // Do not sync if the activity comment was marked as spam.
 801      $activity = new BP_Activity_Activity( $comment_id );
 802      if ( $activity->is_spam ) {
 803          return;
 804      }
 805  
 806      // Check if comments are still open for parent item.
 807      $comments_open = bp_blogs_comments_open( $parent_activity );
 808      if ( ! $comments_open ) {
 809          return;
 810      }
 811  
 812      // Get userdata.
 813      if ( $params['user_id'] == bp_loggedin_user_id() ) {
 814          $user = buddypress()->loggedin_user->userdata;
 815      } else {
 816          $user = bp_core_get_core_userdata( $params['user_id'] );
 817      }
 818  
 819      // Get associated post type and set default comment parent.
 820      $post_type      = bp_activity_post_type_get_tracking_arg( $parent_activity->type, 'post_type' );
 821      $comment_parent = 0;
 822  
 823      // See if a parent WP comment ID exists.
 824      if ( ! empty( $params['parent_id'] ) && ! empty( $post_type ) ) {
 825          $comment_parent = bp_activity_get_meta( $params['parent_id'], "bp_blogs_{$post_type}_comment_id" );
 826      }
 827  
 828      // Comment args.
 829      $args = array(
 830          'comment_post_ID'      => $parent_activity->secondary_item_id,
 831          'comment_author'       => bp_core_get_user_displayname( $params['user_id'] ),
 832          'comment_author_email' => $user->user_email,
 833          'comment_author_url'   => bp_core_get_user_domain( $params['user_id'], $user->user_nicename, $user->user_login ),
 834          'comment_content'      => $params['content'],
 835          'comment_type'         => '', // Could be interesting to add 'BuddyPress' here...
 836          'comment_parent'       => (int) $comment_parent,
 837          'user_id'              => $params['user_id'],
 838          'comment_approved'     => 1
 839      );
 840  
 841      // Prevent separate activity entry being made.
 842      remove_action( 'comment_post', 'bp_activity_post_type_comment', 10 );
 843  
 844      // Handle multisite.
 845      switch_to_blog( $parent_activity->item_id );
 846  
 847      // Handle timestamps for the WP comment after we've switched to the blog.
 848      $args['comment_date']     = current_time( 'mysql' );
 849      $args['comment_date_gmt'] = current_time( 'mysql', 1 );
 850  
 851      // Post the comment.
 852      $post_comment_id = wp_insert_comment( $args );
 853  
 854      // Add meta to comment.
 855      add_comment_meta( $post_comment_id, 'bp_activity_comment_id', $comment_id );
 856  
 857      // Add meta to activity comment.
 858      if ( ! empty( $post_type ) ) {
 859          bp_activity_update_meta( $comment_id, "bp_blogs_{$post_type}_comment_id", $post_comment_id );
 860      }
 861  
 862      // Resave activity comment with WP comment permalink.
 863      //
 864      // in bp_blogs_activity_comment_permalink(), we change activity comment
 865      // permalinks to use the post comment link
 866      //
 867      // @todo since this is done after AJAX posting, the activity comment permalink
 868      // doesn't change on the front end until the next page refresh.
 869      $resave_activity = new BP_Activity_Activity( $comment_id );
 870      $resave_activity->primary_link = get_comment_link( $post_comment_id );
 871  
 872      /**
 873       * Now that the activity id exists and the post comment was created, we don't need to update
 874       * the content of the comment as there are no chances it has evolved.
 875       */
 876      remove_action( 'bp_activity_before_save', 'bp_blogs_sync_activity_edit_to_post_comment', 20 );
 877  
 878      $resave_activity->save();
 879  
 880      // Add the edit activity comment hook back.
 881      add_action( 'bp_activity_before_save', 'bp_blogs_sync_activity_edit_to_post_comment', 20 );
 882  
 883      // Multisite again!
 884      restore_current_blog();
 885  
 886      // Add the comment hook back.
 887      add_action( 'comment_post', 'bp_activity_post_type_comment', 10, 2 );
 888  
 889      /**
 890       * Fires after activity comments have been synced and posted as blog comments.
 891       *
 892       * @since 2.0.0
 893       *
 894       * @param int    $comment_id      The activity ID for the posted activity comment.
 895       * @param array  $args            Array of args used for the comment syncing.
 896       * @param object $parent_activity Parameters of the blog post parent activity item.
 897       * @param object $user            User data object for the blog comment.
 898       */
 899      do_action( 'bp_blogs_sync_add_from_activity_comment', $comment_id, $args, $parent_activity, $user );
 900  }
 901  add_action( 'bp_activity_comment_posted', 'bp_blogs_sync_add_from_activity_comment', 10, 3 );
 902  
 903  /**
 904   * Deletes the blog comment when the associated activity comment is deleted.
 905   *
 906   * Note: This is hooked on the 'bp_activity_delete_comment_pre' filter instead
 907   * of the 'bp_activity_delete_comment' action because we need to fetch the
 908   * activity comment children before they are deleted.
 909   *
 910   * @since 2.0.0
 911   * @since 2.5.0 Add the $delected parameter
 912   *
 913   * @param bool $retval             Whether BuddyPress should continue or not.
 914   * @param int  $parent_activity_id The parent activity ID for the activity comment.
 915   * @param int  $activity_id        The activity ID for the pending deleted activity comment.
 916   * @param bool $deleted            Whether the comment was deleted or not.
 917   * @return bool
 918   */
 919  function bp_blogs_sync_delete_from_activity_comment( $retval, $parent_activity_id, $activity_id, &$deleted ) {
 920      // Check if parent activity is a blog post.
 921      $parent_activity = new BP_Activity_Activity( $parent_activity_id );
 922  
 923      // if parent activity isn't a post type having the buddypress-activity support, stop now!
 924      if ( ! bp_activity_type_supports( $parent_activity->type, 'post-type-comment-tracking' ) ) {
 925          return $retval;
 926      }
 927  
 928      // Fetch the activity comments for the activity item.
 929      $activity = bp_activity_get( array(
 930          'in'               => $activity_id,
 931          'display_comments' => 'stream',
 932          'spam'             => 'all',
 933      ) );
 934  
 935      // Get all activity comment IDs for the pending deleted item.
 936      $activity_ids   = bp_activity_recurse_comments_activity_ids( $activity );
 937      $activity_ids[] = $activity_id;
 938  
 939      // Handle multisite.
 940      // switch to the blog where the comment was made.
 941      switch_to_blog( $parent_activity->item_id );
 942  
 943      // Remove associated blog comments.
 944      bp_blogs_remove_associated_blog_comments( $activity_ids, current_user_can( 'moderate_comments' ) );
 945  
 946      // Multisite again!
 947      restore_current_blog();
 948  
 949      // Rebuild activity comment tree
 950      // emulate bp_activity_delete_comment().
 951      BP_Activity_Activity::rebuild_activity_comment_tree( $parent_activity_id );
 952  
 953      // Avoid the error message although the comments were successfully deleted.
 954      $deleted = true;
 955  
 956      // We're overriding the default bp_activity_delete_comment() functionality
 957      // so we need to return false.
 958      return false;
 959  }
 960  add_filter( 'bp_activity_delete_comment_pre', 'bp_blogs_sync_delete_from_activity_comment', 10, 4 );
 961  
 962  /**
 963   * Updates the blog comment when the associated activity comment is edited.
 964   *
 965   * @since 2.0.0
 966   *
 967   * @param BP_Activity_Activity $activity The activity object.
 968   */
 969  function bp_blogs_sync_activity_edit_to_post_comment( BP_Activity_Activity $activity ) {
 970      // This is a new entry, so stop!
 971      // We only want edits!
 972      if ( empty( $activity->id ) || bp_disable_blogforum_comments() ) {
 973          return;
 974      }
 975  
 976      // Fetch parent activity item.
 977      $parent_activity = new BP_Activity_Activity( $activity->item_id );
 978  
 979      // If parent activity isn't a post type having the buddypress-activity support for comments, stop now!
 980      if ( ! bp_activity_type_supports( $parent_activity->type, 'post-type-comment-tracking' ) ) {
 981          return;
 982      }
 983  
 984      $post_type = bp_activity_post_type_get_tracking_arg( $parent_activity->type, 'post_type' );
 985  
 986      // No associated post type for this activity comment, stop.
 987      if ( ! $post_type ) {
 988          return;
 989      }
 990  
 991      // Try to see if a corresponding blog comment exists.
 992      $post_comment_id = bp_activity_get_meta( $activity->id, "bp_blogs_{$post_type}_comment_id" );
 993  
 994      if ( empty( $post_comment_id ) ) {
 995          return;
 996      }
 997  
 998      // Handle multisite.
 999      switch_to_blog( $parent_activity->item_id );
1000  
1001      // Get the comment status.
1002      $post_comment_status = wp_get_comment_status( $post_comment_id );
1003      $old_comment_status  = $post_comment_status;
1004  
1005      // No need to edit the activity, as it's the activity who's updating the comment.
1006      remove_action( 'transition_comment_status', 'bp_activity_transition_post_type_comment_status', 10 );
1007      remove_action( 'bp_activity_post_type_comment', 'bp_blogs_comment_sync_activity_comment', 10 );
1008  
1009      if ( 1 === $activity->is_spam && 'spam' !== $post_comment_status ) {
1010          wp_spam_comment( $post_comment_id );
1011      } elseif ( ! $activity->is_spam ) {
1012          if ( 'spam' === $post_comment_status  ) {
1013              wp_unspam_comment( $post_comment_id );
1014          } elseif ( 'trash' === $post_comment_status ) {
1015              wp_untrash_comment( $post_comment_id );
1016          } else {
1017              // Update the blog post comment.
1018              wp_update_comment( array(
1019                  'comment_ID'       => $post_comment_id,
1020                  'comment_content'  => $activity->content,
1021              ) );
1022          }
1023      }
1024  
1025      // Restore actions.
1026      add_action( 'transition_comment_status',     'bp_activity_transition_post_type_comment_status', 10, 3 );
1027      add_action( 'bp_activity_post_type_comment', 'bp_blogs_comment_sync_activity_comment',          10, 4 );
1028  
1029      restore_current_blog();
1030  }
1031  add_action( 'bp_activity_before_save', 'bp_blogs_sync_activity_edit_to_post_comment', 20 );
1032  
1033  /**
1034   * When a post is trashed, remove each comment's associated activity meta.
1035   *
1036   * When a post is trashed and later untrashed, we currently don't reinstate
1037   * activity items for these comments since their activity entries are already
1038   * deleted when initially trashed.
1039   *
1040   * Since these activity entries are deleted, we need to remove the deleted
1041   * activity comment IDs from each comment's meta when a post is trashed.
1042   *
1043   * @since 2.0.0
1044   *
1045   * @param int   $post_id  The post ID.
1046   * @param array $comments Array of comment statuses. The key is comment ID, the
1047   *                        value is the $comment->comment_approved value.
1048   */
1049  function bp_blogs_remove_activity_meta_for_trashed_comments( $post_id = 0, $comments = array() ) {
1050      if ( ! empty( $comments ) ) {
1051          foreach ( array_keys( $comments ) as $comment_id ) {
1052              delete_comment_meta( $comment_id, 'bp_activity_comment_id' );
1053          }
1054      }
1055  }
1056  add_action( 'trashed_post_comments', 'bp_blogs_remove_activity_meta_for_trashed_comments', 10, 2 );
1057  
1058  /**
1059   * Filter 'new_blog_comment' bp_has_activities() loop to include new- and old-style blog activity comment items.
1060   *
1061   * In BuddyPress 2.0, the schema for storing activity items related to blog
1062   * posts changed. Instead creating new top-level 'new_blog_comment' activity
1063   * items, blog comments are recorded in the activity stream as comments on the
1064   * 'new_blog_post' activity items corresponding to the parent post. This filter
1065   * ensures that the 'new_blog_comment' filter in bp_has_activities() (which
1066   * powers the 'Comments' filter in the activity directory dropdown) includes
1067   * both old-style and new-style activity comments.
1068   *
1069   * @since 2.1.0
1070   * @since 2.5.0 Used for any synced Post type comments, in wp-admin or front-end contexts.
1071   *
1072   * @param array $args Arguments passed from bp_parse_args() in bp_has_activities().
1073   * @return array $args
1074   */
1075  function bp_blogs_new_blog_comment_query_backpat( $args ) {
1076      global $wpdb;
1077      $bp = buddypress();
1078  
1079      // If activity comments are disabled for blog posts, stop now!
1080      if ( bp_disable_blogforum_comments() ) {
1081          return $args;
1082      }
1083  
1084      // Get the associated post type.
1085      $post_type = bp_activity_post_type_get_tracking_arg( $args['action'], 'post_type' );
1086  
1087      // Bail if this is not an activity associated with a post type.
1088      if ( empty( $post_type ) ) {
1089          return $args;
1090      }
1091  
1092      // Bail if this is an activity about posts and not comments.
1093      if ( bp_activity_post_type_get_tracking_arg( $args['action'], 'comment_action_id' ) ) {
1094          return $args;
1095      }
1096  
1097      // Comment synced ?
1098      $activity_ids = $wpdb->get_col( $wpdb->prepare( "SELECT activity_id FROM {$bp->activity->table_name_meta} WHERE meta_key = %s", "bp_blogs_{$post_type}_comment_id" ) );
1099  
1100      if ( empty( $activity_ids ) ) {
1101          return $args;
1102      }
1103  
1104      // Init the filter query.
1105      $filter_query = array();
1106  
1107      if ( ! isset( $args['scope'] ) || 'null' === $args['scope'] ) {
1108          $args['scope'] = '';
1109      } elseif ( 'just-me' === $args['scope'] ) {
1110          $filter_query = array(
1111              'relation' => 'AND',
1112              array(
1113                  'column' => 'user_id',
1114                  'value'  => bp_displayed_user_id(),
1115              ),
1116          );
1117          $args['scope'] = '';
1118      }
1119  
1120      $filter_query[] = array(
1121          'relation' => 'OR',
1122          array(
1123              'column' => 'type',
1124              'value'  => $args['action'],
1125          ),
1126          array(
1127              'column'  => 'id',
1128              'value'   =>  $activity_ids,
1129              'compare' => 'IN'
1130          ),
1131      );
1132  
1133      $args['filter_query'] = $filter_query;
1134  
1135      // Make sure to have comment in stream mode && avoid duplicate content.
1136      $args['display_comments'] = 'stream';
1137  
1138      // Finally reset the action.
1139      $args['action'] = '';
1140      $args['type']   = '';
1141  
1142      // Return the original arguments.
1143      return $args;
1144  }
1145  add_filter( 'bp_after_has_activities_parse_args',                'bp_blogs_new_blog_comment_query_backpat' );
1146  add_filter( 'bp_activity_list_table_filter_activity_type_items', 'bp_blogs_new_blog_comment_query_backpat' );
1147  
1148  /**
1149   * Utility function to set up some variables for use in the activity loop.
1150   *
1151   * Grabs the blog's comment depth and the post's open comment status options
1152   * for later use in the activity and activity comment loops.
1153   *
1154   * This is to prevent having to requery these items later on.
1155   *
1156   * @since 2.0.0
1157   *
1158   * @see bp_blogs_disable_activity_commenting()
1159   * @see bp_blogs_setup_comment_loop_globals_on_ajax()
1160   *
1161   * @param object $activity The BP_Activity_Activity object.
1162   */
1163  function bp_blogs_setup_activity_loop_globals( $activity ) {
1164      if ( ! is_object( $activity ) ) {
1165          return;
1166      }
1167  
1168      // The activity type does not support comments or replies ? stop now!
1169      if ( ! bp_activity_type_supports( $activity->type, 'post-type-comment-reply' ) ) {
1170          return;
1171      }
1172  
1173      if ( empty( $activity->id ) ) {
1174          return;
1175      }
1176  
1177      // If we've already done this before, stop now!
1178      if ( isset( buddypress()->blogs->allow_comments[ $activity->id ] ) ) {
1179          return;
1180      }
1181  
1182      $allow_comments = bp_blogs_comments_open( $activity );
1183      $thread_depth   = bp_blogs_get_blogmeta( $activity->item_id, 'thread_comments_depth' );
1184      $moderation     = bp_blogs_get_blogmeta( $activity->item_id, 'comment_moderation' );
1185  
1186      // Initialize a local object so we won't have to query this again in the
1187      // comment loop.
1188      if ( ! isset( buddypress()->blogs->allow_comments ) ) {
1189          buddypress()->blogs->allow_comments = array();
1190      }
1191      if ( ! isset( buddypress()->blogs->thread_depth ) ) {
1192          buddypress()->blogs->thread_depth   = array();
1193      }
1194      if ( ! isset( buddypress()->blogs->comment_moderation ) ) {
1195          buddypress()->blogs->comment_moderation = array();
1196      }
1197  
1198      /*
1199       * Cache comment settings in the buddypress() singleton for later reference.
1200       *
1201       * See bp_blogs_disable_activity_commenting() / bp_blogs_can_comment_reply().
1202       *
1203       * thread_depth is keyed by activity ID instead of blog ID because when we're
1204       * in an actvity comment loop, we don't have access to the blog ID...
1205       *
1206       * Should probably object cache these values instead...
1207       */
1208      buddypress()->blogs->allow_comments[ $activity->id ]     = $allow_comments;
1209      buddypress()->blogs->thread_depth[ $activity->id ]       = $thread_depth;
1210      buddypress()->blogs->comment_moderation[ $activity->id ] = $moderation;
1211  }
1212  
1213  /**
1214   * Set up some globals used in the activity comment loop when AJAX is used.
1215   *
1216   * @since 2.0.0
1217   *
1218   * @see bp_blogs_setup_activity_loop_globals()
1219   */
1220  function bp_blogs_setup_comment_loop_globals_on_ajax() {
1221      // Not AJAX? stop now!
1222      if ( ! defined( 'DOING_AJAX' ) ) {
1223          return;
1224      }
1225      if ( false === (bool) constant( 'DOING_AJAX' ) ) {
1226          return;
1227      }
1228  
1229      // Get the parent activity item.
1230      $comment         = bp_activity_current_comment();
1231      $parent_activity = new BP_Activity_Activity( $comment->item_id );
1232  
1233      // Setup the globals.
1234      bp_blogs_setup_activity_loop_globals( $parent_activity );
1235  }
1236  add_action( 'bp_before_activity_comment', 'bp_blogs_setup_comment_loop_globals_on_ajax' );
1237  
1238  /**
1239   * Disable activity commenting for blog posts based on certain criteria.
1240   *
1241   * If activity commenting is enabled for blog posts, we still need to disable
1242   * commenting if:
1243   *  - comments are disabled for the WP blog post from the admin dashboard
1244   *  - the WP blog post is supposed to be automatically closed from comments
1245   *    based on a certain age
1246   *  - the activity entry is a 'new_blog_comment' type
1247   *
1248   * @since 2.0.0
1249   *
1250   * @param bool $retval Is activity commenting enabled for this activity entry.
1251   * @return bool
1252   */
1253  function bp_blogs_disable_activity_commenting( $retval ) {
1254      global $activities_template;
1255  
1256      // If activity commenting is disabled, return current value.
1257      if ( bp_disable_blogforum_comments() || ! isset( $activities_template->in_the_loop ) ) {
1258          return $retval;
1259      }
1260  
1261      $type = bp_get_activity_type();
1262  
1263      // It's a post type supporting comment tracking.
1264      if ( bp_activity_type_supports( $type, 'post-type-comment-tracking' ) ) {
1265          // The activity type is supporting comments or replies.
1266          if ( bp_activity_type_supports( $type, 'post-type-comment-reply' ) ) {
1267              // Setup some globals we'll need to reference later.
1268              bp_blogs_setup_activity_loop_globals( $activities_template->activity );
1269  
1270              // If comments are closed for the WP blog post, we should disable
1271              // activity comments for this activity entry.
1272              if ( ! isset( buddypress()->blogs->allow_comments[ bp_get_activity_id() ] ) || ! buddypress()->blogs->allow_comments[ bp_get_activity_id() ] ) {
1273                  $retval = false;
1274              }
1275  
1276              // If comments need moderation, disable activity commenting.
1277              if ( isset( buddypress()->blogs->comment_moderation[ bp_get_activity_id() ] ) && buddypress()->blogs->comment_moderation[ bp_get_activity_id() ] ) {
1278                  $retval = false;
1279              }
1280          // The activity type does not support comments or replies.
1281          } else {
1282              $retval = false;
1283          }
1284      }
1285  
1286      return $retval;
1287  }
1288  add_filter( 'bp_activity_can_comment', 'bp_blogs_disable_activity_commenting' );
1289  
1290  /**
1291   * Limit the display of post type synced comments.
1292   *
1293   * @since  2.5.0
1294   *
1295   * When viewing the synced comments in stream mode, this prevents comments to
1296   * be displayed twice, and avoids a Javascript error as the form to add replies
1297   * is not available.
1298   *
1299   * @param  int $retval  The comment count for the activity.
1300   * @return int          The comment count, or 0 to hide activity comment replies.
1301   */
1302  function bp_blogs_post_type_comments_avoid_duplicates( $retval ) {
1303      /**
1304       * Only limit the display when Post type comments are synced with
1305       * activity comments.
1306       */
1307      if ( bp_disable_blogforum_comments() ) {
1308          return $retval;
1309      }
1310  
1311      if ( 'activity_comment' !== bp_get_activity_type() ) {
1312          return $retval;
1313      }
1314  
1315      // Check the parent activity.
1316      $parent_activity = new BP_Activity_Activity( bp_get_activity_item_id() );
1317  
1318      if ( isset( $parent_activity->type ) && bp_activity_post_type_get_tracking_arg( $parent_activity->type, 'post_type' ) ) {
1319          $retval = 0;
1320      }
1321  
1322      return $retval;
1323  }
1324  add_filter( 'bp_activity_get_comment_count', 'bp_blogs_post_type_comments_avoid_duplicates' );
1325  
1326  /**
1327   * Check if an activity comment associated with a blog post can be replied to.
1328   *
1329   * By default, disables replying to activity comments if the corresponding WP
1330   * blog post no longer accepts comments.
1331   *
1332   * This check uses a locally-cached value set in {@link bp_blogs_disable_activity_commenting()}
1333   * via {@link bp_blogs_setup_activity_loop_globals()}.
1334   *
1335   * @since 2.0.0
1336   *
1337   * @param bool         $retval  Are replies allowed for this activity reply.
1338   * @param object|array $comment The activity comment object.
1339   *
1340   * @return bool
1341   */
1342  function bp_blogs_can_comment_reply( $retval, $comment ) {
1343      if ( is_array( $comment ) ) {
1344          $comment = (object) $comment;
1345      }
1346  
1347      // Check comment depth and disable if depth is too large.
1348      if ( isset( buddypress()->blogs->thread_depth[$comment->item_id] ) ){
1349          if ( bp_activity_get_comment_depth( $comment ) >= buddypress()->blogs->thread_depth[$comment->item_id] ) {
1350              $retval = false;
1351          }
1352      }
1353  
1354      // Check if we should disable activity replies based on the parent activity.
1355      if ( isset( buddypress()->blogs->allow_comments[$comment->item_id] ) ){
1356          // The blog post has closed off commenting, so we should disable all activity
1357          // comments under the parent 'new_blog_post' activity entry.
1358          if ( ! buddypress()->blogs->allow_comments[ $comment->item_id ] ) {
1359              $retval = false;
1360          }
1361      }
1362  
1363      // If comments need moderation, disable activity commenting.
1364      if ( isset( buddypress()->blogs->comment_moderation[ $comment->item_id ] ) && buddypress()->blogs->comment_moderation[ $comment->item_id ] ) {
1365          $retval = false;
1366      }
1367  
1368      return $retval;
1369  }
1370  add_filter( 'bp_activity_can_comment_reply', 'bp_blogs_can_comment_reply', 10, 2 );
1371  
1372  /**
1373   * Changes activity comment permalinks to use the blog comment permalink
1374   * instead of the activity permalink.
1375   *
1376   * This is only done if activity commenting is allowed and whether the parent
1377   * activity item is a 'new_blog_post' entry.
1378   *
1379   * @since 2.0.0
1380   *
1381   * @param string $retval The activity comment permalink.
1382   * @return string
1383   */
1384  function bp_blogs_activity_comment_permalink( $retval = '' ) {
1385      global $activities_template;
1386  
1387      // Get the current comment ID.
1388      $item_id = isset( $activities_template->activity->current_comment->item_id )
1389          ? $activities_template->activity->current_comment->item_id
1390          : false;
1391  
1392      // Maybe adjust the link if item ID exists.
1393      if ( ( false !== $item_id ) && isset( buddypress()->blogs->allow_comments[ $item_id ] ) ) {
1394          $retval = $activities_template->activity->current_comment->primary_link;
1395      }
1396  
1397      return $retval;
1398  }
1399  add_filter( 'bp_get_activity_comment_permalink', 'bp_blogs_activity_comment_permalink' );
1400  
1401  /**
1402   * Changes single activity comment entries to use the blog comment permalink.
1403   *
1404   * This is only done if the activity comment is associated with a blog comment.
1405   *
1406   * @since 2.0.1
1407   *
1408   * @param string               $retval   The activity permalink.
1409   * @param BP_Activity_Activity $activity Activity object.
1410   * @return string
1411   */
1412  function bp_blogs_activity_comment_single_permalink( $retval, $activity ) {
1413      if ( 'activity_comment' !== $activity->type ) {
1414          return $retval;
1415      }
1416  
1417      if ( bp_disable_blogforum_comments() ) {
1418          return $retval;
1419      }
1420  
1421      $parent_activity = new BP_Activity_Activity( $activity->item_id );
1422  
1423      if ( isset( $parent_activity->type ) && bp_activity_post_type_get_tracking_arg( $parent_activity->type, 'post_type' ) ) {
1424          $retval = $activity->primary_link;
1425      }
1426  
1427      return $retval;
1428  }
1429  add_filter( 'bp_activity_get_permalink', 'bp_blogs_activity_comment_single_permalink', 10, 2 );
1430  
1431  /**
1432   * Formats single activity comment entries to use the blog comment action.
1433   *
1434   * This is only done if the activity comment is associated with a blog comment.
1435   *
1436   * @since 2.0.1
1437   *
1438   * @param string               $retval   The activity action.
1439   * @param BP_Activity_Activity $activity Activity object.
1440   * @return string
1441   */
1442  function bp_blogs_activity_comment_single_action( $retval, $activity ) {
1443      if ( 'activity_comment' !== $activity->type ) {
1444          return $retval;
1445      }
1446  
1447      if ( bp_disable_blogforum_comments() ) {
1448          return $retval;
1449      }
1450  
1451      $parent_activity = new BP_Activity_Activity( $activity->item_id );
1452  
1453      if ( ! isset( $parent_activity->type ) ) {
1454          return $retval;
1455      }
1456  
1457      $post_type = bp_activity_post_type_get_tracking_arg( $parent_activity->type, 'post_type' );
1458  
1459      if ( ! $post_type ) {
1460          return $retval;
1461      }
1462  
1463      $blog_comment_id = bp_activity_get_meta( $activity->id, "bp_blogs_{$post_type}_comment_id" );
1464  
1465      if ( ! empty( $blog_comment_id ) ) {
1466          $bp = buddypress();
1467  
1468          // Check if a comment action id is set for the parent activity.
1469          $comment_action_id = bp_activity_post_type_get_tracking_arg( $parent_activity->type, 'comment_action_id' );
1470  
1471          // Use the action string callback for the activity type.
1472          if ( ! empty( $comment_action_id ) ) {
1473              // Fake a 'new_{post_type}_comment' by cloning the activity object.
1474              $object = clone $activity;
1475  
1476              // Set the type of the activity to be a comment about a post type.
1477              $object->type = $comment_action_id;
1478  
1479              // Use the blog ID as the item_id.
1480              $object->item_id = $parent_activity->item_id;
1481  
1482              // Use comment ID as the secondary_item_id.
1483              $object->secondary_item_id = $blog_comment_id;
1484  
1485              // Get the format callback for this activity comment.
1486              $format_callback = bp_activity_post_type_get_tracking_arg( $comment_action_id, 'format_callback' );
1487  
1488              // Now format the activity action using the 'new_{post_type}_comment' action callback.
1489              if ( is_callable( $format_callback ) ) {
1490                  $retval = call_user_func_array( $format_callback, array( '', $object ) );
1491              }
1492          }
1493      }
1494  
1495      return $retval;
1496  }
1497  add_filter( 'bp_get_activity_action_pre_meta', 'bp_blogs_activity_comment_single_action', 10, 2 );


Generated: Tue May 26 01:01:29 2020 Cross-referenced by PHPXref 0.7.1