Skip to:
Content

BuddyPress.org


Ignore:
Timestamp:
03/13/2014 06:34:06 PM (11 years ago)
Author:
boonebgorges
Message:

Generate activity actions dynamically, instead of using static values stored in the database

Activity actions - like 'Joe became a registered member' - have always been
stored as static strings in the activity table. This has been a perennial thorn
in the side of BP site administrators. For one thing, static strings cannot be
translated for multilingual audiences (without unreasonable workarounds).
For another, information in these static strings becomes out of date as users
change their display names, groups change their names, and so on.

This changeset makes it possible for activity types to be registered with a
new $format_callback function, passed to bp_activity_set_action(), which BP
will use to generate the action dynamically when building the activity loop.
This makes the activity stream fully localizable, continually up-to-date, and
generally the bomb dot com.

Existing plugins that do not register format_callback functions will continue
to have their actions pulled directly from the database. Likewise, since a copy
of the static string is saved in the activity table, static strings can be
served if the given component is disabled at any point (and thus the callback
is no longer available).

The original argument for caching the action strings was that generating them
inline was too resource intensive; it often requires pulling up display names,
user permalinks, group links, blog post names, and so forth. To address this
problem, each component can now prefetch required data at the beginning of an
activity loop by hooking to bp_activity_prefetch_object_data, and loading any
relevant data into the cache. The Activity, Friends, Groups, and Blogs
component now do this natively. It's likely that this prefetching will have
other performance benefits, as plugin authors will now be able to access user
data etc inline without performance penalties.

The case of the Blogs component is a special one; it's not practical to
prefetch data from multiple blogs at the beginning of a loop, due to the
resources required by switch_to_blog(). For this reason, the format_callback
functions in the blog component cache some relevant data (like the post name)
in blogmeta, where it's readily accessible within the loop.

Fixes #3856

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/bp-friends/bp-friends-activity.php

    r7629 r8125  
    9393
    9494    // These two added in BP 1.6
    95     bp_activity_set_action( $bp->friends->id, 'friendship_accepted', __( 'Friendships accepted', 'buddypress' ) );
    96     bp_activity_set_action( $bp->friends->id, 'friendship_created',  __( 'New friendships',      'buddypress' ) );
     95    bp_activity_set_action(
     96        $bp->friends->id,
     97        'friendship_accepted',
     98        __( 'Friendships accepted', 'buddypress' ),
     99        'bp_friends_format_activity_action_friendship_accepted'
     100    );
     101
     102    bp_activity_set_action(
     103        $bp->friends->id,
     104        'friendship_created',
     105        __( 'New friendships', 'buddypress' ),
     106        'bp_friends_format_activity_action_friendship_created'
     107    );
    97108
    98109    // < BP 1.6 backpat
     
    102113}
    103114add_action( 'bp_register_activity_actions', 'friends_register_activity_actions' );
     115
     116/**
     117 * Format 'friendship_accepted' activity actions.
     118 *
     119 * @since BuddyPress (2.0.0)
     120 *
     121 * @param object $activity Activity data.
     122 * @return string $action Formatted activity action.
     123 */
     124function bp_friends_format_activity_action_friendship_accepted( $activity ) {
     125    $initiator_link = bp_core_get_userlink( $activity->user_id );
     126    $friend_link    = bp_core_get_userlink( $activity->secondary_item_id );
     127
     128    $action = sprintf( __( '%1$s and %2$s are now friends', 'buddypress' ), $initiator_link, $friend_link );
     129
     130    // Backward compatibility for legacy filter
     131    // The old filter has the $friendship object passed to it. We want to
     132    // avoid having to build this object if it's not necessary
     133    if ( has_filter( 'friends_activity_friendship_accepted_action' ) ) {
     134        $friendship = new BP_Friends_Friendship( $activity->item_id );
     135        $action     = apply_filters( 'friends_activity_friendsip_accepted_action', $action, $friendship );
     136    }
     137
     138    return apply_filters( 'bp_friends_format_activity_action_friendship_accepted', $action, $activity );
     139}
     140
     141/**
     142 * Format 'friendship_created' activity actions.
     143 *
     144 * @since BuddyPress (2.0.0)
     145 *
     146 * @param object $activity Activity data.
     147 * @return string $action Formatted activity action.
     148 */
     149function bp_friends_format_activity_action_friendship_created( $activity ) {
     150    $initiator_link = bp_core_get_userlink( $activity->user_id );
     151    $friend_link    = bp_core_get_userlink( $activity->secondary_item_id );
     152
     153    $action = sprintf( __( '%1$s and %2$s are now friends', 'buddypress' ), $initiator_link, $friend_link );
     154
     155    // Backward compatibility for legacy filter
     156    // The old filter has the $friendship object passed to it. We want to
     157    // avoid having to build this object if it's not necessary
     158    if ( has_filter( 'friends_activity_friendship_accepted_action' ) ) {
     159        $friendship = new BP_Friends_Friendship( $activity->item_id );
     160        $action     = apply_filters( 'friends_activity_friendsip_accepted_action', $action, $friendship );
     161    }
     162
     163    return apply_filters( 'bp_friends_format_activity_action_friendship_created', $action, $activity );
     164}
     165
     166/**
     167 * Fetch data related to friended users at the beginning of an activity loop.
     168 *
     169 * This reduces database overhead during the activity loop.
     170 *
     171 * @since BuddyPress (2.0.0)
     172 *
     173 * @param array $activities Array of activity items.
     174 * @return array
     175 */
     176function bp_friends_prefetch_activity_object_data( $activities ) {
     177    if ( empty( $activities ) ) {
     178        return $activities;
     179    }
     180
     181    $friend_ids = array();
     182
     183    foreach ( $activities as $activity ) {
     184        if ( buddypress()->friends->id !== $activity->component ) {
     185            continue;
     186        }
     187
     188        $friend_ids[] = $activity->secondary_item_id;
     189    }
     190
     191    if ( ! empty( $friend_ids ) ) {
     192        // Fire a user query to prime user caches
     193        new BP_User_Query( array(
     194            'user_ids'          => $friend_ids,
     195            'populate_extras'   => false,
     196            'update_meta_cache' => false,
     197        ) );
     198    }
     199}
     200add_filter( 'bp_activity_prefetch_object_data', 'bp_friends_prefetch_activity_object_data' );
    104201
    105202/**
     
    129226        'user_id'           => $initiator_user_id,
    130227        'type'              => 'friendship_created',
    131         'action'            => apply_filters( 'friends_activity_friendship_accepted_action', sprintf( __( '%1$s and %2$s are now friends', 'buddypress' ), $initiator_link, $friend_link ), $friendship ),
    132228        'item_id'           => $friendship_id,
    133229        'secondary_item_id' => $friend_user_id
     
    138234        'user_id'           => $friend_user_id,
    139235        'type'              => 'friendship_created',
    140         'action'            => apply_filters( 'friends_activity_friendship_accepted_action', sprintf( __( '%1$s and %2$s are now friends', 'buddypress' ), $friend_link, $initiator_link ), $friendship ),
    141236        'item_id'           => $friendship_id,
    142237        'secondary_item_id' => $initiator_user_id,
Note: See TracChangeset for help on using the changeset viewer.