<!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][5396] trunk/bp-activity: See #3660.</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, #logmsg > ol { margin-left: 0; 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/5396">5396</a></dd>
<dt>Author</dt> <dd>djpaul</dd>
<dt>Date</dt> <dd>2011-11-27 19:00:33 +0000 (Sun, 27 Nov 2011)</dd>
</dl>

<h3>Log Message</h3>
<pre>See <a href="http://buddypress.trac.wordpress.org/ticket/3660">#3660</a>. Activity admin iteration.

* Updated use of old, incorrect bp_activity_get_specific() spam parameter to new name.
* Updated contextual help.
* Updated In Reply To column; now correctly shows details of that activity.
* Made speech bubble appearance consistent between root activities vs. non-root activities.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkbpactivityadmincssadmincss">trunk/bp-activity/admin/css/admin.css</a></li>
<li><a href="#trunkbpactivityadmincssadmindevcss">trunk/bp-activity/admin/css/admin.dev.css</a></li>
<li><a href="#trunkbpactivitybpactivityadminphp">trunk/bp-activity/bp-activity-admin.php</a></li>
<li><a href="#trunkbpactivitybpactivityscreensphp">trunk/bp-activity/bp-activity-screens.php</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkbpactivityadmincssadmincss"></a>
<div class="modfile"><h4>Modified: trunk/bp-activity/admin/css/admin.css (5395 => 5396)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/bp-activity/admin/css/admin.css        2011-11-27 17:31:07 UTC (rev 5395)
+++ trunk/bp-activity/admin/css/admin.css        2011-11-27 19:00:33 UTC (rev 5396)
</span><span class="lines">@@ -1 +1 @@
</span><del>-#wp-bp-activities-wrap{padding:5px 0;}#bp-activities{height:120px;}#bp-replyhead{font-size:1em;line-height:1.4em;margin:0;}#bp-replysubmit{margin:0;padding:0 0 3px;text-align:center;}#bp-replysubmit .error{color:red;line-height:21px;text-align:center;vertical-align:center;}#bp-replysubmit img.waiting{float:right;padding:4px 10px 0;vertical-align:top;}
</del><span class="cx">\ No newline at end of file
</span><ins>+#wp-bp-activities-wrap{padding:5px 0;}#bp-activities{height:120px;}#bp-replyhead{font-size:1em;line-height:1.4em;margin:0;}#bp-replysubmit{margin:0;padding:0 0 3px;text-align:center;}#bp-replysubmit .error{color:red;line-height:21px;text-align:center;vertical-align:center;}#bp-replysubmit img.waiting{float:right;padding:4px 10px 0;vertical-align:top;}#bp-activities-form .column-response img{float:left;margin-right:10px;margin-top:1px;}
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="trunkbpactivityadmincssadmindevcss"></a>
<div class="modfile"><h4>Modified: trunk/bp-activity/admin/css/admin.dev.css (5395 => 5396)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/bp-activity/admin/css/admin.dev.css        2011-11-27 17:31:07 UTC (rev 5395)
+++ trunk/bp-activity/admin/css/admin.dev.css        2011-11-27 19:00:33 UTC (rev 5396)
</span><span class="lines">@@ -1,32 +1,32 @@
</span><span class="cx"> #wp-bp-activities-wrap {
</span><span class="cx">         padding: 5px 0;
</span><span class="cx"> }
</span><del>-
</del><span class="cx"> #bp-activities {
</span><span class="cx">         height: 120px;
</span><span class="cx"> }
</span><del>-
</del><span class="cx"> #bp-replyhead {
</span><span class="cx">         font-size: 1em;
</span><span class="cx">         line-height: 1.4em;
</span><span class="cx">         margin: 0;
</span><span class="cx"> }
</span><del>-
</del><span class="cx"> #bp-replysubmit {
</span><span class="cx">         margin: 0;
</span><span class="cx">         padding: 0 0 3px;
</span><span class="cx">         text-align: center;
</span><span class="cx"> }
</span><del>-
</del><span class="cx"> #bp-replysubmit .error {
</span><span class="cx">         color: red;
</span><span class="cx">         line-height: 21px;
</span><span class="cx">         text-align: center;
</span><span class="cx">         vertical-align: center;
</span><span class="cx"> }
</span><del>-
</del><span class="cx"> #bp-replysubmit img.waiting {
</span><span class="cx">         float: right;
</span><span class="cx">         padding: 4px 10px 0;
</span><span class="cx">         vertical-align: top;
</span><ins>+}
+#bp-activities-form .column-response img {
+        float: left;
+        margin-right: 10px;
+        margin-top: 1px;
</ins><span class="cx"> }
</span><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="trunkbpactivitybpactivityadminphp"></a>
<div class="modfile"><h4>Modified: trunk/bp-activity/bp-activity-admin.php (5395 => 5396)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/bp-activity/bp-activity-admin.php        2011-11-27 17:31:07 UTC (rev 5395)
+++ trunk/bp-activity/bp-activity-admin.php        2011-11-27 19:00:33 UTC (rev 5396)
</span><span class="lines">@@ -147,9 +147,8 @@
</span><span class="cx">         // Help panel - text
</span><span class="cx">         add_contextual_help( get_current_screen(), '&lt;p&gt;' . __( 'You can manage activities made on your site similar to the way you manage comments and other content. This screen is customizable in the same ways as other management screens, and you can act on activities using the on-hover action links or the Bulk Actions.', 'buddypress' ) . '&lt;/p&gt;' .
</span><span class="cx">                 '&lt;p&gt;' . __( 'There are many different types of activities. Some are generated by BuddyPress automatically, and others are entered directly by a user in the form of status update. To help manage the different activity types, use the filter dropdown box to switch between them.', 'buddypress' ) . '&lt;/p&gt;' .
</span><del>-
</del><span class="cx">                 '&lt;p&gt;' . __( 'In the Activity column, above each activity it says &amp;#8220;Submitted on,&amp;#8221; followed by the date and time the activity item was generated on your site. Clicking on the date/time link will take you to that activity on your live site. Hovering over any activity gives you options to reply, edit, spam mark, or delete that activity.', 'buddypress' ) . '&lt;/p&gt;' .
</span><del>-                '&lt;p&gt;' . __( 'In the In Response To column, the text is the name of the user who generated the activity, and a link to the activity on your live site. The small bubble with the number in it shows how many other activities are related to this one; these are usually comments. Clicking the bubble will filter the activity screen to show only related activity items.', 'buddypress' ) . '&lt;/p&gt;'
</del><ins>+                '&lt;p&gt;' . __( &quot;In the In Response To Column, if the activity was in reply to another activity, it shows that activity's author's picture and name, and a link to that activity on your live site. If there is a small bubble, the number in it shows how many other activities are related to this one; these are usually comments. Clicking the bubble will filter the activity screen to show only related activity items.&quot;, 'buddypress' ) . '&lt;/p&gt;'
</ins><span class="cx">         );
</span><span class="cx"> 
</span><span class="cx">         // Help panel - sidebar links
</span><span class="lines">@@ -162,7 +161,7 @@
</span><span class="cx"> 
</span><span class="cx">         // Enqueue CSS and JavaScript
</span><span class="cx">         wp_enqueue_script( 'bp_activity_admin_js', BP_PLUGIN_URL . &quot;bp-activity/admin/js/admin.{$dev}js&quot;, array( 'jquery', 'wp-ajax-response' ), '20111120' );
</span><del>-        wp_enqueue_style( 'bp_activity_admin_css', BP_PLUGIN_URL . &quot;bp-activity/admin/css/admin.{$dev}css&quot;, array(), '20111120' );
</del><ins>+        wp_enqueue_style( 'bp_activity_admin_css', BP_PLUGIN_URL . &quot;bp-activity/admin/css/admin.{$dev}css&quot;, array(), '20111126' );
</ins><span class="cx"> 
</span><span class="cx">         // Create the Activity screen list table
</span><span class="cx">         $bp_activity_list_table = new BP_Activity_List_Table();
</span><span class="lines">@@ -400,6 +399,13 @@
</span><span class="cx">         public $spam_count = 0;
</span><span class="cx"> 
</span><span class="cx">         /**
</span><ins>+         * Store activity-to-user-ID mappings for use in the In Response To column.
+         *
+         * @since 1.6
+         */
+        protected $activity_user_id = array();
+
+        /**
</ins><span class="cx">          * Constructor
</span><span class="cx">          *
</span><span class="cx">          * @global $bp BuddyPress global settings
</span><span class="lines">@@ -487,9 +493,13 @@
</span><span class="cx"> 
</span><span class="cx">                 // bp_activity_get returns an array of objects; cast these to arrays for WP_List_Table.
</span><span class="cx">                 $new_activities = array();
</span><del>-                foreach ( $activities['activities'] as $activity_item )
</del><ins>+                foreach ( $activities['activities'] as $activity_item ) {
</ins><span class="cx">                         $new_activities[] = (array) $activity_item;
</span><span class="cx"> 
</span><ins>+                        // Build an array of activity-to-user ID mappings for better efficency in the In Response To column
+                        $this-&gt;activity_user_id[$activity_item-&gt;id] = $activity_item-&gt;user_id;
+                }
+
</ins><span class="cx">                 // @todo If we're viewing a specific activity, check/merge $activity-&gt;children into the main list (recursive).
</span><span class="cx">                 /*if ( $include_id ) {
</span><span class="cx">                 }*/
</span><span class="lines">@@ -795,50 +805,66 @@
</span><span class="cx">          * @since 1.6
</span><span class="cx">          */
</span><span class="cx">         function column_response( $item ) {
</span><del>-                // Display link to user's profile
-                echo bp_core_get_userlink( $item['user_id'] );
-
</del><span class="cx">                 // Get activity permalink
</span><span class="cx">                 $activity_link = bp_activity_get_permalink( $item['id'], (object) $item );
</span><span class="cx"> 
</span><del>-                // Get the root activity ID by parsing the permalink; this may be not be the same as $item['id'] for nested items (e.g. activity_comments)
-                $root_activity_id = array();
-                preg_match( '/\/p\/(\d+)\/*$/i', $activity_link, $root_activity_id );
-                if ( empty( $root_activity_id[1] ) )
-                        return;
-
-                $root_activity_id  = (int) $root_activity_id[1];
</del><ins>+                // Get the root activity ID; this may be not be the same as $item['id'] for nested items (e.g. activity_comments)
+                $is_root_activity  = empty( $item['item_id'] );
+                $root_activity_id  = $is_root_activity ? $item['id'] : $item['item_id'];
</ins><span class="cx">                 $root_activity_url = network_admin_url( 'admin.php?page=bp-activity&amp;amp;aid=' . $root_activity_id );
</span><span class="cx"> 
</span><del>-                // Is $item the root activity?
-                if ( (int) $item['id'] == $root_activity_id ) {
-                        $root_activity = (object) $item;
</del><ins>+                // Get comment count
+                if ( $is_root_activity )
+                        $comment_count = !empty( $item['children'] ) ? bp_activity_recurse_comment_count( (object) $item ) : 0;
+                else
+                        $comment_count = count( BP_Activity_Activity::get_child_comments( $item['id'] ) );
</ins><span class="cx"> 
</span><del>-                        // Get root activity comment count
-                        $comment_count = !empty( $root_activity-&gt;children ) ? number_format_i18n( bp_activity_recurse_comment_count( $root_activity ) ) : 0;
-                        $title_attr    = sprintf( __( '%s related activities', 'buddypress' ), $comment_count );
</del><ins>+                if ( ! $is_root_activity ) {
+                        // Display link to the replied-to activity's author's profile
+                        echo '&lt;strong&gt;' . get_avatar( $this-&gt;get_activity_user_id( $item['item_id'] ), '32' ) . ' ' . bp_core_get_userlink( $this-&gt;get_activity_user_id( $item['item_id'] ) ) . '&lt;/strong&gt;&lt;br /&gt;';
+                }
</ins><span class="cx"> 
</span><del>-                        // Display a link to the root activity's permalink, with its comment count in a speech bubble
-                        printf( '&lt;br /&gt;&lt;a href=&quot;%1$s&quot; title=&quot;%2$s&quot; class=&quot;post-com-count&quot;&gt;&lt;span class=&quot;comment-count&quot;&gt;%3$s&lt;/span&gt;&lt;/a&gt;', $root_activity_url, esc_attr( $title_attr ), number_format_i18n( $comment_count ) );
</del><ins>+                // If the activity has comments, display a link to the root activity's permalink, with its comment count in a speech bubble
+                if ( $comment_count ) {
+                        $title_attr = sprintf( _n( '%s related activity', '%s related activities', $comment_count, 'buddypress' ), number_format_i18n( $comment_count ) );
+                        printf( '&lt;a href=&quot;%1$s&quot; title=&quot;%2$s&quot; class=&quot;post-com-count&quot;&gt;&lt;span class=&quot;comment-count&quot;&gt;%3$s&lt;/span&gt;&lt;/a&gt;', $root_activity_url, esc_attr( $title_attr ), number_format_i18n( $comment_count ) );
+                }
</ins><span class="cx"> 
</span><del>-                // $item is not the root activity (it is probably an activity_comment).
</del><ins>+                // Activity permalink
+                printf( __( '&lt;a href=&quot;%1$s&quot;&gt;View Activity&lt;/a&gt;', 'buddypress' ), bp_activity_get_permalink( $item['id'], (object) $item ) );
+        }
+
+        /**
+         * A wrapper function for the BP_Activity_List_Table to get the specified activity's user ID.
+         *
+         * @param int $activity_id Activity ID to retrieve User ID for
+         * @since 1.6
+         */
+        protected function get_activity_user_id( $activity_id ) {
+                // If there is an existing activity/user ID mapping, just return the user ID.
+                if ( ! empty( $this-&gt;activity_user_id[$activity_id] ) ) {
+                        return $this-&gt;activity_user_id[$activity_id];
+
+                /**
+                 * We don't have a mapping. This means the $activity_id is not on the current
+                 * page of results, so fetch its details from the database.
+                 */
</ins><span class="cx">                 } else {
</span><del>-                        $comment_count = count( BP_Activity_Activity::get_child_comments( $item['id'] ) );
</del><ins>+                        $activity = bp_activity_get_specific( array( 'activity_ids' =&gt; $activity_id, 'show_hidden' =&gt; true, 'spam' =&gt; 'all', ) );
</ins><span class="cx"> 
</span><del>-                        // If a non-root activity has zero (child) comments, then don't show a zero bubble to keep the UI tidy
-                        if ( 0 == $comment_count ) {
-                                echo '&lt;br /&gt;';
</del><ins>+                        /**
+                         * If, somehow, the referenced activity has been deleted, leaving its associated
+                         * activites as orphans, use the logged in user's ID to avoid errors.
+                         */
+                        if ( empty( $activity['activities'] ) )
+                                return bp_loggedin_user_id();
</ins><span class="cx"> 
</span><del>-                        } else {
-                                $comment_count = number_format_i18n( $comment_count );
-                                $title_attr    = sprintf( __( '%s related activities', 'buddypress' ), $comment_count );
</del><ins>+                        // Store the new activity/user ID mapping for any later re-use
+                        $this-&gt;activity_user_id[ $activity['activities'][0]-&gt;id ] = $activity['activities'][0]-&gt;user_id;
</ins><span class="cx"> 
</span><del>-                                // Display a link to the root activity's permalink, with the current activity's (child) comment count in a speech bubble
-                                printf( '&lt;br /&gt;&lt;a href=&quot;%1$s&quot; title=&quot;%2$s&quot; class=&quot;post-com-count&quot;&gt;&lt;span class=&quot;comment-count&quot;&gt;%3$s&lt;/span&gt;&lt;/a&gt;', $root_activity_url, esc_attr( $title_attr ), number_format_i18n( $comment_count ) );
-                        }
</del><ins>+                        // Return the user ID
+                        return $activity['activities'][0]-&gt;user_id;
</ins><span class="cx">                 }
</span><del>-
-                // Link to the activity permalink
-                printf( __( '&lt;a href=&quot;%1$s&quot;&gt;View Activity&lt;/a&gt;', 'buddypress' ), bp_activity_get_permalink( $item['id'], (object) $item ) );
</del><span class="cx">         }
</span><del>-}?&gt;
</del><span class="cx">\ No newline at end of file
</span><ins>+}
+?&gt;
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="trunkbpactivitybpactivityscreensphp"></a>
<div class="modfile"><h4>Modified: trunk/bp-activity/bp-activity-screens.php (5395 => 5396)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/bp-activity/bp-activity-screens.php        2011-11-27 17:31:07 UTC (rev 5395)
+++ trunk/bp-activity/bp-activity-screens.php        2011-11-27 19:00:33 UTC (rev 5396)
</span><span class="lines">@@ -194,7 +194,7 @@
</span><span class="cx">                 return false;
</span><span class="cx"> 
</span><span class="cx">         // Get the activity details
</span><del>-        $activity = bp_activity_get_specific( array( 'activity_ids' =&gt; bp_current_action(), 'hide_spam' =&gt; true, 'show_hidden' =&gt; true ) );
</del><ins>+        $activity = bp_activity_get_specific( array( 'activity_ids' =&gt; bp_current_action(), 'show_hidden' =&gt; true, 'spam' =&gt; 'ham_only', ) );
</ins><span class="cx"> 
</span><span class="cx">         // 404 if activity does not exist
</span><span class="cx">         if ( empty( $activity['activities'][0] ) || bp_action_variables() ) {
</span></span></pre>
</div>
</div>

</body>
</html>