Skip to:
Content

BuddyPress.org


Ignore:
Timestamp:
03/28/2014 10:52:14 PM (12 years ago)
Author:
r-a-y
Message:

Blogs: Support post comment synchronization in the activity stream.

Previously, if a reply to a blog post was made in the activity stream,
the reply would only exist in the activity stream and not as a comment
for the blog post.

This commit:

  • Adds a blog comment whenever an activity reply is made under a blog post activity entry
  • Adds an activity comment to the blog post's activity entry whenever a blog comment is made
  • Checks to see if the blog post is open for comments (whether manually closed or due to age) (see r8189) to determine whether the activity item can be replied to
  • Handles content edit synchronization to either the post comment or the activity comment
  • Handles deletion synchronization to a degree

See #5130

File:
1 edited

Legend:

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

    r8189 r8190  
    433433    return $open;
    434434}
     435
     436/** POST COMMENT SYNCHRONIZATION ****************************************/
     437
     438/**
     439 * Syncs activity comments and posts them back as blog comments.
     440 *
     441 * Note: This is only a one-way sync - activity comments -> blog comment.
     442 *
     443 * For blog post -> activity comment, see {@link bp_blogs_record_comment()}.
     444 *
     445 * @since BuddyPress (2.0.0)
     446 *
     447 * @param int $comment_id The activity ID for the posted activity comment.
     448 * @param array $params Parameters for the activity comment.
     449 * @param object Parameters of the parent activity item (in this case, the blog post).
     450 */
     451function bp_blogs_sync_add_from_activity_comment( $comment_id, $params, $parent_activity ) {
     452    // if parent activity isn't a blog post, stop now!
     453    if ( $parent_activity->type != 'new_blog_post' ) {
     454        return;
     455    }
     456
     457    // if activity comments are disabled for blog posts, stop now!
     458    if ( bp_disable_blogforum_comments() ) {
     459        return;
     460    }
     461
     462    // get userdata
     463    if ( $params['user_id'] == bp_loggedin_user_id() ) {
     464        $user = buddypress()->loggedin_user->userdata;
     465    } else {
     466        $user = bp_core_get_core_userdata( $params['user_id'] );
     467    }
     468
     469    // see if a parent WP comment ID exists
     470    if ( ! empty( $params['parent_id'] ) ) {
     471        $comment_parent = bp_activity_get_meta( $params['parent_id'], 'bp_blogs_post_comment_id' );
     472    } else {
     473        $comment_parent = 0;
     474    }
     475
     476    // comment args
     477    $args = array(
     478        'comment_post_ID'      => $parent_activity->secondary_item_id,
     479        'comment_author'       => bp_core_get_user_displayname( $params['user_id'] ),
     480        'comment_author_email' => $user->user_email,
     481        'comment_author_url'   => bp_core_get_user_domain( $params['user_id'], $user->user_nicename, $user->user_login ),
     482        'comment_content'      => $params['content'],
     483        'comment_type'         => '', // could be interesting to add 'buddypress' here...
     484        'comment_parent'       => (int) $comment_parent,
     485        'user_id'              => $params['user_id'],
     486
     487        // commenting these out for now
     488        //'comment_author_IP'    => '127.0.0.1',
     489        //'comment_agent'        => '',
     490
     491        'comment_approved'     => 1
     492    );
     493
     494    // prevent separate activity entry being made
     495    remove_action( 'comment_post', 'bp_blogs_record_comment', 10, 2 );
     496
     497    // handle multisite
     498    switch_to_blog( $parent_activity->item_id );
     499
     500    // handle timestamps for the WP comment after we've switched to the blog
     501    $args['comment_date']     = current_time( 'mysql' );
     502    $args['comment_date_gmt'] = current_time( 'mysql', 1 );
     503
     504    // post the comment
     505    $post_comment_id = wp_insert_comment( $args );
     506
     507    // add meta to comment
     508    add_comment_meta( $post_comment_id, 'bp_activity_comment_id', $comment_id );
     509
     510    // add meta to activity comment
     511    bp_activity_update_meta( $comment_id, 'bp_blogs_post_comment_id', $post_comment_id );
     512
     513    // resave activity comment with WP comment permalink
     514    //
     515    // in bp_blogs_activity_comment_permalink(), we change activity comment
     516    // permalinks to use the post comment link
     517    //
     518    // @todo since this is done after AJAX posting, the activity comment permalink
     519    //       doesn't change on the frontend until the next page refresh.
     520    $resave_activity = new BP_Activity_Activity( $comment_id );
     521    $resave_activity->primary_link = get_comment_link( $post_comment_id );
     522    $resave_activity->save();
     523
     524    // multisite again!
     525    restore_current_blog();
     526
     527    // add the comment hook back
     528    add_action( 'comment_post', 'bp_blogs_record_comment', 10, 2 );
     529
     530    do_action( 'bp_blogs_sync_add_from_activity_comment', $comment_id, $args, $parent_activity, $user );
     531}
     532add_action( 'bp_activity_comment_posted', 'bp_blogs_sync_add_from_activity_comment', 10, 3 );
     533
     534/**
     535 * Deletes the blog comment when the associated activity comment is deleted.
     536 *
     537 * Note: This is hooked on the 'bp_activity_delete_comment_pre' filter instead
     538 * of the 'bp_activity_delete_comment' action because we need to fetch the
     539 * activity comment children before they are deleted.
     540 *
     541 * @since BuddyPress (2.0.0)
     542 *
     543 * @param bool $retval
     544 * @param int $parent_activity_id The parent activity ID for the activity comment.
     545 * @param int $activity_id The activity ID for the pending deleted activity comment.
     546 */
     547function bp_blogs_sync_delete_from_activity_comment( $retval, $parent_activity_id, $activity_id ) {
     548    // check if parent activity is a blog post
     549    $parent_activity = new BP_Activity_Activity( $parent_activity_id );
     550    if ( 'new_blog_post' != $parent_activity->type ) {
     551        return $retval;
     552    }
     553
     554    // fetch the activity comments for the activity item
     555    $activity = bp_activity_get( array(
     556        'in'               => $activity_id,
     557        'display_comments' => 'stream',
     558    ) );
     559
     560    // get all activity comment IDs for the pending deleted item
     561    $activity_ids   = bp_activity_recurse_comments_activity_ids( $activity );
     562    $activity_ids[] = $activity_id;
     563
     564    // handle multisite
     565    // switch to the blog where the comment was made
     566    switch_to_blog( $parent_activity->item_id );
     567
     568    // remove associated blog comments
     569    bp_blogs_remove_associated_blog_comments( $activity_ids, current_user_can( 'moderate_comments' ) );
     570
     571    // multisite again!
     572    restore_current_blog();
     573
     574    // rebuild activity comment tree
     575    // emulate bp_activity_delete_comment()
     576    BP_Activity_Activity::rebuild_activity_comment_tree( $parent_activity_id );
     577
     578    // we're overriding the default bp_activity_delete_comment() functionality
     579    // so we need to return false
     580    return false;
     581}
     582add_filter( 'bp_activity_delete_comment_pre', 'bp_blogs_sync_delete_from_activity_comment', 10, 3 );
     583
     584/**
     585 * Updates the blog comment when the associated activity comment is edited.
     586 *
     587 * @since BuddyPress (2.0.0)
     588 *
     589 * @param BP_Activity_Activity $activity The activity object.
     590 */
     591function bp_blogs_sync_activity_edit_to_post_comment( BP_Activity_Activity $activity ) {
     592    // not an activity comment? stop now!
     593    if ( 'activity_comment' !== $activity->type ) {
     594        return;
     595    }
     596
     597    // this is a new entry, so stop!
     598    // we only want edits!
     599    if ( empty( $activity->id ) ) {
     600        return;
     601    }
     602
     603    // prevent recursion
     604    remove_action( 'bp_activity_before_save', 'bp_blogs_sync_activity_edit_to_post_comment', 20 );
     605
     606    // Try to see if a corresponding blog comment exists
     607    $post_comment_id = bp_activity_get_meta( $activity->id, 'bp_blogs_post_comment_id' );
     608
     609    if ( empty( $post_comment_id ) ) {
     610        return;
     611    }
     612
     613    // fetch parent activity item
     614    $parent_activity = new BP_Activity_Activity( $activity->item_id );
     615
     616    // sanity check
     617    if ( 'new_blog_post' !== $parent_activity->type ) {
     618        return;
     619    }
     620
     621    // handle multisite
     622    switch_to_blog( $parent_activity->item_id );
     623
     624    // update the blog post comment
     625    wp_update_comment( array(
     626        'comment_ID'      => $post_comment_id,
     627        'comment_content' => $activity->content
     628    ) );
     629
     630    restore_current_blog();
     631}
     632add_action( 'bp_activity_before_save', 'bp_blogs_sync_activity_edit_to_post_comment', 20 );
     633
     634/**
     635 * When a post is trashed, remove each comment's associated activity meta.
     636 *
     637 * When a post is trashed and later untrashed, we currently don't reinstate
     638 * activity items for these comments since their activity entries are already
     639 * deleted when initially trashed.
     640 *
     641 * Since these activity entries are deleted, we need to remove the deleted
     642 * activity comment IDs from each comment's meta when a post is trashed.
     643 *
     644 * @since BuddyPress (2.0.0)
     645 *
     646 * @param int $post_id The post ID
     647 * @param array $statuses Array of comment statuses. The key is comment ID, the
     648 *        value is the $comment->comment_approved value.
     649 */
     650function bp_blogs_remove_activity_meta_for_trashed_comments( $post_id, $statuses ) {
     651    foreach ( $statuses as $comment_id => $comment_approved ) {
     652        delete_comment_meta( $comment_id, 'bp_activity_comment_id' );
     653    }
     654}
     655add_action( 'trashed_post_comments', 'bp_blogs_remove_activity_meta_for_trashed_comments', 10, 2 );
     656
     657/**
     658 * Utility function to set up some variables for use in the activity loop.
     659 *
     660 * Grabs the blog's comment depth and the post's open comment status options
     661 * for later use in the activity and activity comment loops.
     662 *
     663 * This is to prevent having to requery these items later on.
     664 *
     665 * @since BuddyPress (2.0.0)
     666 *
     667 * @see bp_blogs_disable_activity_commenting()
     668 * @see bp_blogs_setup_comment_loop_globals_on_ajax()
     669 *
     670 * @param object $activity The BP_Activity_Activity object
     671 */
     672function bp_blogs_setup_activity_loop_globals( $activity ) {
     673    if ( ! is_object( $activity ) ) {
     674        return;
     675    }
     676
     677    // parent not a blog post? stop now!
     678    if ( 'new_blog_post' !== $activity->type ) {
     679        return;
     680    }
     681
     682    if ( empty( $activity->id ) ) {
     683        return;
     684    }
     685
     686    // if we've already done this before, stop now!
     687    if ( isset( buddypress()->blogs->allow_comments[ $activity->id ] ) ) {
     688        return;
     689    }
     690
     691    $allow_comments = bp_blogs_comments_open( $activity );
     692    $thread_depth   = bp_blogs_get_blogmeta( $activity->item_id, 'thread_comments_depth' );
     693
     694    // initialize a local object so we won't have to query this again in the
     695    // comment loop
     696    if ( empty( buddypress()->blogs->allow_comments ) ) {
     697        buddypress()->blogs->allow_comments = array();
     698    }
     699    if ( empty( buddypress()->blogs->thread_depth ) ) {
     700        buddypress()->blogs->thread_depth   = array();
     701    }
     702
     703    // cache comment settings in the buddypress() singleton to reference later in
     704    // the activity comment loop
     705    // @see bp_blogs_disable_activity_replies()
     706    //
     707    // thread_depth is keyed by activity ID instead of blog ID because when we're
     708    // in a comment loop, we don't have access to the blog ID...
     709    // should probably object cache these values instead...
     710    buddypress()->blogs->allow_comments[ $activity->id ] = $allow_comments;
     711    buddypress()->blogs->thread_depth[ $activity->id ]   = $thread_depth;
     712}
     713
     714/**
     715 * Set up some globals used in the activity comment loop when AJAX is used.
     716 *
     717 * @since BuddyPress (2.0.0)
     718 *
     719 * @see bp_blogs_setup_activity_loop_globals()
     720 */
     721function bp_blogs_setup_comment_loop_globals_on_ajax() {
     722    // not AJAX? stop now!
     723    if ( ! defined( 'DOING_AJAX' ) ) {
     724        return;
     725    }
     726    if ( false === (bool) constant( 'DOING_AJAX' ) ) {
     727        return;
     728    }
     729
     730    // get the parent activity item
     731    $comment         = bp_activity_current_comment();
     732    $parent_activity = new BP_Activity_Activity( $comment->item_id );
     733
     734    // setup the globals
     735    bp_blogs_setup_activity_loop_globals( $parent_activity );
     736}
     737add_action( 'bp_before_activity_comment', 'bp_blogs_setup_comment_loop_globals_on_ajax' );
     738
     739/**
     740 * Disable activity commenting for blog posts based on certain criteria.
     741 *
     742 * If activity commenting is enabled for blog posts, we still need to disable
     743 * commenting if:
     744 *  - comments are disabled for the WP blog post from the admin dashboard
     745 *  - the WP blog post is supposed to be automatically closed from comments
     746 *    based on a certain age
     747 *  - the activity entry is a 'new_blog_comment' type
     748 *
     749 * @since BuddyPress (2.0.0)
     750 *
     751 * @param bool $retval Is activity commenting enabled for this activity entry?
     752 * @return bool
     753 */
     754function bp_blogs_disable_activity_commenting( $retval ) {
     755    // if activity commenting is disabled, return current value
     756    if ( bp_disable_blogforum_comments() ) {
     757        return $retval;
     758    }
     759
     760    // activity commenting is enabled for blog posts
     761    switch ( bp_get_activity_action_name() ) {
     762
     763        // we still have to disable activity commenting for 'new_blog_comment' items
     764        // commenting should only be done on the parent 'new_blog_post' item
     765        case 'new_blog_comment' :
     766            $retval = false;
     767
     768            break;
     769
     770        // check if commenting is disabled for the WP blog post
     771        // we should extrapolate this and automate this for plugins... or not
     772        case 'new_blog_post' :
     773            global $activities_template;
     774
     775            // setup some globals we'll need to reference later
     776            bp_blogs_setup_activity_loop_globals( $activities_template->activity );
     777
     778            // if comments are closed for the WP blog post, we should disable
     779            // activity comments for this activity entry
     780            if ( empty( buddypress()->blogs->allow_comments[bp_get_activity_id()] ) ) {
     781                $retval = false;
     782            }
     783
     784            break;
     785    }
     786
     787    return $retval;
     788}
     789add_filter( 'bp_activity_can_comment', 'bp_blogs_disable_activity_commenting' );
     790
     791/**
     792 * Check if an activity comment associated with a blog post can be replied to.
     793 *
     794 * By default, disables replying to activity comments if the corresponding WP
     795 * blog post no longer accepts comments.
     796 *
     797 * This check uses a locally-cached value set in {@link bp_blogs_disable_activity_commenting()}
     798 * via {@link bp_blogs_setup_activity_loop_globals()}.
     799 *
     800 * @since BuddyPress (2.0.0)
     801 *
     802 * @param bool $retval Are replies allowed for this activity reply?
     803 * @param object $comment The activity comment object
     804 * @return bool
     805 */
     806function bp_blogs_can_comment_reply( $retval, $comment ) {
     807    if ( is_array( $comment ) ) {
     808        $comment = (object) $comment;
     809    }
     810
     811    // check comment depth and disable if depth is too large
     812    if ( isset( buddypress()->blogs->thread_depth[$comment->item_id] ) ){
     813        if ( $comment->mptt_left > buddypress()->blogs->thread_depth[$comment->item_id] ) {
     814            $retval = false;
     815        }
     816    }
     817
     818    // check if we should disable activity replies based on the parent activity
     819    if ( isset( buddypress()->blogs->allow_comments[$comment->item_id] ) ){
     820        // the blog post has closed off commenting, so we should disable all activity
     821        // comments under the parent 'new_blog_post' activity entry
     822        if ( empty( buddypress()->blogs->allow_comments[$comment->item_id] ) ) {
     823            $retval = false;
     824        }
     825    }
     826
     827    return $retval;
     828}
     829add_filter( 'bp_activity_can_comment_reply', 'bp_blogs_can_comment_reply', 10, 2 );
     830
     831/**
     832 * Changes activity comment permalinks to use the blog comment permalink
     833 * instead of the activity permalink.
     834 *
     835 * This is only done if activity commenting is allowed and whether the parent
     836 * activity item is a 'new_blog_post' entry.
     837 *
     838 * @since BuddyPress (2.0.0)
     839 *
     840 * @param string $retval The activity comment permalink
     841 * @return string
     842 */
     843function bp_blogs_activity_comment_permalink( $retval ) {
     844    global $activities_template;
     845
     846    if ( isset( buddypress()->blogs->allow_comments[$activities_template->activity->current_comment->item_id] ) ){
     847        $retval = $activities_template->activity->current_comment->primary_link;
     848    }
     849
     850    return $retval;
     851}
     852add_filter( 'bp_get_activity_comment_permalink', 'bp_blogs_activity_comment_permalink' );
Note: See TracChangeset for help on using the changeset viewer.