<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[BuddyPress][10543] trunk/src/bp-activity: Post Type Activities: introduce new functions to track the post type comments</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta" style="font-size: 105%">
<dt style="float: left; width: 6em; font-weight: bold">Revision</dt> <dd><a style="font-weight: bold" href="http://buddypress.trac.wordpress.org/changeset/10543">10543</a><script type="application/ld+json">{"@context":"http://schema.org","@type":"EmailMessage","description":"Review this Commit","action":{"@type":"ViewAction","url":"http://buddypress.trac.wordpress.org/changeset/10543","name":"Review Commit"}}</script></dd>
<dt style="float: left; width: 6em; font-weight: bold">Author</dt> <dd>imath</dd>
<dt style="float: left; width: 6em; font-weight: bold">Date</dt> <dd>2016-02-07 16:36:40 +0000 (Sun, 07 Feb 2016)</dd>
</dl>

<pre style='padding-left: 1em; margin: 2em 0; border-left: 2px solid #ccc; line-height: 1.25; font-size: 105%; font-family: sans-serif'>Post Type Activities: introduce new functions to track the post type comments

These functions are generalizing to any post type what was only performed for the "post" post type so far.

We are also editing the `bp_activity_new_comment()` so that it is possible to post an activity comment without sending notifications.

Props shanebp, r-a-y.

