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-activity/bp-activity-classes.php

    r8075 r8125  
    161161            $this->mptt_right        = $row->mptt_right;
    162162            $this->is_spam           = $row->is_spam;
     163        }
     164
     165        // Generate dynamic 'action' when possible
     166        $action = bp_activity_generate_action_string( $this );
     167        if ( false !== $action ) {
     168            $this->action = $action;
     169
     170        // If no callback is available, use the literal string from
     171        // the database row
     172        } else if ( ! empty( $row->action ) ) {
     173            $this->action = $row->action;
     174
     175        // Provide a fallback to avoid PHP notices
     176        } else {
     177            $this->action = '';
    163178        }
    164179    }
     
    443458            $activities = BP_Activity_Activity::append_comments( $activities, $spam );
    444459
     460        // Pre-fetch data associated with activity users and other objects
     461        BP_Activity_Activity::prefetch_object_data( $activities );
     462
     463        // Generate action strings
     464        $activities = BP_Activity_Activity::generate_action_strings( $activities );
     465
    445466        // If $max is set, only return up to the max results
    446467        if ( !empty( $max ) ) {
     
    540561                }
    541562            }
     563        }
     564
     565        return $activities;
     566    }
     567
     568    /**
     569     * Pre-fetch data for objects associated with activity items.
     570     *
     571     * Activity items are associated with users, and often with other
     572     * BuddyPress data objects. Here, we pre-fetch data about these
     573     * associated objects, so that inline lookups - done primarily when
     574     * building action strings - do not result in excess database queries.
     575     *
     576     * The only object data required for activity component activity types
     577     * (activity_update and activity_comment) is related to users, and that
     578     * info is fetched separately in BP_Activity_Activity::get_activity_data().
     579     * So this method contains nothing but a filter that allows other
     580     * components, such as bp-friends and bp-groups, to hook in and prime
     581     * their own caches at the beginning of an activity loop.
     582     *
     583     * @since BuddyPress (2.0.0)
     584     *
     585     * @param array $activities Array of activities.
     586     */
     587    protected static function prefetch_object_data( $activities ) {
     588        return apply_filters( 'bp_activity_prefetch_object_data', $activities );
     589    }
     590
     591    /**
     592     * Generate action strings for the activities located in BP_Activity_Activity::get().
     593     *
     594     * If no string can be dynamically generated for a given item
     595     * (typically because the activity type has not been properly
     596     * registered), the static 'action' value pulled from the database will
     597     * be left in place.
     598     *
     599     * @since BuddyPress (2.0.0)
     600     *
     601     * @param array $activities Array of activities.
     602     * @return array
     603     */
     604    protected static function generate_action_strings( $activities ) {
     605        foreach ( $activities as $key => $activity ) {
     606            $generated_action = bp_activity_generate_action_string( $activity );
     607            if ( false !== $generated_action ) {
     608                $activity->action = $generated_action;
     609            }
     610
     611            $activities[ $key ] = $activity;
    542612        }
    543613
Note: See TracChangeset for help on using the changeset viewer.