Skip to:
Content

BuddyPress.org


Ignore:
Timestamp:
12/18/2012 12:18:32 AM (12 years ago)
Author:
r-a-y
Message:

Only fire the activity save hooks once. Fixes #3980.

Previously, bp_activity_at_name_filter_updates() would run the
BP_Activity_Activity::save() method again. So basically, all activity save
hooks would run twice; this caused problems for plugins that hooked into
any activity save hook as their code would run twice.

This commit changes the logic of how @mention activity items are linked and
sent so the activity save hooks are only run once.

bp_activity_at_name_filter_updates() now runs before an activity item is
saved and detects if @mentions are found. If @mentions exists, we add a
hook to send the emails after the activity item is saved -
bp_activity_at_name_send_emails().

Hat-tip boonebgorges for feedback.

For a full list of changes, view:
https://buddypress.trac.wordpress.org/ticket/3980#comment:11

File:
1 edited

Legend:

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

    r6342 r6649  
    9090add_filter( 'group_forum_topic_text_before_save',    'bp_activity_at_name_filter' );
    9191add_filter( 'group_forum_post_text_before_save',     'bp_activity_at_name_filter' );
    92 add_filter( 'the_content',               'bp_activity_at_name_filter' );
     92add_filter( 'the_content',                           'bp_activity_at_name_filter' );
    9393
    9494add_filter( 'bp_get_activity_parent_content',        'bp_create_excerpt' );
     
    100100
    101101// At-name filter
    102 add_action( 'bp_activity_after_save', 'bp_activity_at_name_filter_updates' );
     102add_action( 'bp_activity_before_save', 'bp_activity_at_name_filter_updates' );
    103103
    104104// Activity stream moderation
     
    195195
    196196/**
    197  * Finds and links @-mentioned users in the contents of activity items
     197 * Finds and links @-mentioned users in the contents of a given item.
    198198 *
    199199 * @since BuddyPress (1.2)
    200200 *
    201  * @param string $content The activity content
    202  * @param int $activity_id The activity id
     201 * @param string $content The contents of a given item.
     202 * @param int $activity_id The activity id. Deprecated.
    203203 *
    204204 * @uses bp_activity_find_mentions()
    205  * @uses bp_is_username_compatibility_mode()
    206  * @uses bp_core_get_userid_from_nicename()
     205 * @uses bp_core_get_user_domain()
     206 *
     207 * @return string $content Content filtered for mentions
     208 */
     209function bp_activity_at_name_filter( $content, $activity_id = 0 ) {
     210
     211    // Try to find mentions
     212    $usernames = bp_activity_find_mentions( $content );
     213
     214    // No mentions? Stop now!
     215    if ( empty( $usernames ) )
     216        return $content;
     217
     218    // Linkify the mentions with the username
     219    foreach( (array) $usernames as $user_id => $username ) {
     220        $content = preg_replace( '/(@' . $username . '\b)/', "<a href='" . bp_core_get_user_domain( $user_id ) . "' rel='nofollow'>@$username</a>", $content );
     221    }
     222
     223    // Return the content
     224    return $content;
     225}
     226
     227/**
     228 * Catch mentions in activity items before they are saved into the database.
     229 *
     230 * If mentions are found, replace @mention text with user links and add our
     231 * hook to send mentions after the activity item is saved.
     232 *
     233 * @since BuddyPress (1.5)
     234 *
     235 * @param obj $activity
     236 *
     237 * @uses bp_activity_find_mentions()
     238 */
     239function bp_activity_at_name_filter_updates( $activity ) {
     240    // If activity was marked as spam, stop the rest of this function.
     241    if ( ! empty( $activity->is_spam ) )
     242        return;
     243
     244    // Try to find mentions
     245    $usernames = bp_activity_find_mentions( $activity->content );
     246
     247    // We have mentions!
     248    if ( ! empty( $usernames ) ) {
     249        // Replace @mention text with userlinks
     250        foreach( (array) $usernames as $user_id => $username ) {
     251            $activity->content = preg_replace( '/(@' . $username . '\b)/', "<a href='" . bp_core_get_user_domain( $user_id ) . "' rel='nofollow'>@$username</a>", $activity->content );
     252        }
     253
     254        // Add our hook to send @mention emails after the activity item is saved
     255        add_action( 'bp_activity_after_save', 'bp_activity_at_name_send_emails' );
     256
     257        // temporary variable to avoid having to run bp_activity_find_mentions() again
     258        buddypress()->activity->mentioned_users = $usernames;
     259    }
     260}
     261
     262/**
     263 * Sends emails and BP notifications for @-mentioned users in the contents of
     264 * an activity item.
     265 *
     266 * @since BuddyPress (1.7)
     267 *
     268 * @param obj $activity The BP_Activity_Activity object
     269 *
    207270 * @uses bp_activity_at_message_notification()
    208  * @uses bp_core_get_user_domain()
    209  * @uses bp_activity_adjust_mention_count()
    210  *
    211  * @return string $content Content filtered for mentions
    212  */
    213 function bp_activity_at_name_filter( $content, $activity_id = 0 ) {
    214     if ( $activity_id & bp_is_active( 'activity' ) ) {
    215         $activity = new BP_Activity_Activity( $activity_id );
    216 
    217         // If this activity has been marked as spam, don't do anything. This prevents @notifications being sent.
    218         if ( !empty( $activity ) && $activity->is_spam )
    219             return $content;
    220     }
    221 
    222     $usernames = bp_activity_find_mentions( $content );
    223     foreach( (array) $usernames as $username ) {
    224         if ( bp_is_username_compatibility_mode() )
    225             $user_id = username_exists( $username );
    226         else
    227             $user_id = bp_core_get_userid_from_nicename( $username );
    228 
    229         if ( empty( $user_id ) )
    230             continue;
    231 
    232         // If an activity_id is provided, we can send email and BP notifications
    233         if ( $activity_id && apply_filters( 'bp_activity_at_name_do_notifications', true ) ) {
    234             bp_activity_at_message_notification( $activity_id, $user_id );
     271 * @uses bp_activity_update_mention_count_for_user()
     272 */
     273function bp_activity_at_name_send_emails( $activity ) {
     274    // If our temporary variable doesn't exist, stop now.
     275    if ( empty( buddypress()->activity->mentioned_users ) )
     276        return;
     277
     278    // Grab our temporary variable from bp_activity_at_name_filter_updates()
     279    $usernames = buddypress()->activity->mentioned_users;
     280
     281    // Get rid of temporary variable
     282    unset( buddypress()->activity->mentioned_users );
     283
     284    // Send @mentions and setup BP notifications
     285    foreach( (array) $usernames as $user_id => $username ) {
     286        // If you want to disable notifications, you can use this filter to stop email sending
     287        if ( apply_filters( 'bp_activity_at_name_do_notifications', true, $usernames ) ) {
     288            bp_activity_at_message_notification( $activity->id, $user_id );
    235289        }
    236290
    237         $content = preg_replace( '/(@' . $username . '\b)/', "<a href='" . bp_core_get_user_domain( $user_id ) . "' rel='nofollow'>@$username</a>", $content );
    238     }
    239 
    240     // Adjust the activity count for this item
    241     if ( $activity_id )
    242         bp_activity_adjust_mention_count( $activity_id, 'add' );
    243 
    244     return $content;
    245 }
    246 
    247 /**
    248  * Catch mentions in saved activity items
    249  *
    250  * @since BuddyPress (1.5)
    251  *
    252  * @param obj $activity
    253  *
    254  * @uses remove_filter() To remove the 'bp_activity_at_name_filter_updates' hook.
    255  * @uses bp_activity_at_name_filter()
    256  * @uses BP_Activity_Activity::save() {@link BP_Activity_Activity}
    257  */
    258 function bp_activity_at_name_filter_updates( $activity ) {
    259     // Only run this function once for a given activity item
    260     remove_filter( 'bp_activity_after_save', 'bp_activity_at_name_filter_updates' );
    261 
    262     // Run the content through the linking filter, making sure to increment mention count
    263     $activity->content = bp_activity_at_name_filter( $activity->content, $activity->id );
    264 
    265     // Resave the activity with the new content
    266     $activity->save();
     291        // Updates mention count for the user
     292        bp_activity_update_mention_count_for_user( $user_id, $activity->id );
     293    }
    267294}
    268295
Note: See TracChangeset for help on using the changeset viewer.