See <a href="http://buddypress.trac.wordpress.org/ticket/6482">#6482</a></pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunksrcbpactivitybpactivityactionsphp">trunk/src/bp-activity/bp-activity-actions.php</a></li>
<li><a href="#trunksrcbpactivitybpactivityfunctionsphp">trunk/src/bp-activity/bp-activity-functions.php</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunksrcbpactivitybpactivityactionsphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/bp-activity/bp-activity-actions.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/bp-activity/bp-activity-actions.php     2016-02-07 16:29:52 UTC (rev 10542)
+++ trunk/src/bp-activity/bp-activity-actions.php       2016-02-07 16:36:40 UTC (rev 10543)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -831,3 +831,123 @@
</span><span class="cx" style="display: block; padding: 0 10px">        }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> add_action( 'transition_post_status', 'bp_activity_catch_transition_post_type_status', 10, 3 );
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+
+/**
+ * When a post type comment status transition occurs, update the relevant activity's status.
+ *
+ * @since 2.5.0
+ *
+ * @param string     $new_status New comment status.
+ * @param string     $old_status Previous comment status.
+ * @param WP_Comment $comment Comment data.
+ */
+function bp_activity_transition_post_type_comment_status( $new_status, $old_status, $comment ) {
+       $post_type = get_post_type( $comment->comment_post_ID );
+       if ( ! $post_type ) {
+               return;
+       }
+
+       // Get the post type tracking args.
+       $activity_post_object = bp_activity_get_post_type_tracking_args( $post_type );
+
+       // Bail if the activity type does not exist
+       if ( empty( $activity_post_object->comments_tracking->action_id ) ) {
+               return false;
+
+       // Set the $activity_comment_object
+       } else {
+               $activity_comment_object = $activity_post_object->comments_tracking;
+       }
+
+       // Init an empty activity ID
+       $activity_id = 0;
+
+       /**
+        * Activity currently doesn't have any concept of a trash, or an unapproved/approved state.
+        *
+        * If a blog comment transitions to a "delete" or "hold" status, delete the activity item.
+        * If a blog comment transitions to trashed, or spammed, mark the activity as spam.
+        * If a blog comment transitions to approved (and the activity exists), mark the activity as ham.
+        * If a blog comment transitions to unapproved (and the activity exists), mark the activity as spam.
+        * Otherwise, record the comment into the activity stream.
+        */
+
+       // This clause handles delete/hold.
+       if ( in_array( $new_status, array( 'delete', 'hold' ) ) ) {
+               return bp_activity_post_type_remove_comment( $comment->comment_ID, $activity_post_object );
+
+       // These clauses handle trash, spam, and un-spams.
+       } elseif ( in_array( $new_status, array( 'trash', 'spam', 'unapproved' ) ) ) {
+               $action = 'spam_activity';
+       } elseif ( 'approved' == $new_status ) {
+               $action = 'ham_activity';
+       }
+
+       // Get the activity
+       if ( bp_disable_blogforum_comments() ) {
+               $activity_id = bp_activity_get_activity_id( array(
+                       'component'         => $activity_comment_object->component_id,
+                       'item_id'           => get_current_blog_id(),
+                       'secondary_item_id' => $comment->comment_ID,
+                       'type'              => $activity_comment_object->action_id,
+               ) );
+       } else {
+               $activity_id = get_comment_meta( $comment->comment_ID, 'bp_activity_comment_id', true );
+       }
+
+       /**
+        * Leave a chance to plugins to manage activity comments differently.
+        *
+        * @since  2.5.0
+        *
+        * @param bool        $value       True to override BuddyPress management.
+        * @param string      $post_type   The post type name.
+        * @param int         $activity_id The post type activity (0 if not found).
+        * @param string      $new_status  The new status of the post type comment.
+        * @param string      $old_status  The old status of the post type comment.
+        * @param WP_Comment  $comment Comment data.
+        */
+       if ( true === apply_filters( 'bp_activity_pre_transition_post_type_comment_status', false, $post_type, $activity_id, $new_status, $old_status, $comment ) ) {
+               return false;
+       }
+
+       // Check activity item exists
+       if ( empty( $activity_id ) ) {
+               // If no activity exists, but the comment has been approved, record it into the activity table.
+               if ( 'approved' == $new_status ) {
+                       return bp_activity_post_type_comment( $comment->comment_ID, true, $activity_post_object );
+               }
+
+               return;
+       }
+
+       // Create an activity object
+       $activity = new BP_Activity_Activity( $activity_id );
+       if ( empty( $activity->component ) ) {
+               return;
+       }
+
+       // Spam/ham the activity if it's not already in that state
+       if ( 'spam_activity' === $action && ! $activity->is_spam ) {
+               bp_activity_mark_as_spam( $activity );
+       } elseif ( 'ham_activity' == $action) {
+               bp_activity_mark_as_ham( $activity );
+       }
+
+       // Add "new_post_type_comment" to the whitelisted activity types, so that the activity's Akismet history is generated
+       $post_type_comment_action = $activity_comment_object->action_id;
+       $comment_akismet_history = create_function( '$t', '$t[] = $post_type_comment_action; return $t;' );
+       add_filter( 'bp_akismet_get_activity_types', $comment_akismet_history );
+
+       // Make sure the activity change won't edit the comment if sync is on
+       remove_action( 'bp_activity_before_save', 'bp_blogs_sync_activity_edit_to_post_comment', 20 );
+
+       // Save the updated activity
+       $activity->save();
+
+       // Restore the action
+       add_action( 'bp_activity_before_save', 'bp_blogs_sync_activity_edit_to_post_comment', 20 );
+
+       // Remove the "new_blog_comment" activity type whitelist so we don't break anything
+       remove_filter( 'bp_akismet_get_activity_types', $comment_akismet_history );
+}
</ins></span></pre></div>
<a id="trunksrcbpactivitybpactivityfunctionsphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/bp-activity/bp-activity-functions.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/bp-activity/bp-activity-functions.php   2016-02-07 16:29:52 UTC (rev 10542)
+++ trunk/src/bp-activity/bp-activity-functions.php     2016-02-07 16:36:40 UTC (rev 10543)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2231,11 +2231,13 @@
</span><span class="cx" style="display: block; padding: 0 10px">         * Fires after the updating of an activity item for a custom post type entry.
</span><span class="cx" style="display: block; padding: 0 10px">         *
</span><span class="cx" style="display: block; padding: 0 10px">         * @since 2.2.0
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         * @since 2.5.0 Add the post type tracking args parameter
</ins><span class="cx" style="display: block; padding: 0 10px">          *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-         * @param WP_Post              $post     Post object.
-        * @param BP_Activity_Activity $activity Activity object.
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+  * @param WP_Post              $post                 Post object.
+        * @param BP_Activity_Activity $activity             Activity object.
+        * @param object               $activity_post_object The post type tracking args object.
</ins><span class="cx" style="display: block; padding: 0 10px">          */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        do_action( 'bp_activity_post_type_updated', $post, $activity );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ do_action( 'bp_activity_post_type_updated', $post, $activity, $activity_post_object );
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        return $updated;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2291,9 +2293,267 @@
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * Create an activity item for a newly posted post type comment.
+ *
+ * @since 2.5.0
+ *
+ * @param  int  $comment_id  ID of the comment.
+ * @param  bool $is_approved Whether the comment is approved or not.
+ * @param  object $activity_post_object the post type tracking args object.
+ *
+ * @return int|bool The ID of the activity on success. False on error.
+ */
+function bp_activity_post_type_comment( $comment_id = 0, $is_approved = true, $activity_post_object = null ) {
+       // Get the users comment
+       $post_type_comment = get_comment( $comment_id );
+
+       // Don't record activity if the comment hasn't been approved
+       if ( empty( $is_approved ) ) {
+               return false;
+       }
+
+       // Don't record activity if no email address has been included
+       if ( empty( $post_type_comment->comment_author_email ) ) {
+               return false;
+       }
+
+       // Don't record activity if the comment has already been marked as spam
+       if ( 'spam' === $is_approved ) {
+               return false;
+       }
+
+       // Get the user by the comment author email.
+       $user = get_user_by( 'email', $post_type_comment->comment_author_email );
+
+       // If user isn't registered, don't record activity
+       if ( empty( $user ) ) {
+               return false;
+       }
+
+       // Get the user_id
+       $user_id = (int) $user->ID;
+
+       // Get blog and post data
+       $blog_id = get_current_blog_id();
+
+       // Get the post
+       $post_type_comment->post = get_post( $post_type_comment->comment_post_ID );
+
+       if ( ! is_a( $post_type_comment->post, 'WP_Post' ) ) {
+               return false;
+       }
+
+       /**
+        * Filters whether to publish activities about the comment regarding the post status
+        *
+        * @since 2.5.0
+        *
+        * @param bool true to bail, false otherwise.
+        */
+       $is_post_status_not_allowed = (bool) apply_filters( 'bp_activity_post_type_is_post_status_allowed', 'publish' !== $post_type_comment->post->post_status || ! empty( $post_type_comment->post->post_password ) );
+
+       // If this is a password protected post, or not a public post don't record the comment
+       if ( $is_post_status_not_allowed ) {
+               return false;
+       }
+
+       // Set post type
+       $post_type = $post_type_comment->post->post_type;
+
+       if ( empty( $activity_post_object ) ) {
+               // Get the post type tracking args.
+               $activity_post_object = bp_activity_get_post_type_tracking_args( $post_type );
+
+               // Bail if the activity type does not exist
+               if ( empty( $activity_post_object->comments_tracking->action_id ) ) {
+                       return false;
+               }
+       }
+
+       // Set the $activity_comment_object
+       $activity_comment_object = $activity_post_object->comments_tracking;
+
+       /**
+        * Filters whether or not to post the activity about the comment.
+        *
+        * This is a variable filter, dependent on the post type,
+        * that lets components or plugins bail early if needed.
+        *
+        * @since 2.5.0
+        *
+        * @param bool $value      Whether or not to continue.
+        * @param int  $blog_id    ID of the current site.
+        * @param int  $post_id    ID of the current post being commented.
+        * @param int  $user_id    ID of the current user.
+        * @param int  $comment_id ID of the current comment being posted.
+        */
+       if ( false === apply_filters( "bp_activity_{$post_type}_pre_comment", true, $blog_id, $post_type_comment->post->ID, $user_id, $comment_id ) ) {
+               return false;
+       }
+
+       // Is this an update ?
+       $activity_id = bp_activity_get_activity_id( array(
+               'user_id'           => $user_id,
+               'component'         => $activity_comment_object->component_id,
+               'type'              => $activity_comment_object->action_id,
+               'item_id'           => $blog_id,
+               'secondary_item_id' => $comment_id,
+       ) );
+
+       // Record this in activity streams.
+       $comment_link = get_comment_link( $post_type_comment->comment_ID );
+
+       // Backward compatibility filters for the 'blogs' component.
+       if ( 'blogs' == $activity_comment_object->component_id )  {
+               $activity_content      = apply_filters_ref_array( 'bp_blogs_activity_new_comment_content',      array( $post_type_comment->comment_content, &$post_type_comment, $comment_link ) );
+               $activity_primary_link = apply_filters_ref_array( 'bp_blogs_activity_new_comment_primary_link', array( $comment_link, &$post_type_comment ) );
+       } else {
+               $activity_content      = $post_type_comment->comment_content;
+               $activity_primary_link = $comment_link;
+       }
+
+       $activity_args = array(
+               'id'            => $activity_id,
+               'user_id'       => $user_id,
+               'content'       => $activity_content,
+               'primary_link'  => $activity_primary_link,
+               'component'     => $activity_comment_object->component_id,
+               'recorded_time' => $post_type_comment->comment_date_gmt,
+       );
+
+       if ( bp_disable_blogforum_comments() ) {
+               $blog_url = get_home_url( $blog_id );
+               $post_url = add_query_arg(
+                       'p',
+                       $post_type_comment->post->ID,
+                       trailingslashit( $blog_url )
+               );
+
+               $activity_args['type']              = $activity_comment_object->action_id;
+               $activity_args['item_id']           = $blog_id;
+               $activity_args['secondary_item_id'] = $post_type_comment->comment_ID;
+
+               if ( ! empty( $activity_args['content'] ) ) {
+                       // Create the excerpt.
+                       $activity_summary = bp_activity_create_summary( $activity_args['content'], $activity_args );
+
+                       // Backward compatibility filter for blog comments.
+                       if ( 'blogs' == $activity_post_object->component_id )  {
+                               $activity_args['content'] = apply_filters( 'bp_blogs_record_activity_content', $activity_summary, $activity_args['content'], $activity_args, $post_type );
+                       } else {
+                               $activity_args['content'] = $activity_summary;
+                       }
+               }
+
+               // Set up the action by using the format functions.
+               $action_args = array_merge( $activity_args, array(
+                       'post_title' => $post_type_comment->post->post_title,
+                       'post_url'   => $post_url,
+                       'blog_url'   => $blog_url,
+                       'blog_name'  => get_blog_option( $blog_id, 'blogname' ),
+               ) );
+
+               $activity_args['action'] = call_user_func_array( $activity_comment_object->format_callback, array( '', (object) $action_args ) );
+
+               // Make sure the action is set.
+               if ( empty( $activity_args['action'] ) ) {
+                       return;
+               } else {
+                       // Backward compatibility filter for the blogs component.
+                       if ( 'blogs' === $activity_post_object->component_id )  {
+                               $activity_args['action'] = apply_filters( 'bp_blogs_record_activity_action', $activity_args['action'] );
+                       }
+               }
+
+               $activity_id = bp_activity_add( $activity_args );
+       }
+
+       /**
+        * Fires after the publishing of an activity item for a newly published post type post.
+        *
+        * @since 2.5.0
+        *
+        * @param int        $activity_id          ID of the newly published activity item.
+        * @param WP_Comment $post_type_comment    Comment object.
+        * @param array      $activity_args        Array of activity arguments.
+        * @param object     $activity_post_object the post type tracking args object.
+        */
+       do_action_ref_array( 'bp_activity_post_type_comment', array( &$activity_id, $post_type_comment, $activity_args, $activity_post_object ) );
+
+       return $activity_id;
+}
+
+/**
+ * Remove an activity item when a comment about a post type is deleted.
+ *
+ * @since 2.5.0
+ *
+ * @param  int    $comment_id           ID of the comment.
+ * @param  object $activity_post_object The post type tracking args object.
+ *
+ * @return bool True on success. False on error.
+ */
+function bp_activity_post_type_remove_comment( $comment_id = 0, $activity_post_object = null ) {
+       if ( empty( $activity_post_object ) ) {
+               $comment = get_comment( $comment_id );
+               if ( ! $comment ) {
+                       return;
+               }
+
+               $post_type = get_post_type( $comment->comment_post_ID );
+               if ( ! $post_type ) {
+                       return;
+               }
+
+               // Get the post type tracking args.
+               $activity_post_object = bp_activity_get_post_type_tracking_args( $post_type );
+
+               // Bail if the activity type does not exist
+               if ( empty( $activity_post_object->comments_tracking->action_id ) ) {
+                       return false;
+               }
+       }
+
+       // Set the $activity_comment_object
+       $activity_comment_object = $activity_post_object->comments_tracking;
+
+       if ( empty( $activity_comment_object->action_id ) ) {
+               return false;
+       }
+
+       $deleted = false;
+
+       if ( bp_disable_blogforum_comments() ) {
+               $deleted = bp_activity_delete_by_item_id( array(
+                       'item_id'           => get_current_blog_id(),
+                       'secondary_item_id' => $comment_id,
+                       'component'         => $activity_comment_object->component_id,
+                       'type'              => $activity_comment_object->action_id,
+                       'user_id'           => false,
+               ) );
+       }
+
+       /**
+        * Fires after the custom post type comment activity was removed.
+        *
+        * @since 2.5.0
+        *
+        * @param bool       $deleted              True if the activity was deleted false otherwise
+        * @param WP_Comment $comment              Comment object.
+        * @param object     $activity_post_object The post type tracking args object.
+        * @param string     $value                The post type comment activity type.
+        */
+       do_action( 'bp_activity_post_type_remove_comment', $deleted, $comment_id, $activity_post_object, $activity_comment_object->action_id );
+
+       return $deleted;
+}
+
+/**
</ins><span class="cx" style="display: block; padding: 0 10px">  * Add an activity comment.
</span><span class="cx" style="display: block; padding: 0 10px">  *
</span><span class="cx" style="display: block; padding: 0 10px">  * @since 1.2.0
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @since 2.5.0 Add a new possible parameter $skip_notification for the array of arguments.
+ *              Add the $primary_link parameter for the array of arguments.
</ins><span class="cx" style="display: block; padding: 0 10px">  *
</span><span class="cx" style="display: block; padding: 0 10px">  * @uses wp_parse_args()
</span><span class="cx" style="display: block; padding: 0 10px">  * @uses bp_activity_add()
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2303,15 +2563,19 @@
</span><span class="cx" style="display: block; padding: 0 10px">  * @uses do_action() To call the 'bp_activity_comment_posted' hook.
</span><span class="cx" style="display: block; padding: 0 10px">  *
</span><span class="cx" style="display: block; padding: 0 10px">  * @param array|string $args {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- *     @type int    $id          Optional. Pass an ID to update an existing comment.
- *     @type string $content     The content of the comment.
- *     @type int    $user_id     Optional. The ID of the user making the comment.
- *                               Defaults to the ID of the logged-in user.
- *     @type int    $activity_id The ID of the "root" activity item, ie the oldest
- *                               ancestor of the comment.
- *     @type int    $parent_id   Optional. The ID of the parent activity item, ie the item to
- *                               which the comment is an immediate reply. If not provided,
- *                               this value defaults to the $activity_id.
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ *     @type int    $id                Optional. Pass an ID to update an existing comment.
+ *     @type string $content           The content of the comment.
+ *     @type int    $user_id           Optional. The ID of the user making the comment.
+ *                                     Defaults to the ID of the logged-in user.
+ *     @type int    $activity_id       The ID of the "root" activity item, ie the oldest
+ *                                     ancestor of the comment.
+ *     @type int    $parent_id         Optional. The ID of the parent activity item, ie the item to
+ *                                     which the comment is an immediate reply. If not provided,
+ *                                     this value defaults to the $activity_id.
+ *     @type string $primary_link      Optional. the primary link for the comment.
+ *                                     Defaults to an empty string.
+ *     @type bool   $skip_notification Optional. false to send a comment notification, false otherwise.
+ *                                     Defaults to false.
</ins><span class="cx" style="display: block; padding: 0 10px">  * }
</span><span class="cx" style="display: block; padding: 0 10px">  * @return int|bool The ID of the comment on success, otherwise false.
</span><span class="cx" style="display: block; padding: 0 10px">  */
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2325,11 +2589,13 @@
</span><span class="cx" style="display: block; padding: 0 10px">        }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        $r = wp_parse_args( $args, array(
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                'id'          => false,
-               'content'     => false,
-               'user_id'     => bp_loggedin_user_id(),
-               'activity_id' => false, // ID of the root activity item.
-               'parent_id'   => false  // ID of a parent comment (optional).
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         'id'                => false,
+               'content'           => false,
+               'user_id'           => bp_loggedin_user_id(),
+               'activity_id'       => false, // ID of the root activity item.
+               'parent_id'         => false, // ID of a parent comment (optional).
+               'primary_link'      => '',
+               'skip_notification' => false,
</ins><span class="cx" style="display: block; padding: 0 10px">         ) );
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        // Bail if missing necessary data.
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2376,6 +2642,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">                'content'           => $comment_content,
</span><span class="cx" style="display: block; padding: 0 10px">                'component'         => buddypress()->activity->id,
</span><span class="cx" style="display: block; padding: 0 10px">                'type'              => 'activity_comment',
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                'primary_link'      => $r['primary_link'],
</ins><span class="cx" style="display: block; padding: 0 10px">                 'user_id'           => $r['user_id'],
</span><span class="cx" style="display: block; padding: 0 10px">                'item_id'           => $activity_id,
</span><span class="cx" style="display: block; padding: 0 10px">                'secondary_item_id' => $r['parent_id'],
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2394,16 +2661,31 @@
</span><span class="cx" style="display: block; padding: 0 10px">        }
</span><span class="cx" style="display: block; padding: 0 10px">        wp_cache_delete( $activity_id, 'bp_activity' );
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        /**
-        * Fires near the end of an activity comment posting, before the returning of the comment ID.
-        *
-        * @since 1.2.0
-        *
-        * @param int                  $comment_id ID of the newly posted activity comment.
-        * @param array                $r          Array of parsed comment arguments.
-        * @param BP_Activity_Activity $activity   Activity item being commented on.
-        */
-       do_action( 'bp_activity_comment_posted', $comment_id, $r, $activity );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ if ( empty( $r[ 'skip_notification' ] ) ) {
+               /**
+                * Fires near the end of an activity comment posting, before the returning of the comment ID.
+                * Sends a notification to the user @see bp_activity_new_comment_notification_helper().
+                *
+                * @since 1.2.0
+                *
+                * @param int   $comment_id ID of the newly posted activity comment.
+                * @param array $r          Array of parsed comment arguments.
+                * @param int   $activity   ID of the activity item being commented on.
+                */
+               do_action( 'bp_activity_comment_posted', $comment_id, $r, $activity );
+       } else {
+               /**
+                * Fires near the end of an activity comment posting, before the returning of the comment ID.
+                * without sending a notification to the user
+                *
+                * @since 2.5.0
+                *
+                * @param int   $comment_id ID of the newly posted activity comment.
+                * @param array $r          Array of parsed comment arguments.
+                * @param int   $activity   ID of the activity item being commented on.
+                */
+               do_action( 'bp_activity_comment_posted_notification_skipped', $comment_id, $r, $activity );
+       }
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        if ( empty( $comment_id ) ) {
</span><span class="cx" style="display: block; padding: 0 10px">                $errors->add( 'comment_failed', $feedback );
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2672,6 +2954,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">  * @return bool True on success, false on failure.
</span><span class="cx" style="display: block; padding: 0 10px">  */
</span><span class="cx" style="display: block; padding: 0 10px"> function bp_activity_delete_comment( $activity_id, $comment_id ) {
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+        $deleted = false;
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        /**
</span><span class="cx" style="display: block; padding: 0 10px">         * Filters whether BuddyPress should delete an activity comment or not.
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2680,13 +2963,15 @@
</span><span class="cx" style="display: block; padding: 0 10px">         * handle the deletion of child comments differently. Make sure you return false.
</span><span class="cx" style="display: block; padding: 0 10px">         *
</span><span class="cx" style="display: block; padding: 0 10px">         * @since 1.2.0
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         * @since 2.5.0 Add the deleted parameter (passed by reference)
</ins><span class="cx" style="display: block; padding: 0 10px">          *
</span><span class="cx" style="display: block; padding: 0 10px">         * @param bool $value       Whether BuddyPress should continue or not.
</span><span class="cx" style="display: block; padding: 0 10px">         * @param int  $activity_id ID of the root activity item being deleted.
</span><span class="cx" style="display: block; padding: 0 10px">         * @param int  $comment_id  ID of the comment being deleted.
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         * @param bool $deleted     Whether the activity comment has been deleted or not.
</ins><span class="cx" style="display: block; padding: 0 10px">          */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        if ( ! apply_filters( 'bp_activity_delete_comment_pre', true, $activity_id, $comment_id ) ) {
-               return false;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ if ( ! apply_filters_ref_array( 'bp_activity_delete_comment_pre', array( true, $activity_id, $comment_id, &$deleted ) ) ) {
+               return $deleted;
</ins><span class="cx" style="display: block; padding: 0 10px">         }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        // Delete any children of this comment.
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2695,6 +2980,8 @@
</span><span class="cx" style="display: block; padding: 0 10px">        // Delete the actual comment.
</span><span class="cx" style="display: block; padding: 0 10px">        if ( ! bp_activity_delete( array( 'id' => $comment_id, 'type' => 'activity_comment' ) ) ) {
</span><span class="cx" style="display: block; padding: 0 10px">                return false;
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+        } else {
+               $deleted = true;
</ins><span class="cx" style="display: block; padding: 0 10px">         }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        // Purge comment cache for the root activity update.
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2713,7 +3000,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">         */
</span><span class="cx" style="display: block; padding: 0 10px">        do_action( 'bp_activity_delete_comment', $activity_id, $comment_id );
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        return true;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ return $deleted;
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        /**
</span></span></pre>
</div>
</div>

</body>
</html>