[ 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  
 469      $r = bp_parse_args(
 470          $args,
 471          array(
 472              'user_id'           => bp_loggedin_user_id(),
 473              'action'            => '',
 474              'content'           => '',
 475              'primary_link'      => '',
 476              'component'         => buddypress()->blogs->id,
 477              'type'              => false,
 478              'item_id'           => false,
 479              'secondary_item_id' => false,
 480              'recorded_time'     => bp_core_current_time(),
 481              'hide_sitewide'     => false,
 482          )
 483      );
 484  
 485      if ( ! empty( $r['action'] ) ) {
 486  
 487          /**
 488           * Filters the action associated with activity for activity stream.
 489           *
 490           * @since 1.2.0
 491           *
 492           * @param string $value Action for the activity stream.
 493           */
 494          $r['action'] = apply_filters( 'bp_blogs_record_activity_action', $r['action'] );
 495      }
 496  
 497      if ( ! empty( $r['content'] ) ) {
 498  
 499          /**
 500           * Filters the content associated with activity for activity stream.
 501           *
 502           * @since 1.2.0
 503           *
 504           * @param string $value Generated summary from content for the activity stream.
 505           * @param string $value Content for the activity stream.
 506           * @param array  $r     Array of arguments used for the activity stream item.
 507           */
 508          $r['content'] = apply_filters( 'bp_blogs_record_activity_content', bp_activity_create_summary( $r['content'], $r ), $r['content'], $r );
 509      }
 510  
 511      // Check for an existing entry and update if one exists.
 512      $id = bp_activity_get_activity_id( array(
 513          'user_id'           => $r['user_id'],
 514          'component'         => $r['component'],
 515          'type'              => $r['type'],
 516          'item_id'           => $r['item_id'],
 517          'secondary_item_id' => $r['secondary_item_id'],
 518      ) );
 519  
 520      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'] ) );
 521  }
 522  
 523  /**
 524   * Delete a blog-related activity stream item.
 525   *
 526   * @since 1.0.0
 527   *
 528   * @see bp_activity_delete() for description of parameters.
 529   *
 530   * @param array|string $args {
 531   *     See {@link bp_activity_delete()} for complete description of arguments.
 532   *     The arguments listed here have different default values from
 533   *     bp_activity_add().
 534   *     @type string $component Default: 'blogs'.
 535   * }
 536   * @return bool True on success, false on failure.
 537   */
 538  function bp_blogs_delete_activity( $args = '' ) {
 539      $r = bp_parse_args(
 540          $args,
 541          array(
 542              'item_id'           => false,
 543              'component'         => buddypress()->blogs->id,
 544              'type'              => false,
 545              'user_id'           => false,
 546              'secondary_item_id' => false,
 547          )
 548      );
 549  
 550      bp_activity_delete_by_item_id( $r );
 551  }
 552  
 553  /**
 554   * Check if a blog post's activity item should be closed from commenting.
 555   *
 556   * This mirrors the {@link comments_open()} and {@link _close_comments_for_old_post()}
 557   * functions, but for use with the BuddyPress activity stream to be as
 558   * lightweight as possible.
 559   *
 560   * By lightweight, we actually mirror a few of the blog's commenting settings
 561   * to blogmeta and checks the values in blogmeta instead.  This is to prevent
 562   * multiple {@link switch_to_blog()} calls in the activity stream.
 563   *
 564   * @since 2.0.0
 565   *
 566   * @param object $activity The BP_Activity_Activity object.
 567   * @return bool
 568   */
 569  function bp_blogs_comments_open( $activity ) {
 570      $open = true;
 571  
 572      $blog_id = $activity->item_id;
 573  
 574      // See if we've mirrored the close comments option before.
 575      $days_old = bp_blogs_get_blogmeta( $blog_id, 'close_comments_days_old' );
 576  
 577      // We've never cached these items before, so do it now.
 578      if ( '' === $days_old ) {
 579          switch_to_blog( $blog_id );
 580  
 581          // Use comments_open().
 582          remove_filter( 'comments_open', 'bp_comments_open', 10 );
 583          $open = comments_open( $activity->secondary_item_id );
 584          add_filter( 'comments_open', 'bp_comments_open', 10, 2 );
 585  
 586          // Might as well mirror values to blogmeta since we're here!
 587          $thread_depth = get_option( 'thread_comments' );
 588          if ( ! empty( $thread_depth ) ) {
 589              $thread_depth = get_option( 'thread_comments_depth' );
 590          } else {
 591              // Perhaps filter this?
 592              $thread_depth = 1;
 593          }
 594  
 595          bp_blogs_update_blogmeta( $blog_id, 'close_comments_for_old_posts', get_option( 'close_comments_for_old_posts' ) );
 596          bp_blogs_update_blogmeta( $blog_id, 'close_comments_days_old',      get_option( 'close_comments_days_old' ) );
 597          bp_blogs_update_blogmeta( $blog_id, 'thread_comments_depth',        $thread_depth );
 598  
 599          restore_current_blog();
 600  
 601      // Check blogmeta and manually check activity item.
 602      // Basically a copy of _close_comments_for_old_post().
 603      } else {
 604  
 605          // Comments are closed.
 606          if ( 'closed' == bp_activity_get_meta( $activity->id, 'post_comment_status' ) ) {
 607              return false;
 608          }
 609  
 610          if ( ! bp_blogs_get_blogmeta( $blog_id, 'close_comments_for_old_posts' ) ) {
 611              return $open;
 612          }
 613  
 614          $days_old = (int) $days_old;
 615          if ( ! $days_old ) {
 616              return $open;
 617          }
 618  
 619          /*
 620             Commenting out for now - needs some more thought...
 621             should we add the post type to activity meta?
 622  
 623          $post = get_post($post_id);
 624  
 625          // This filter is documented in wp-includes/comment.php
 626          $post_types = apply_filters( 'close_comments_for_post_types', array( 'post' ) );
 627          if ( ! in_array( $post->post_type, $post_types ) )
 628              return $open;
 629          */
 630  
 631          if ( time() - strtotime( $activity->date_recorded ) > ( $days_old * DAY_IN_SECONDS ) ) {
 632              return false;
 633          }
 634  
 635          return $open;
 636      }
 637  
 638      return $open;
 639  }
 640  
 641  /** SITE TRACKING *******************************************************/
 642  
 643  /**
 644   * Add an activity entry for a newly-created site.
 645   *
 646   * Hooked to the 'bp_blogs_new_blog' action.
 647   *
 648   * @since 2.6.0
 649   *
 650   * @param BP_Blogs_Blog $recorded_blog Current site being recorded. Passed by reference.
 651   * @param bool          $is_private    Whether the current site being recorded is private.
 652   * @param bool          $is_recorded   Whether the current site was recorded.
 653   */
 654  function bp_blogs_record_activity_on_site_creation( $recorded_blog, $is_private, $is_recorded, $no_activity ) {
 655      // Only record this activity if the blog is public.
 656      if ( ! $is_private && ! $no_activity && bp_blogs_is_blog_trackable( $recorded_blog->blog_id, $recorded_blog->user_id ) ) {
 657          bp_blogs_record_activity( array(
 658              'user_id'      => $recorded_blog->user_id,
 659  
 660              /**
 661               * Filters the activity created blog primary link.
 662               *
 663               * @since 1.1.0
 664               *
 665               * @param string $value Blog primary link.
 666               * @param int    $value Blog ID.
 667               */
 668              'primary_link' => apply_filters( 'bp_blogs_activity_created_blog_primary_link', bp_blogs_get_blogmeta( $recorded_blog->blog_id, 'url' ), $recorded_blog->blog_id ),
 669              'type'         => 'new_blog',
 670              'item_id'      => $recorded_blog->blog_id
 671          ) );
 672      }
 673  }
 674  add_action( 'bp_blogs_new_blog', 'bp_blogs_record_activity_on_site_creation', 10, 4 );
 675  
 676  /**
 677   * Deletes the 'new_blog' activity entry when a site is deleted.
 678   *
 679   * @since 2.6.0
 680   *
 681   * @param int $blog_id Site ID.
 682   */
 683  function bp_blogs_delete_new_blog_activity_for_site( $blog_id, $user_id = 0 ) {
 684      $args = array(
 685          'item_id'   => $blog_id,
 686          'component' => buddypress()->blogs->id,
 687          'type'      => 'new_blog'
 688      );
 689  
 690      /**
 691       * In the case a user is removed, make sure he is the author of the 'new_blog' activity
 692       * when trying to delete it.
 693       */
 694      if ( ! empty( $user_id ) ) {
 695          $args['user_id'] = $user_id;
 696      }
 697  
 698      bp_blogs_delete_activity( $args );
 699  }
 700  add_action( 'bp_blogs_remove_blog',          'bp_blogs_delete_new_blog_activity_for_site', 10, 1 );
 701  add_action( 'bp_blogs_remove_blog_for_user', 'bp_blogs_delete_new_blog_activity_for_site', 10, 2 );
 702  
 703  /**
 704   * Delete all 'blogs' activity items for a site when the site is deleted.
 705   *
 706   * @since 2.6.0
 707   *
 708   * @param int $blog_id Site ID.
 709   */
 710  function bp_blogs_delete_activity_for_site( $blog_id ) {
 711      bp_blogs_delete_activity( array(
 712          'item_id'   => $blog_id,
 713          'component' => buddypress()->blogs->id,
 714          'type'      => false
 715      ) );
 716  }
 717  add_action( 'bp_blogs_remove_data_for_blog', 'bp_blogs_delete_activity_for_site' );
 718  
 719  /**
 720   * Remove a blog post activity item from the activity stream.
 721   *
 722   * @since 1.0.0
 723   *
 724   * @param int $post_id ID of the post to be removed.
 725   * @param int $blog_id Optional. Defaults to current blog ID.
 726   * @param int $user_id Optional. Defaults to the logged-in user ID. This param
 727   *                     is currently unused in the function (but is passed to hooks).
 728   * @return bool
 729   */
 730  function bp_blogs_remove_post( $post_id, $blog_id = 0, $user_id = 0 ) {
 731      global $wpdb;
 732  
 733      if ( empty( $wpdb->blogid ) ) {
 734          return false;
 735      }
 736  
 737      $post_id = (int) $post_id;
 738  
 739      if ( ! $blog_id ) {
 740          $blog_id = (int) $wpdb->blogid;
 741      }
 742  
 743      if ( ! $user_id ) {
 744          $user_id = bp_loggedin_user_id();
 745      }
 746  
 747      /**
 748       * Fires before removal of a blog post activity item from the activity stream.
 749       *
 750       * @since 1.5.0
 751       *
 752       * @param int $blog_id ID of the blog associated with the post that was removed.
 753       * @param int $post_id ID of the post that was removed.
 754       * @param int $user_id ID of the user having the blog removed for.
 755       */
 756      do_action( 'bp_blogs_before_remove_post', $blog_id, $post_id, $user_id );
 757  
 758      bp_blogs_delete_activity( array(
 759          'item_id'           => $blog_id,
 760          'secondary_item_id' => $post_id,
 761          'component'         => buddypress()->blogs->id,
 762          'type'              => 'new_blog_post'
 763      ) );
 764  
 765      /**
 766       * Fires after removal of a blog post activity item from the activity stream.
 767       *
 768       * @since 1.0.0
 769       *
 770       * @param int $blog_id ID of the blog associated with the post that was removed.
 771       * @param int $post_id ID of the post that was removed.
 772       * @param int $user_id ID of the user having the blog removed for.
 773       */
 774      do_action( 'bp_blogs_remove_post', $blog_id, $post_id, $user_id );
 775  }
 776  add_action( 'delete_post', 'bp_blogs_remove_post' );
 777  
 778  /** POST COMMENT SYNCHRONIZATION ****************************************/
 779  
 780  /**
 781   * Syncs activity comments and posts them back as blog comments.
 782   *
 783   * Note: This is only a one-way sync - activity comments -> blog comment.
 784   *
 785   * For blog post -> activity comment, see {@link bp_activity_post_type_comment()}.
 786   *
 787   * @since 2.0.0
 788   * @since 2.5.0 Allow custom post types to sync their comments with activity ones
 789   *
 790   * @param int    $comment_id      The activity ID for the posted activity comment.
 791   * @param array  $params          Parameters for the activity comment.
 792   * @param object $parent_activity Parameters of the parent activity item (in this case, the blog post).
 793   */
 794  function bp_blogs_sync_add_from_activity_comment( $comment_id, $params, $parent_activity ) {
 795      // if parent activity isn't a post type having the buddypress-activity support, stop now!
 796      if ( ! bp_activity_type_supports( $parent_activity->type, 'post-type-comment-tracking' ) ) {
 797          return;
 798      }
 799  
 800      // If activity comments are disabled for blog posts, stop now!
 801      if ( bp_disable_blogforum_comments() ) {
 802          return;
 803      }
 804  
 805      // Do not sync if the activity comment was marked as spam.
 806      $activity = new BP_Activity_Activity( $comment_id );
 807      if ( $activity->is_spam ) {
 808          return;
 809      }
 810  
 811      // Check if comments are still open for parent item.
 812      $comments_open = bp_blogs_comments_open( $parent_activity );
 813      if ( ! $comments_open ) {
 814          return;
 815      }
 816  
 817      // Get userdata.
 818      if ( $params['user_id'] == bp_loggedin_user_id() ) {
 819          $user = buddypress()->loggedin_user->userdata;
 820      } else {
 821          $user = bp_core_get_core_userdata( $params['user_id'] );
 822      }
 823  
 824      // Get associated post type and set default comment parent.
 825      $post_type      = bp_activity_post_type_get_tracking_arg( $parent_activity->type, 'post_type' );
 826      $comment_parent = 0;
 827  
 828      // See if a parent WP comment ID exists.
 829      if ( ! empty( $params['parent_id'] ) && ! empty( $post_type ) ) {
 830          $comment_parent = bp_activity_get_meta( $params['parent_id'], "bp_blogs_{$post_type}_comment_id" );
 831      }
 832  
 833      // Comment args.
 834      $args = array(
 835          'comment_post_ID'      => $parent_activity->secondary_item_id,
 836          'comment_author'       => bp_core_get_user_displayname( $params['user_id'] ),
 837          'comment_author_email' => $user->user_email,
 838          'comment_author_url'   => bp_core_get_user_domain( $params['user_id'], $user->user_nicename, $user->user_login ),
 839          'comment_content'      => $params['content'],
 840          'comment_type'         => '', // Could be interesting to add 'BuddyPress' here...
 841          'comment_parent'       => (int) $comment_parent,
 842          'user_id'              => $params['user_id'],
 843          'comment_approved'     => 1
 844      );
 845  
 846      // Prevent separate activity entry being made.
 847      remove_action( 'comment_post', 'bp_activity_post_type_comment', 10 );
 848  
 849      // Handle multisite.
 850      switch_to_blog( $parent_activity->item_id );
 851  
 852      // Handle timestamps for the WP comment after we've switched to the blog.
 853      $args['comment_date']     = current_time( 'mysql' );
 854      $args['comment_date_gmt'] = current_time( 'mysql', 1 );
 855  
 856      // Post the comment.
 857      $post_comment_id = wp_insert_comment( $args );
 858  
 859      // Add meta to comment.
 860      add_comment_meta( $post_comment_id, 'bp_activity_comment_id', $comment_id );
 861  
 862      // Add meta to activity comment.
 863      if ( ! empty( $post_type ) ) {
 864          bp_activity_update_meta( $comment_id, "bp_blogs_{$post_type}_comment_id", $post_comment_id );
 865      }
 866  
 867      // Resave activity comment with WP comment permalink.
 868      //
 869      // in bp_blogs_activity_comment_permalink(), we change activity comment
 870      // permalinks to use the post comment link
 871      //
 872      // @todo since this is done after AJAX posting, the activity comment permalink
 873      // doesn't change on the front end until the next page refresh.
 874      $resave_activity = new BP_Activity_Activity( $comment_id );
 875      $resave_activity->primary_link = get_comment_link( $post_comment_id );
 876  
 877      /**
 878       * Now that the activity id exists and the post comment was created, we don't need to update
 879       * the content of the comment as there are no chances it has evolved.
 880       */
 881      remove_action( 'bp_activity_before_save', 'bp_blogs_sync_activity_edit_to_post_comment', 20 );
 882  
 883      $resave_activity->save();
 884  
 885      // Add the edit activity comment hook back.
 886      add_action( 'bp_activity_before_save', 'bp_blogs_sync_activity_edit_to_post_comment', 20 );
 887  
 888      // Multisite again!
 889      restore_current_blog();
 890  
 891      // Add the comment hook back.
 892      add_action( 'comment_post', 'bp_activity_post_type_comment', 10, 2 );
 893  
 894      /**
 895       * Fires after activity comments have been synced and posted as blog comments.
 896       *
 897       * @since 2.0.0
 898       *
 899       * @param int    $comment_id      The activity ID for the posted activity comment.
 900       * @param array  $args            Array of args used for the comment syncing.
 901       * @param object $parent_activity Parameters of the blog post parent activity item.
 902       * @param object $user            User data object for the blog comment.
 903       */
 904      do_action( 'bp_blogs_sync_add_from_activity_comment', $comment_id, $args, $parent_activity, $user );
 905  }
 906  add_action( 'bp_activity_comment_posted', 'bp_blogs_sync_add_from_activity_comment', 10, 3 );
 907  
 908  /**
 909   * Deletes the blog comment when the associated activity comment is deleted.
 910   *
 911   * Note: This is hooked on the 'bp_activity_delete_comment_pre' filter instead
 912   * of the 'bp_activity_delete_comment' action because we need to fetch the
 913   * activity comment children before they are deleted.
 914   *
 915   * @since 2.0.0
 916   * @since 2.5.0 Add the $delected parameter
 917   *
 918   * @param bool $retval             Whether BuddyPress should continue or not.
 919   * @param int  $parent_activity_id The parent activity ID for the activity comment.
 920   * @param int  $activity_id        The activity ID for the pending deleted activity comment.
 921   * @param bool $deleted            Whether the comment was deleted or not.
 922   * @return bool
 923   */
 924  function bp_blogs_sync_delete_from_activity_comment( $retval, $parent_activity_id, $activity_id, &$deleted ) {
 925      // Check if parent activity is a blog post.
 926      $parent_activity = new BP_Activity_Activity( $parent_activity_id );
 927  
 928      // if parent activity isn't a post type having the buddypress-activity support, stop now!
 929      if ( ! bp_activity_type_supports( $parent_activity->type, 'post-type-comment-tracking' ) ) {
 930          return $retval;
 931      }
 932  
 933      // Fetch the activity comments for the activity item.
 934      $activity = bp_activity_get( array(
 935          'in'               => $activity_id,
 936          'display_comments' => 'stream',
 937          'spam'             => 'all',
 938      ) );
 939  
 940      // Get all activity comment IDs for the pending deleted item.
 941      $activity_ids   = bp_activity_recurse_comments_activity_ids( $activity );
 942      $activity_ids[] = $activity_id;
 943  
 944      // Handle multisite.
 945      // switch to the blog where the comment was made.
 946      switch_to_blog( $parent_activity->item_id );
 947  
 948      // Remove associated blog comments.
 949      bp_blogs_remove_associated_blog_comments( $activity_ids, current_user_can( 'moderate_comments' ) );
 950  
 951      // Multisite again!
 952      restore_current_blog();
 953  
 954      // Rebuild activity comment tree
 955      // emulate bp_activity_delete_comment().
 956      BP_Activity_Activity::rebuild_activity_comment_tree( $parent_activity_id );
 957  
 958      // Avoid the error message although the comments were successfully deleted.
 959      $deleted = true;
 960  
 961      // We're overriding the default bp_activity_delete_comment() functionality
 962      // so we need to return false.
 963      return false;
 964  }
 965  add_filter( 'bp_activity_delete_comment_pre', 'bp_blogs_sync_delete_from_activity_comment', 10, 4 );
 966  
 967  /**
 968   * Updates the blog comment when the associated activity comment is edited.
 969   *
 970   * @since 2.0.0
 971   *
 972   * @param BP_Activity_Activity $activity The activity object.
 973   */
 974  function bp_blogs_sync_activity_edit_to_post_comment( BP_Activity_Activity $activity ) {
 975      // This is a new entry, so stop!
 976      // We only want edits!
 977      if ( empty( $activity->id ) || bp_disable_blogforum_comments() ) {
 978          return;
 979      }
 980  
 981      // Fetch parent activity item.
 982      $parent_activity = new BP_Activity_Activity( $activity->item_id );
 983  
 984      // If parent activity isn't a post type having the buddypress-activity support for comments, stop now!
 985      if ( ! bp_activity_type_supports( $parent_activity->type, 'post-type-comment-tracking' ) ) {
 986          return;
 987      }
 988  
 989      $post_type = bp_activity_post_type_get_tracking_arg( $parent_activity->type, 'post_type' );
 990  
 991      // No associated post type for this activity comment, stop.
 992      if ( ! $post_type ) {
 993          return;
 994      }
 995  
 996      // Try to see if a corresponding blog comment exists.
 997      $post_comment_id = bp_activity_get_meta( $activity->id, "bp_blogs_{$post_type}_comment_id" );
 998  
 999      if ( empty( $post_comment_id ) ) {
1000          return;
1001      }
1002  
1003      // Handle multisite.
1004      switch_to_blog( $parent_activity->item_id );
1005  
1006      // Get the comment status.
1007      $post_comment_status = wp_get_comment_status( $post_comment_id );
1008      $old_comment_status  = $post_comment_status;
1009  
1010      // No need to edit the activity, as it's the activity who's updating the comment.
1011      remove_action( 'transition_comment_status', 'bp_activity_transition_post_type_comment_status', 10 );
1012      remove_action( 'bp_activity_post_type_comment', 'bp_blogs_comment_sync_activity_comment', 10 );
1013  
1014      if ( 1 === $activity->is_spam && 'spam' !== $post_comment_status ) {
1015          wp_spam_comment( $post_comment_id );
1016      } elseif ( ! $activity->is_spam ) {
1017          if ( 'spam' === $post_comment_status  ) {
1018              wp_unspam_comment( $post_comment_id );
1019          } elseif ( 'trash' === $post_comment_status ) {
1020              wp_untrash_comment( $post_comment_id );
1021          } else {
1022              // Update the blog post comment.
1023              wp_update_comment( array(
1024                  'comment_ID'       => $post_comment_id,
1025                  'comment_content'  => $activity->content,
1026              ) );
1027          }
1028      }
1029  
1030      // Restore actions.
1031      add_action( 'transition_comment_status',     'bp_activity_transition_post_type_comment_status', 10, 3 );
1032      add_action( 'bp_activity_post_type_comment', 'bp_blogs_comment_sync_activity_comment',          10, 4 );
1033  
1034      restore_current_blog();
1035  }
1036  add_action( 'bp_activity_before_save', 'bp_blogs_sync_activity_edit_to_post_comment', 20 );
1037  
1038  /**
1039   * When a post is trashed, remove each comment's associated activity meta.
1040   *
1041   * When a post is trashed and later untrashed, we currently don't reinstate
1042   * activity items for these comments since their activity entries are already
1043   * deleted when initially trashed.
1044   *
1045   * Since these activity entries are deleted, we need to remove the deleted
1046   * activity comment IDs from each comment's meta when a post is trashed.
1047   *
1048   * @since 2.0.0
1049   *
1050   * @param int   $post_id  The post ID.
1051   * @param array $comments Array of comment statuses. The key is comment ID, the
1052   *                        value is the $comment->comment_approved value.
1053   */
1054  function bp_blogs_remove_activity_meta_for_trashed_comments( $post_id = 0, $comments = array() ) {
1055      if ( ! empty( $comments ) ) {
1056          foreach ( array_keys( $comments ) as $comment_id ) {
1057              delete_comment_meta( $comment_id, 'bp_activity_comment_id' );
1058          }
1059      }
1060  }
1061  add_action( 'trashed_post_comments', 'bp_blogs_remove_activity_meta_for_trashed_comments', 10, 2 );
1062  
1063  /**
1064   * Filter 'new_blog_comment' bp_has_activities() loop to include new- and old-style blog activity comment items.
1065   *
1066   * In BuddyPress 2.0, the schema for storing activity items related to blog
1067   * posts changed. Instead creating new top-level 'new_blog_comment' activity
1068   * items, blog comments are recorded in the activity stream as comments on the
1069   * 'new_blog_post' activity items corresponding to the parent post. This filter
1070   * ensures that the 'new_blog_comment' filter in bp_has_activities() (which
1071   * powers the 'Comments' filter in the activity directory dropdown) includes
1072   * both old-style and new-style activity comments.
1073   *
1074   * @since 2.1.0
1075   * @since 2.5.0 Used for any synced Post type comments, in wp-admin or front-end contexts.
1076   *
1077   * @param array $args Arguments passed from bp_parse_args() in bp_has_activities().
1078   * @return array $args
1079   */
1080  function bp_blogs_new_blog_comment_query_backpat( $args ) {
1081      global $wpdb;
1082      $bp = buddypress();
1083  
1084      // If activity comments are disabled for blog posts, stop now!
1085      if ( bp_disable_blogforum_comments() ) {
1086          return $args;
1087      }
1088  
1089      // Get the associated post type.
1090      $post_type = bp_activity_post_type_get_tracking_arg( $args['action'], 'post_type' );
1091  
1092      // Bail if this is not an activity associated with a post type.
1093      if ( empty( $post_type ) ) {
1094          return $args;
1095      }
1096  
1097      // Bail if this is an activity about posts and not comments.
1098      if ( bp_activity_post_type_get_tracking_arg( $args['action'], 'comment_action_id' ) ) {
1099          return $args;
1100      }
1101  
1102      // Comment synced ?
1103      $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" ) );
1104  
1105      if ( empty( $activity_ids ) ) {
1106          return $args;
1107      }
1108  
1109      // Init the filter query.
1110      $filter_query = array();
1111  
1112      if ( ! isset( $args['scope'] ) || 'null' === $args['scope'] ) {
1113          $args['scope'] = '';
1114      } elseif ( 'just-me' === $args['scope'] ) {
1115          $filter_query = array(
1116              'relation' => 'AND',
1117              array(
1118                  'column' => 'user_id',
1119                  'value'  => bp_displayed_user_id(),
1120              ),
1121          );
1122          $args['scope'] = '';
1123      }
1124  
1125      $filter_query[] = array(
1126          'relation' => 'OR',
1127          array(
1128              'column' => 'type',
1129              'value'  => $args['action'],
1130          ),
1131          array(
1132              'column'  => 'id',
1133              'value'   =>  $activity_ids,
1134              'compare' => 'IN'
1135          ),
1136      );
1137  
1138      $args['filter_query'] = $filter_query;
1139  
1140      // Make sure to have comment in stream mode && avoid duplicate content.
1141      $args['display_comments'] = 'stream';
1142  
1143      // Finally reset the action.
1144      $args['action'] = '';
1145      $args['type']   = '';
1146  
1147      // Return the original arguments.
1148      return $args;
1149  }
1150  add_filter( 'bp_after_has_activities_parse_args',                'bp_blogs_new_blog_comment_query_backpat' );
1151  add_filter( 'bp_activity_list_table_filter_activity_type_items', 'bp_blogs_new_blog_comment_query_backpat' );
1152  
1153  /**
1154   * Utility function to set up some variables for use in the activity loop.
1155   *
1156   * Grabs the blog's comment depth and the post's open comment status options
1157   * for later use in the activity and activity comment loops.
1158   *
1159   * This is to prevent having to requery these items later on.
1160   *
1161   * @since 2.0.0
1162   *
1163   * @see bp_blogs_disable_activity_commenting()
1164   * @see bp_blogs_setup_comment_loop_globals_on_ajax()
1165   *
1166   * @param object $activity The BP_Activity_Activity object.
1167   */
1168  function bp_blogs_setup_activity_loop_globals( $activity ) {
1169      if ( ! is_object( $activity ) ) {
1170          return;
1171      }
1172  
1173      // The activity type does not support comments or replies ? stop now!
1174      if ( ! bp_activity_type_supports( $activity->type, 'post-type-comment-reply' ) ) {
1175          return;
1176      }
1177  
1178      if ( empty( $activity->id ) ) {
1179          return;
1180      }
1181  
1182      // If we've already done this before, stop now!
1183      if ( isset( buddypress()->blogs->allow_comments[ $activity->id ] ) ) {
1184          return;
1185      }
1186  
1187      $allow_comments = bp_blogs_comments_open( $activity );
1188      $thread_depth   = bp_blogs_get_blogmeta( $activity->item_id, 'thread_comments_depth' );
1189      $moderation     = bp_blogs_get_blogmeta( $activity->item_id, 'comment_moderation' );
1190  
1191      // Initialize a local object so we won't have to query this again in the
1192      // comment loop.
1193      if ( ! isset( buddypress()->blogs->allow_comments ) ) {
1194          buddypress()->blogs->allow_comments = array();
1195      }
1196      if ( ! isset( buddypress()->blogs->thread_depth ) ) {
1197          buddypress()->blogs->thread_depth   = array();
1198      }
1199      if ( ! isset( buddypress()->blogs->comment_moderation ) ) {
1200          buddypress()->blogs->comment_moderation = array();
1201      }
1202  
1203      /*
1204       * Cache comment settings in the buddypress() singleton for later reference.
1205       *
1206       * See bp_blogs_disable_activity_commenting() / bp_blogs_can_comment_reply().
1207       *
1208       * thread_depth is keyed by activity ID instead of blog ID because when we're
1209       * in an actvity comment loop, we don't have access to the blog ID...
1210       *
1211       * Should probably object cache these values instead...
1212       */
1213      buddypress()->blogs->allow_comments[ $activity->id ]     = $allow_comments;
1214      buddypress()->blogs->thread_depth[ $activity->id ]       = $thread_depth;
1215      buddypress()->blogs->comment_moderation[ $activity->id ] = $moderation;
1216  }
1217  
1218  /**
1219   * Set up some globals used in the activity comment loop when AJAX is used.
1220   *
1221   * @since 2.0.0
1222   *
1223   * @see bp_blogs_setup_activity_loop_globals()
1224   */
1225  function bp_blogs_setup_comment_loop_globals_on_ajax() {
1226      // Not AJAX? stop now!
1227      if ( ! defined( 'DOING_AJAX' ) ) {
1228          return;
1229      }
1230      if ( false === (bool) constant( 'DOING_AJAX' ) ) {
1231          return;
1232      }
1233  
1234      // Get the parent activity item.
1235      $comment         = bp_activity_current_comment();
1236      $parent_activity = new BP_Activity_Activity( $comment->item_id );
1237  
1238      // Setup the globals.
1239      bp_blogs_setup_activity_loop_globals( $parent_activity );
1240  }
1241  add_action( 'bp_before_activity_comment', 'bp_blogs_setup_comment_loop_globals_on_ajax' );
1242  
1243  /**
1244   * Disable activity commenting for blog posts based on certain criteria.
1245   *
1246   * If activity commenting is enabled for blog posts, we still need to disable
1247   * commenting if:
1248   *  - comments are disabled for the WP blog post from the admin dashboard
1249   *  - the WP blog post is supposed to be automatically closed from comments
1250   *    based on a certain age
1251   *  - the activity entry is a 'new_blog_comment' type
1252   *
1253   * @since 2.0.0
1254   *
1255   * @param bool $retval Is activity commenting enabled for this activity entry.
1256   * @return bool
1257   */
1258  function bp_blogs_disable_activity_commenting( $retval ) {
1259      global $activities_template;
1260  
1261      // If activity commenting is disabled, return current value.
1262      if ( bp_disable_blogforum_comments() || ! isset( $activities_template->in_the_loop ) ) {
1263          return $retval;
1264      }
1265  
1266      $type = bp_get_activity_type();
1267  
1268      // It's a post type supporting comment tracking.
1269      if ( bp_activity_type_supports( $type, 'post-type-comment-tracking' ) ) {
1270          // The activity type is supporting comments or replies.
1271          if ( bp_activity_type_supports( $type, 'post-type-comment-reply' ) ) {
1272              // Setup some globals we'll need to reference later.
1273              bp_blogs_setup_activity_loop_globals( $activities_template->activity );
1274  
1275              // If comments are closed for the WP blog post, we should disable
1276              // activity comments for this activity entry.
1277              if ( ! isset( buddypress()->blogs->allow_comments[ bp_get_activity_id() ] ) || ! buddypress()->blogs->allow_comments[ bp_get_activity_id() ] ) {
1278                  $retval = false;
1279              }
1280  
1281              // If comments need moderation, disable activity commenting.
1282              if ( isset( buddypress()->blogs->comment_moderation[ bp_get_activity_id() ] ) && buddypress()->blogs->comment_moderation[ bp_get_activity_id() ] ) {
1283                  $retval = false;
1284              }
1285          // The activity type does not support comments or replies.
1286          } else {
1287              $retval = false;
1288          }
1289      }
1290  
1291      return $retval;
1292  }
1293  add_filter( 'bp_activity_can_comment', 'bp_blogs_disable_activity_commenting' );
1294  
1295  /**
1296   * Limit the display of post type synced comments.
1297   *
1298   * @since  2.5.0
1299   *
1300   * When viewing the synced comments in stream mode, this prevents comments to
1301   * be displayed twice, and avoids a Javascript error as the form to add replies
1302   * is not available.
1303   *
1304   * @param  int $retval  The comment count for the activity.
1305   * @return int          The comment count, or 0 to hide activity comment replies.
1306   */
1307  function bp_blogs_post_type_comments_avoid_duplicates( $retval ) {
1308      /**
1309       * Only limit the display when Post type comments are synced with
1310       * activity comments.
1311       */
1312      if ( bp_disable_blogforum_comments() ) {
1313          return $retval;
1314      }
1315  
1316      if ( 'activity_comment' !== bp_get_activity_type() ) {
1317          return $retval;
1318      }
1319  
1320      // Check the parent activity.
1321      $parent_activity = new BP_Activity_Activity( bp_get_activity_item_id() );
1322  
1323      if ( isset( $parent_activity->type ) && bp_activity_post_type_get_tracking_arg( $parent_activity->type, 'post_type' ) ) {
1324          $retval = 0;
1325      }
1326  
1327      return $retval;
1328  }
1329  add_filter( 'bp_activity_get_comment_count', 'bp_blogs_post_type_comments_avoid_duplicates' );
1330  
1331  /**
1332   * Check if an activity comment associated with a blog post can be replied to.
1333   *
1334   * By default, disables replying to activity comments if the corresponding WP
1335   * blog post no longer accepts comments.
1336   *
1337   * This check uses a locally-cached value set in {@link bp_blogs_disable_activity_commenting()}
1338   * via {@link bp_blogs_setup_activity_loop_globals()}.
1339   *
1340   * @since 2.0.0
1341   *
1342   * @param bool         $retval  Are replies allowed for this activity reply.
1343   * @param object|array $comment The activity comment object.
1344   *
1345   * @return bool
1346   */
1347  function bp_blogs_can_comment_reply( $retval, $comment ) {
1348      if ( is_array( $comment ) ) {
1349          $comment = (object) $comment;
1350      }
1351  
1352      // Check comment depth and disable if depth is too large.
1353      if ( isset( buddypress()->blogs->thread_depth[$comment->item_id] ) ){
1354          if ( bp_activity_get_comment_depth( $comment ) >= buddypress()->blogs->thread_depth[$comment->item_id] ) {
1355              $retval = false;
1356          }
1357      }
1358  
1359      // Check if we should disable activity replies based on the parent activity.
1360      if ( isset( buddypress()->blogs->allow_comments[$comment->item_id] ) ){
1361          // The blog post has closed off commenting, so we should disable all activity
1362          // comments under the parent 'new_blog_post' activity entry.
1363          if ( ! buddypress()->blogs->allow_comments[ $comment->item_id ] ) {
1364              $retval = false;
1365          }
1366      }
1367  
1368      // If comments need moderation, disable activity commenting.
1369      if ( isset( buddypress()->blogs->comment_moderation[ $comment->item_id ] ) && buddypress()->blogs->comment_moderation[ $comment->item_id ] ) {
1370          $retval = false;
1371      }
1372  
1373      return $retval;
1374  }
1375  add_filter( 'bp_activity_can_comment_reply', 'bp_blogs_can_comment_reply', 10, 2 );
1376  
1377  /**
1378   * Changes activity comment permalinks to use the blog comment permalink
1379   * instead of the activity permalink.
1380   *
1381   * This is only done if activity commenting is allowed and whether the parent
1382   * activity item is a 'new_blog_post' entry.
1383   *
1384   * @since 2.0.0
1385   *
1386   * @param string $retval The activity comment permalink.
1387   * @return string
1388   */
1389  function bp_blogs_activity_comment_permalink( $retval = '' ) {
1390      global $activities_template;
1391  
1392      // Get the current comment ID.
1393      $item_id = isset( $activities_template->activity->current_comment->item_id )
1394          ? $activities_template->activity->current_comment->item_id
1395          : false;
1396  
1397      // Maybe adjust the link if item ID exists.
1398      if ( ( false !== $item_id ) && isset( buddypress()->blogs->allow_comments[ $item_id ] ) ) {
1399          $retval = $activities_template->activity->current_comment->primary_link;
1400      }
1401  
1402      return $retval;
1403  }
1404  add_filter( 'bp_get_activity_comment_permalink', 'bp_blogs_activity_comment_permalink' );
1405  
1406  /**
1407   * Changes single activity comment entries to use the blog comment permalink.
1408   *
1409   * This is only done if the activity comment is associated with a blog comment.
1410   *
1411   * @since 2.0.1
1412   *
1413   * @param string               $retval   The activity permalink.
1414   * @param BP_Activity_Activity $activity Activity object.
1415   * @return string
1416   */
1417  function bp_blogs_activity_comment_single_permalink( $retval, $activity ) {
1418      if ( 'activity_comment' !== $activity->type ) {
1419          return $retval;
1420      }
1421  
1422      if ( bp_disable_blogforum_comments() ) {
1423          return $retval;
1424      }
1425  
1426      $parent_activity = new BP_Activity_Activity( $activity->item_id );
1427  
1428      if ( isset( $parent_activity->type ) && bp_activity_post_type_get_tracking_arg( $parent_activity->type, 'post_type' ) ) {
1429          $retval = $activity->primary_link;
1430      }
1431  
1432      return $retval;
1433  }
1434  add_filter( 'bp_activity_get_permalink', 'bp_blogs_activity_comment_single_permalink', 10, 2 );
1435  
1436  /**
1437   * Formats single activity comment entries to use the blog comment action.
1438   *
1439   * This is only done if the activity comment is associated with a blog comment.
1440   *
1441   * @since 2.0.1
1442   *
1443   * @param string               $retval   The activity action.
1444   * @param BP_Activity_Activity $activity Activity object.
1445   * @return string
1446   */
1447  function bp_blogs_activity_comment_single_action( $retval, $activity ) {
1448      if ( 'activity_comment' !== $activity->type ) {
1449          return $retval;
1450      }
1451  
1452      if ( bp_disable_blogforum_comments() ) {
1453          return $retval;
1454      }
1455  
1456      $parent_activity = new BP_Activity_Activity( $activity->item_id );
1457  
1458      if ( ! isset( $parent_activity->type ) ) {
1459          return $retval;
1460      }
1461  
1462      $post_type = bp_activity_post_type_get_tracking_arg( $parent_activity->type, 'post_type' );
1463  
1464      if ( ! $post_type ) {
1465          return $retval;
1466      }
1467  
1468      $blog_comment_id = bp_activity_get_meta( $activity->id, "bp_blogs_{$post_type}_comment_id" );
1469  
1470      if ( ! empty( $blog_comment_id ) ) {
1471          $bp = buddypress();
1472  
1473          // Check if a comment action id is set for the parent activity.
1474          $comment_action_id = bp_activity_post_type_get_tracking_arg( $parent_activity->type, 'comment_action_id' );
1475  
1476          // Use the action string callback for the activity type.
1477          if ( ! empty( $comment_action_id ) ) {
1478              // Fake a 'new_{post_type}_comment' by cloning the activity object.
1479              $object = clone $activity;
1480  
1481              // Set the type of the activity to be a comment about a post type.
1482              $object->type = $comment_action_id;
1483  
1484              // Use the blog ID as the item_id.
1485              $object->item_id = $parent_activity->item_id;
1486  
1487              // Use comment ID as the secondary_item_id.
1488              $object->secondary_item_id = $blog_comment_id;
1489  
1490              // Get the format callback for this activity comment.
1491              $format_callback = bp_activity_post_type_get_tracking_arg( $comment_action_id, 'format_callback' );
1492  
1493              // Now format the activity action using the 'new_{post_type}_comment' action callback.
1494              if ( is_callable( $format_callback ) ) {
1495                  $retval = call_user_func_array( $format_callback, array( '', $object ) );
1496              }
1497          }
1498      }
1499  
1500      return $retval;
1501  }
1502  add_filter( 'bp_get_activity_action_pre_meta', 'bp_blogs_activity_comment_single_action', 10, 2 );


Generated: Fri Dec 6 01:00:58 2024 Cross-referenced by PHPXref 0.7.1