<!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][9204] trunk: Create an activity item when a group's details are updated.</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/9204">9204</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/9204","name":"Review Commit"}}</script></dd>
<dt style="float: left; width: 6em; font-weight: bold">Author</dt> <dd>boonebgorges</dd>
<dt style="float: left; width: 6em; font-weight: bold">Date</dt> <dd>2014-11-29 16:04:42 +0000 (Sat, 29 Nov 2014)</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'>Create an activity item when a group's details are updated.

When a name or description alone are updated, the activity item will display
the "from" and "to" values as part of the formatted activity action string. If
both items have been changed, the activity action will read "x changed the name
and description of the group y".

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

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunksrcbpgroupsbpgroupsactivityphp">trunk/src/bp-groups/bp-groups-activity.php</a></li>
<li><a href="#trunksrcbpgroupsbpgroupsfunctionsphp">trunk/src/bp-groups/bp-groups-functions.php</a></li>
<li><a href="#trunktestsphpunittestcasesgroupsactivityphp">trunk/tests/phpunit/testcases/groups/activity.php</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunksrcbpgroupsbpgroupsactivityphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/bp-groups/bp-groups-activity.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/bp-groups/bp-groups-activity.php        2014-11-28 20:41:07 UTC (rev 9203)
+++ trunk/src/bp-groups/bp-groups-activity.php  2014-11-29 16:04:42 UTC (rev 9204)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -43,6 +43,15 @@
</span><span class="cx" style="display: block; padding: 0 10px">                array( 'activity', 'group', 'member', 'member_groups' )
</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">+        bp_activity_set_action(
+               $bp->groups->id,
+               'group_details_updated',
+               __( 'Group details edited', 'buddypress' ),
+               'bp_groups_format_activity_action_group_details_updated',
+               __( 'Group Updates', 'buddypress' ),
+               array( 'activity', 'group', 'member', 'member_groups' )
+       );
+
</ins><span class="cx" style="display: block; padding: 0 10px">         // These actions are for the legacy forums
</span><span class="cx" style="display: block; padding: 0 10px">        // Since the bbPress plugin also shares the same 'forums' identifier, we also
</span><span class="cx" style="display: block; padding: 0 10px">        // check for the legacy forums loader class to be extra cautious
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -128,6 +137,51 @@
</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">+ * Format 'group_details_updated' activity actions.
+ *
+ * @since BuddyPress (2.2.0)
+ *
+ * @param  string $action   Static activity action.
+ * @param  object $activity Activity data object.
+ * @return string
+ */
+function bp_groups_format_activity_action_group_details_updated( $action, $activity ) {
+       $user_link = bp_core_get_userlink( $activity->user_id );
+
+       $group = groups_get_group( array(
+               'group_id'        => $activity->item_id,
+               'populate_extras' => false,
+       ) );
+       $group_link = '<a href="' . esc_url( bp_get_group_permalink( $group ) ) . '">' . esc_html( $group->name ) . '</a>';
+
+       /*
+        * Changed group details are stored in groupmeta, keyed by the activity
+        * timestamp. See {@link bp_groups_group_details_updated_add_activity()}.
+        */
+       $changed = groups_get_groupmeta( $activity->item_id, 'updated_details_' . $activity->date_recorded );
+
+       // No changed details were found, so use a generic message.
+       if ( empty( $changed ) ) {
+               $action = sprintf( __( '%1$s updated details for the group %2$s', 'buddypress' ), $user_link, $group_link );
+
+       // Name and description changed - to keep things short, don't describe changes in detail.
+       } else if ( isset( $changed['name'] ) && isset( $changed['description'] ) ) {
+               $action = sprintf( __( '%1$s changed the name and description of the group %2$s', 'buddypress' ), $user_link, $group_link );
+
+       // Name only.
+       } else if ( ! empty( $changed['name']['old'] ) && ! empty( $changed['name']['new'] ) ) {
+               $action = sprintf( __( '%1$s changed the name of the group %2$s from "%3$s" to "%4$s"', 'buddypress' ), $user_link, $group_link, esc_html( $changed['name']['old'] ), esc_html( $changed['name']['new'] ) );
+
+       // Description only.
+       } else if ( ! empty( $changed['description']['old'] ) && ! empty( $changed['description']['new'] ) ) {
+               $action = sprintf( __( '%1$s changed the description of the group %2$s from "%3$s" to "%4$s"', 'buddypress' ), $user_link, $group_link, esc_html( $changed['description']['old'] ), esc_html( $changed['description']['new'] ) );
+
+       }
+
+       return apply_filters( 'bp_groups_format_activity_action_joined_group', $action, $activity );
+}
+
+/**
</ins><span class="cx" style="display: block; padding: 0 10px">  * Fetch data related to groups at the beginning of an activity loop.
</span><span class="cx" style="display: block; padding: 0 10px">  *
</span><span class="cx" style="display: block; padding: 0 10px">  * This reduces database overhead during the activity loop.
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -290,6 +344,78 @@
</span><span class="cx" style="display: block; padding: 0 10px"> add_action( 'groups_membership_accepted', 'bp_groups_membership_accepted_add_activity', 10, 2 );
</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">+ * Add an activity item when a group's details are updated.
+ *
+ * @since BuddyPress (2.2.0)
+ *
+ * @param  int             $group_id       ID of the group.
+ * @param  BP_Groups_Group $old_grop       Group object before the details had been changed.
+ * @param  bool            $notify_members True if the admin has opted to notify group members, otherwise false.
+ * @return int|bool The ID of the activity on success. False on error.
+ */
+function bp_groups_group_details_updated_add_activity( $group_id, $old_group, $notify_members ) {
+
+       // Bail if Activity is not active.
+       if ( ! bp_is_active( 'activity' ) ) {
+               return false;
+       }
+
+       if ( ! isset( $old_group->name ) || ! isset( $old_group->description ) ) {
+               return false;
+       }
+
+       // If the admin has opted not to notify members, don't post an activity item either
+       if ( empty( $notify_members ) ) {
+               return;
+       }
+
+       $group = groups_get_group( array(
+               'group_id' => $group_id,
+       ) );
+
+       /*
+        * Store the changed data, which will be used to generate the activity
+        * action. Since we haven't yet created the activity item, we store the
+        * old group data in groupmeta, keyed by the timestamp that we'll put
+        * on the activity item.
+        */
+       $changed = array();
+
+       if ( $group->name !== $old_group->name ) {
+               $changed['name'] = array(
+                       'old' => $old_group->name,
+                       'new' => $group->name,
+               );
+       }
+
+       if ( $group->description !== $old_group->description ) {
+               $changed['description'] = array(
+                       'old' => $old_group->description,
+                       'new' => $group->description,
+               );
+       }
+
+       // If there are no changes, don't post an activity item.
+       if ( empty( $changed ) ) {
+               return;
+       }
+
+       $time = bp_core_current_time();
+       groups_update_groupmeta( $group_id, 'updated_details_' . $time, $changed );
+
+       // Record in activity streams.
+       return groups_record_activity( array(
+               'type'          => 'group_details_updated',
+               'item_id'       => $group_id,
+               'user_id'       => bp_loggedin_user_id(),
+               'recorded_time' => $time,
+
+       ) );
+
+}
+add_action( 'groups_details_updated', 'bp_groups_group_details_updated_add_activity', 10, 3 );
+
+/**
</ins><span class="cx" style="display: block; padding: 0 10px">  * Delete all activity items related to a specific group.
</span><span class="cx" style="display: block; padding: 0 10px">  *
</span><span class="cx" style="display: block; padding: 0 10px">  * @since BuddyPress (1.9.0)
</span></span></pre></div>
<a id="trunksrcbpgroupsbpgroupsfunctionsphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/bp-groups/bp-groups-functions.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/bp-groups/bp-groups-functions.php       2014-11-28 20:41:07 UTC (rev 9203)
+++ trunk/src/bp-groups/bp-groups-functions.php 2014-11-29 16:04:42 UTC (rev 9204)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -190,7 +190,9 @@
</span><span class="cx" style="display: block; padding: 0 10px">        if ( empty( $group_name ) || empty( $group_desc ) )
</span><span class="cx" style="display: block; padding: 0 10px">                return false;
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        $group              = groups_get_group( array( 'group_id' => $group_id ) );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $group     = groups_get_group( array( 'group_id' => $group_id ) );
+       $old_group = clone $group;
+
</ins><span class="cx" style="display: block; padding: 0 10px">         $group->name        = $group_name;
</span><span class="cx" style="display: block; padding: 0 10px">        $group->description = $group_desc;
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -201,7 +203,16 @@
</span><span class="cx" style="display: block; padding: 0 10px">                groups_notification_group_updated( $group->id );
</span><span class="cx" style="display: block; padding: 0 10px">        }
</span><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( 'groups_details_updated', $group->id );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ /**
+        * Fired after a group's details are updated.
+        *
+        * @since BuddyPress (2.2.0)
+        *
+        * @param int             $value          ID of the group.
+        * @param BP_Groups_Group $old_group      Group object, before being modified.
+        * @param bool            $notify_members Whether to send an email notification to members about the change.
+        */
+       do_action( 'groups_details_updated', $group->id, $old_group, $notify_members );
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        return true;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span></span></pre></div>
<a id="trunktestsphpunittestcasesgroupsactivityphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/tests/phpunit/testcases/groups/activity.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/tests/phpunit/testcases/groups/activity.php 2014-11-28 20:41:07 UTC (rev 9203)
+++ trunk/tests/phpunit/testcases/groups/activity.php   2014-11-29 16:04:42 UTC (rev 9204)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -48,4 +48,116 @@
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                $this->assertSame( $expected, $a_obj->action );
</span><span class="cx" style="display: block; padding: 0 10px">        }
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+
+       /**
+        * @group activity_action
+        * @group bp_groups_format_activity_action_group_details_updated
+        */
+       public function test_bp_groups_format_activity_action_group_details_updated_with_no_change() {
+               $group = $this->factory->group->create_and_get();
+               groups_edit_base_group_details( $group->id, $group->name, $group->description, true );
+
+               $a = bp_activity_get( array(
+                       'component' => buddypress()->groups->id,
+                       'action' => 'group_details_updated',
+                       'item_id' => $group->id,
+               ) );
+
+               $this->assertTrue( empty( $a['activities'] ) );
+       }
+
+       /**
+        * @group activity_action
+        * @group bp_groups_format_activity_action_group_details_updated
+        */
+       public function test_bp_groups_format_activity_action_group_details_updated_with_notify_members_false() {
+               $group = $this->factory->group->create_and_get();
+               groups_edit_base_group_details( $group->id, 'Foo', $group->description, false );
+
+               $a = bp_activity_get( array(
+                       'component' => buddypress()->groups->id,
+                       'action' => 'group_details_updated',
+                       'item_id' => $group->id,
+               ) );
+
+               $this->assertTrue( empty( $a['activities'] ) );
+       }
+
+       /**
+        * @group activity_action
+        * @group bp_groups_format_activity_action_group_details_updated
+        */
+       public function test_bp_groups_format_activity_action_group_details_updated_with_updated_name() {
+               $old_user = get_current_user_id();
+               $u = $this->factory->user->create();
+               $this->set_current_user( $u );
+
+               $group = $this->factory->group->create_and_get();
+               groups_edit_base_group_details( $group->id, 'Foo', $group->description, true );
+
+               $a = bp_activity_get( array(
+                       'component' => buddypress()->groups->id,
+                       'action' => 'group_details_updated',
+                       'item_id' => $group->id,
+               ) );
+
+               $this->assertNotEmpty( $a['activities'] );
+
+               $expected = sprintf( __( '%s changed the name of the group %s from "%s" to "%s"', 'buddypress' ), bp_core_get_userlink( $u ),  '<a href="' . bp_get_group_permalink( $group ) . '">Foo</a>', $group->name, 'Foo' );
+               $this->assertSame( $expected, $a['activities'][0]->action );
+
+               $this->set_current_user( $old_user );
+       }
+
+       /**
+        * @group activity_action
+        * @group bp_groups_format_activity_action_group_details_updated
+        */
+       public function test_bp_groups_format_activity_action_group_details_updated_with_updated_description() {
+               $old_user = get_current_user_id();
+               $u = $this->factory->user->create();
+               $this->set_current_user( $u );
+
+               $group = $this->factory->group->create_and_get();
+               groups_edit_base_group_details( $group->id, $group->name, 'Bar', true );
+
+               $a = bp_activity_get( array(
+                       'component' => buddypress()->groups->id,
+                       'action' => 'group_details_updated',
+                       'item_id' => $group->id,
+               ) );
+
+               $this->assertNotEmpty( $a['activities'] );
+
+               $expected = sprintf( __( '%s changed the description of the group %s from "%s" to "%s"', 'buddypress' ), bp_core_get_userlink( $u ),  '<a href="' . bp_get_group_permalink( $group ) . '">' . $group->name . '</a>', $group->description, 'Bar' );
+               $this->assertSame( $expected, $a['activities'][0]->action );
+
+               $this->set_current_user( $old_user );
+       }
+
+       /**
+        * @group activity_action
+        * @group bp_groups_format_activity_action_group_details_updated
+        */
+       public function test_bp_groups_format_activity_action_group_details_updated_with_updated_name_and_description() {
+               $old_user = get_current_user_id();
+               $u = $this->factory->user->create();
+               $this->set_current_user( $u );
+
+               $group = $this->factory->group->create_and_get();
+               groups_edit_base_group_details( $group->id, 'Foo', 'Bar', true );
+
+               $a = bp_activity_get( array(
+                       'component' => buddypress()->groups->id,
+                       'action' => 'group_details_updated',
+                       'item_id' => $group->id,
+               ) );
+
+               $this->assertNotEmpty( $a['activities'] );
+
+               $expected = sprintf( __( '%s changed the name and description of the group %s', 'buddypress' ), bp_core_get_userlink( $u ),  '<a href="' . bp_get_group_permalink( $group ) . '">Foo</a>' );
+               $this->assertSame( $expected, $a['activities'][0]->action );
+
+               $this->set_current_user( $old_user );
+       }
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span></span></pre>
</div>
</div>

</body>
</html>