<!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][7422] trunk: Delete activity comment meta when deleting parent activity items.</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">
<dt>Revision</dt> <dd><a href="http://buddypress.trac.wordpress.org/changeset/7422">7422</a></dd>
<dt>Author</dt> <dd>r-a-y</dd>
<dt>Date</dt> <dd>2013-10-13 02:36:04 +0000 (Sun, 13 Oct 2013)</dd>
</dl>

<h3>Log Message</h3>
<pre>Delete activity comment meta when deleting parent activity items.

Previously, when deleting parent activity items, BP would delete the
related activity comments, but not the activity comment metadata.

To solve this, activity comments are now queried and removed in the
main BP_Activity_Activity::delete() method and the activity comment
IDs are now properly passed to the delete_activity_meta_entries()
method.

Commit also includes a unit test for this issue.

Hat-tip boonebgorges for feedback.

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

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkbpactivitybpactivityclassesphp">trunk/bp-activity/bp-activity-classes.php</a></li>
<li><a href="#trunkteststestcasesactivityfunctionsphp">trunk/tests/testcases/activity/functions.php</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkbpactivitybpactivityclassesphp"></a>
<div class="modfile"><h4>Modified: trunk/bp-activity/bp-activity-classes.php (7421 => 7422)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/bp-activity/bp-activity-classes.php        2013-10-11 18:58:12 UTC (rev 7421)
+++ trunk/bp-activity/bp-activity-classes.php   2013-10-13 02:36:04 UTC (rev 7422)
</span><span class="lines">@@ -550,6 +550,8 @@
</span><span class="cx">   * To delete a specific activity item, pass an 'id' parameter.
</span><span class="cx">   * Otherwise use the filters.
</span><span class="cx">   *
</span><ins>+        * @since BuddyPress (1.2)
+        *
</ins><span class="cx">    * @param array $args {
</span><span class="cx">   *     @int $id Optional. The ID of a specific item to delete.
</span><span class="cx">   *     @string $action Optional. The action to filter by.
</span><span class="lines">@@ -627,14 +629,29 @@
</span><span class="cx">          // Fetch the activity IDs so we can delete any comments for this activity item
</span><span class="cx">          $activity_ids = $wpdb->get_col( "SELECT id FROM {$bp->activity->table_name} {$where_sql}" );
</span><span class="cx"> 
</span><del>-               if ( !$wpdb->query( "DELETE FROM {$bp->activity->table_name} {$where_sql}" ) )
</del><ins>+                if ( ! $wpdb->query( "DELETE FROM {$bp->activity->table_name} {$where_sql}" ) ) {
</ins><span class="cx">                   return false;
</span><ins>+               }
</ins><span class="cx"> 
</span><ins>+               // Handle accompanying activity comments and meta deletion
</ins><span class="cx">           if ( $activity_ids ) {
</span><del>-                       BP_Activity_Activity::delete_activity_item_comments( $activity_ids );
</del><ins>+                        $activity_ids_comma          = implode( ',', wp_parse_id_list( $activity_ids ) );
+                       $activity_comments_where_sql = "WHERE type = 'activity_comment' AND item_id IN ({$activity_ids_comma})";
+
+                       // Fetch the activity comment IDs for our deleted activity items
+                       $activity_comment_ids = $wpdb->get_col( "SELECT id FROM {$bp->activity->table_name} {$activity_comments_where_sql}" );
+
+                       // We have activity comments!
+                       if ( ! empty( $activity_comment_ids ) ) {
+                               // Delete activity comments
+                               $wpdb->query( "DELETE FROM {$bp->activity->table_name} {$activity_comments_where_sql}" );
+
+                               // Merge activity IDs with activity comment IDs
+                               $activity_ids = array_merge( $activity_ids, $activity_comment_ids );
+                       }
+
+                       // Delete all activity meta entries for activity items and activity comments
</ins><span class="cx">                   BP_Activity_Activity::delete_activity_meta_entries( $activity_ids );
</span><del>-
-                       return $activity_ids;
</del><span class="cx">           }
</span><span class="cx"> 
</span><span class="cx">          return $activity_ids;
</span><span class="lines">@@ -643,20 +660,38 @@
</span><span class="cx">  /**
</span><span class="cx">   * Delete the comments associated with a set of activity items.
</span><span class="cx">   *
</span><ins>+        * @since BuddyPress (1.2)
+        *
+        * @todo Mark as deprecated?  Method is no longer used internally.
+        *
</ins><span class="cx">    * @param array $activity_ids Activity IDs whose comments should be deleted.
</span><ins>+        * @param bool $delete_meta Should we delete the activity meta items for these comments?
</ins><span class="cx">    * @return bool True on success.
</span><span class="cx">   */
</span><del>-       public static function delete_activity_item_comments( $activity_ids = array() ) {
</del><ins>+        public static function delete_activity_item_comments( $activity_ids = array(), $delete_meta = true ) {
</ins><span class="cx">           global $bp, $wpdb;
</span><span class="cx"> 
</span><ins>+               $delete_meta = (bool) $delete_meta;
+
</ins><span class="cx">           $activity_ids = implode( ',', wp_parse_id_list( $activity_ids ) );
</span><span class="cx"> 
</span><ins>+               if ( $delete_meta ) {
+                       // Fetch the activity comment IDs for our deleted activity items
+                       $activity_comment_ids = $wpdb->get_col( "SELECT id FROM {$bp->activity->table_name} WHERE type = 'activity_comment' AND item_id IN ({$activity_ids})" );
+
+                       if ( ! empty( $activity_comment_ids ) ) {
+                               self::delete_activity_meta_entries( $activity_comment_ids );
+                       }
+               }
+
</ins><span class="cx">           return $wpdb->query( "DELETE FROM {$bp->activity->table_name} WHERE type = 'activity_comment' AND item_id IN ({$activity_ids})" );
</span><span class="cx">  }
</span><span class="cx"> 
</span><span class="cx">  /**
</span><span class="cx">   * Delete the meta entries associated with a set of activity items.
</span><span class="cx">   *
</span><ins>+        * @since BuddyPress (1.2)
+        *
</ins><span class="cx">    * @param array $activity_ids Activity IDs whose meta should be deleted.
</span><span class="cx">   * @return bool True on success.
</span><span class="cx">   */
</span></span></pre></div>
<a id="trunkteststestcasesactivityfunctionsphp"></a>
<div class="modfile"><h4>Modified: trunk/tests/testcases/activity/functions.php (7421 => 7422)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/tests/testcases/activity/functions.php     2013-10-11 18:58:12 UTC (rev 7421)
+++ trunk/tests/testcases/activity/functions.php        2013-10-13 02:36:04 UTC (rev 7422)
</span><span class="lines">@@ -34,4 +34,56 @@
</span><span class="cx">          $this->assertEquals( bp_activity_thumbnail_content_images( $post_content ), '<img src="http://example.com/foo.jpg" width="40" height="40" alt="Thumbnail" class="align-left thumbnail" /> Awesome.' );
</span><span class="cx">  }
</span><span class="cx"> 
</span><ins>+       /**
+        * @group delete
+        */
+       public function test_delete_activity_and_meta() {
+               // create an activity update
+               $parent_activity = $this->factory->activity->create( array(
+                       'type' => 'activity_update',
+               ) );
+
+               // create some activity comments
+               $comment_one = $this->factory->activity->create( array(
+                       'type'              => 'activity_comment',
+                       'item_id'           => $parent_activity,
+                       'secondary_item_id' => $parent_activity,
+               ) );
+
+               $comment_two = $this->factory->activity->create( array(
+                       'type'              => 'activity_comment',
+                       'item_id'           => $parent_activity,
+                       'secondary_item_id' => $parent_activity,
+               ) );
+
+               // add some meta to the activity items
+               bp_activity_update_meta( $parent_activity, 'foo', 'bar' );
+               bp_activity_update_meta( $comment_one,     'foo', 'bar' );
+               bp_activity_update_meta( $comment_two,     'foo', 'bar' );
+
+               // now delete the parent activity item
+               // this should hopefully delete the associated comments and meta entries
+               bp_activity_delete( array(
+                       'id' => $parent_activity
+               ) );
+
+               // now fetch the deleted activity entries
+               $get = bp_activity_get( array(
+                       'in'               => array( $parent_activity, $comment_one, $comment_two ),
+                       'display_comments' => 'stream'
+               ) );
+
+               // activities should equal zero
+               $this->assertEquals( 0, $get['total'] );
+
+               // now fetch activity meta for the deleted activity entries
+               $m1 = bp_activity_get_meta( $parent_activity );
+               $m2 = bp_activity_get_meta( $comment_one );
+               $m3 = bp_activity_get_meta( $comment_two );
+
+               // test if activity meta entries still exist
+               $this->assertEquals( false, $m1 );
+               $this->assertEquals( false, $m2 );
+               $this->assertEquals( false, $m3 );
+       }
</ins><span class="cx"> }
</span></span></pre>
</div>
</div>

</body>
</html>