/** * Constructor. * * @since 1.6.0 */ public function __construct() { // See if activity commenting is enabled for blog / forum activity items. $this->disable_blogforum_comments = bp_disable_blogforum_comments(); // Define singular and plural labels, as well as whether we support AJAX. parent::__construct(array('ajax' => false, 'plural' => 'activities', 'singular' => 'activity', 'screen' => get_current_screen())); }
/** * Allow activity comments on blog posts and forum posts * * @since BuddyPress (1.6) */ function bp_admin_setting_callback_blogforum_comments() { ?> <input id="bp-disable-blogforum-comments" name="bp-disable-blogforum-comments" type="checkbox" value="1" <?php checked( !bp_disable_blogforum_comments( false ) ); ?> /> <label for="bp-disable-blogforum-comments"><?php _e( 'Allow activity stream commenting on blog and forum posts', 'buddypress' ); ?></label> <?php }
/** * Disable activity commenting for blog posts based on certain criteria. * * If activity commenting is enabled for blog posts, we still need to disable * commenting if: * - comments are disabled for the WP blog post from the admin dashboard * - the WP blog post is supposed to be automatically closed from comments * based on a certain age * - the activity entry is a 'new_blog_comment' type * * @since BuddyPress (2.0.0) * * @param bool $retval Is activity commenting enabled for this activity entry? * @return bool */ function bp_blogs_disable_activity_commenting( $retval ) { // if activity commenting is disabled, return current value if ( bp_disable_blogforum_comments() ) { return $retval; } // activity commenting is enabled for blog posts switch ( bp_get_activity_action_name() ) { // we still have to disable activity commenting for 'new_blog_comment' items // commenting should only be done on the parent 'new_blog_post' item case 'new_blog_comment' : $retval = false; break; // check if commenting is disabled for the WP blog post // we should extrapolate this and automate this for plugins... or not case 'new_blog_post' : global $activities_template; // setup some globals we'll need to reference later bp_blogs_setup_activity_loop_globals( $activities_template->activity ); // if comments are closed for the WP blog post, we should disable // activity comments for this activity entry if ( empty( buddypress()->blogs->allow_comments[bp_get_activity_id()] ) ) { $retval = false; } break; } return $retval; }
/** * Formats single activity comment entries to use the blog comment action. * * This is only done if the activity comment is associated with a blog comment. * * @since 2.0.1 * * @param string $retval The activity action. * @param BP_Activity_Activity $activity Activity object. * @return string */ function bp_blogs_activity_comment_single_action($retval, $activity) { if ('activity_comment' !== $activity->type) { return $retval; } if (bp_disable_blogforum_comments()) { return $retval; } $parent_activity = new BP_Activity_Activity($activity->item_id); if (!isset($parent_activity->type)) { return $retval; } $post_type = bp_activity_post_type_get_tracking_arg($parent_activity->type, 'post_type'); if (!$post_type) { return $retval; } $blog_comment_id = bp_activity_get_meta($activity->id, "bp_blogs_{$post_type}_comment_id"); if (!empty($blog_comment_id)) { $bp = buddypress(); // Check if a comment action id is set for the parent activity $comment_action_id = bp_activity_post_type_get_tracking_arg($parent_activity->type, 'comment_action_id'); // Use the action string callback for the activity type if (!empty($comment_action_id)) { // Fake a 'new_{post_type}_comment' by cloning the activity object. $object = clone $activity; // Set the type of the activity to be a comment about a post type $object->type = $comment_action_id; // Use the blog ID as the item_id. $object->item_id = $parent_activity->item_id; // Use comment ID as the secondary_item_id. $object->secondary_item_id = $blog_comment_id; // Get the format callback for this activity comment $format_callback = bp_activity_post_type_get_tracking_arg($comment_action_id, 'format_callback'); // now format the activity action using the 'new_{post_type}_comment' action callback if (is_callable($format_callback)) { $retval = call_user_func_array($format_callback, array('', $object)); } } } return $retval; }
/** * Remove an activity item when a comment about a post type is deleted. * * @since 2.5.0 * * @param int $comment_id ID of the comment. * @param object $activity_post_object The post type tracking args object. * * @return bool True on success. False on error. */ function bp_activity_post_type_remove_comment($comment_id = 0, $activity_post_object = null) { if (empty($activity_post_object)) { $comment = get_comment($comment_id); if (!$comment) { return; } $post_type = get_post_type($comment->comment_post_ID); if (!$post_type) { return; } // Get the post type tracking args. $activity_post_object = bp_activity_get_post_type_tracking_args($post_type); // Bail if the activity type does not exist if (empty($activity_post_object->comments_tracking->action_id)) { return false; } } // Set the $activity_comment_object $activity_comment_object = $activity_post_object->comments_tracking; if (empty($activity_comment_object->action_id)) { return false; } $deleted = false; if (bp_disable_blogforum_comments()) { $deleted = bp_activity_delete_by_item_id(array('item_id' => get_current_blog_id(), 'secondary_item_id' => $comment_id, 'component' => $activity_comment_object->component_id, 'type' => $activity_comment_object->action_id, 'user_id' => false)); } /** * Fires after the custom post type comment activity was removed. * * @since 2.5.0 * * @param bool $deleted True if the activity was deleted false otherwise * @param WP_Comment $comment Comment object. * @param object $activity_post_object The post type tracking args object. * @param string $value The post type comment activity type. */ do_action('bp_activity_post_type_remove_comment', $deleted, $comment_id, $activity_post_object, $activity_comment_object->action_id); return $deleted; }
/** * When a blog comment status transition occurs, update the relevant activity's status. * * @since BuddyPress (1.6.0) * * @global object $bp BuddyPress global settings. * * @param string $new_status New comment status. * @param string $old_status Previous comment status. * @param object $comment Comment data. */ function bp_blogs_transition_activity_status($new_status, $old_status, $comment) { global $bp; // Check the Activity component is active if (!bp_is_active('activity')) { return; } /** * Activity currently doesn't have any concept of a trash, or an unapproved/approved state. * * If a blog comment transitions to a "delete" or "hold" status, delete the activity item. * If a blog comment transitions to trashed, or spammed, mark the activity as spam. * If a blog comment transitions to approved (and the activity exists), mark the activity as ham. * If a blog comment transitions to unapproved (and the activity exists), mark the activity as spam. * Otherwise, record the comment into the activity stream. */ // This clause was moved in from bp_blogs_remove_comment() in BuddyPress 1.6. It handles delete/hold. if (in_array($new_status, array('delete', 'hold'))) { return bp_blogs_remove_comment($comment->comment_ID); // These clauses handle trash, spam, and un-spams. } elseif (in_array($new_status, array('trash', 'spam', 'unapproved'))) { $action = 'spam_activity'; } elseif ('approved' == $new_status) { $action = 'ham_activity'; } // Get the activity if (bp_disable_blogforum_comments()) { $activity_id = bp_activity_get_activity_id(array('component' => $bp->blogs->id, 'item_id' => get_current_blog_id(), 'secondary_item_id' => $comment->comment_ID, 'type' => 'new_blog_comment')); } else { $activity_id = get_comment_meta($comment->comment_ID, 'bp_activity_comment_id', true); } // Check activity item exists if (empty($activity_id)) { // If no activity exists, but the comment has been approved, record it into the activity table. if ('approved' == $new_status) { return bp_blogs_record_comment($comment->comment_ID, true); } return; } // Create an activity object $activity = new BP_Activity_Activity($activity_id); if (empty($activity->component)) { return; } // Spam/ham the activity if it's not already in that state if ('spam_activity' == $action && !$activity->is_spam) { bp_activity_mark_as_spam($activity); } elseif ('ham_activity' == $action) { bp_activity_mark_as_ham($activity); } // Add "new_blog_comment" to the whitelisted activity types, so that the activity's Akismet history is generated $comment_akismet_history = create_function('$t', '$t[] = "new_blog_comment"; return $t;'); add_filter('bp_akismet_get_activity_types', $comment_akismet_history); // Save the updated activity $activity->save(); // Remove the "new_blog_comment" activity type whitelist so we don't break anything remove_filter('bp_akismet_get_activity_types', $comment_akismet_history); }
/** * Add a notification for post comments to the post author or post commenter. * * Requires "activity stream commenting on blog and forum posts" to be enabled. * * @since 2.6.0 * * @param int $activity_id The activity comment ID. * @param WP_Comment $post_type_comment WP Comment object. * @param array $activity_args Activity comment arguments. * @param object $activity_post_object The post type tracking args object. */ function bp_activity_add_notification_for_synced_blog_comment($activity_id, $post_type_comment, $activity_args, $activity_post_object) { // If activity comments are disabled for WP posts, stop now! if (bp_disable_blogforum_comments() || empty($activity_id)) { return; } // Send a notification to the blog post author. if ((int) $post_type_comment->post->post_author !== (int) $activity_args['user_id']) { // Only add a notification if comment author is a registered user. // @todo Should we remove this restriction? if (!empty($post_type_comment->user_id)) { bp_notifications_add_notification(array('user_id' => $post_type_comment->post->post_author, 'item_id' => $activity_id, 'secondary_item_id' => $post_type_comment->user_id, 'component_name' => buddypress()->activity->id, 'component_action' => 'update_reply', 'date_notified' => $post_type_comment->comment_date_gmt, 'is_new' => 1)); } } // Send a notification to the parent comment author for follow-up comments. if (!empty($post_type_comment->comment_parent)) { $parent_comment = get_comment($post_type_comment->comment_parent); if (!empty($parent_comment->user_id) && (int) $parent_comment->user_id !== (int) $activity_args['user_id']) { bp_notifications_add_notification(array('user_id' => $parent_comment->user_id, 'item_id' => $activity_id, 'secondary_item_id' => $post_type_comment->user_id, 'component_name' => buddypress()->activity->id, 'component_action' => 'comment_reply', 'date_notified' => $post_type_comment->comment_date_gmt, 'is_new' => 1)); } } }
/** * When a post type comment status transition occurs, update the relevant activity's status. * * @since 2.5.0 * * @param string $new_status New comment status. * @param string $old_status Previous comment status. * @param WP_Comment $comment Comment data. */ function bp_activity_transition_post_type_comment_status($new_status, $old_status, $comment) { $post_type = get_post_type($comment->comment_post_ID); if (!$post_type) { return; } // Get the post type tracking args. $activity_post_object = bp_activity_get_post_type_tracking_args($post_type); // Bail if the activity type does not exist if (empty($activity_post_object->comments_tracking->action_id)) { return false; // Set the $activity_comment_object } else { $activity_comment_object = $activity_post_object->comments_tracking; } // Init an empty activity ID $activity_id = 0; /** * Activity currently doesn't have any concept of a trash, or an unapproved/approved state. * * If a blog comment transitions to a "delete" or "hold" status, delete the activity item. * If a blog comment transitions to trashed, or spammed, mark the activity as spam. * If a blog comment transitions to approved (and the activity exists), mark the activity as ham. * If a blog comment transitions to unapproved (and the activity exists), mark the activity as spam. * Otherwise, record the comment into the activity stream. */ // This clause handles delete/hold. if (in_array($new_status, array('delete', 'hold'))) { return bp_activity_post_type_remove_comment($comment->comment_ID, $activity_post_object); // These clauses handle trash, spam, and un-spams. } elseif (in_array($new_status, array('trash', 'spam', 'unapproved'))) { $action = 'spam_activity'; } elseif ('approved' == $new_status) { $action = 'ham_activity'; } // Get the activity if (bp_disable_blogforum_comments()) { $activity_id = bp_activity_get_activity_id(array('component' => $activity_comment_object->component_id, 'item_id' => get_current_blog_id(), 'secondary_item_id' => $comment->comment_ID, 'type' => $activity_comment_object->action_id)); } else { $activity_id = get_comment_meta($comment->comment_ID, 'bp_activity_comment_id', true); } /** * Leave a chance to plugins to manage activity comments differently. * * @since 2.5.0 * * @param bool $value True to override BuddyPress management. * @param string $post_type The post type name. * @param int $activity_id The post type activity (0 if not found). * @param string $new_status The new status of the post type comment. * @param string $old_status The old status of the post type comment. * @param WP_Comment $comment Comment data. */ if (true === apply_filters('bp_activity_pre_transition_post_type_comment_status', false, $post_type, $activity_id, $new_status, $old_status, $comment)) { return false; } // Check activity item exists if (empty($activity_id)) { // If no activity exists, but the comment has been approved, record it into the activity table. if ('approved' == $new_status) { return bp_activity_post_type_comment($comment->comment_ID, true, $activity_post_object); } return; } // Create an activity object $activity = new BP_Activity_Activity($activity_id); if (empty($activity->component)) { return; } // Spam/ham the activity if it's not already in that state if ('spam_activity' === $action && !$activity->is_spam) { bp_activity_mark_as_spam($activity); } elseif ('ham_activity' == $action) { bp_activity_mark_as_ham($activity); } // Add "new_post_type_comment" to the whitelisted activity types, so that the activity's Akismet history is generated $post_type_comment_action = $activity_comment_object->action_id; $comment_akismet_history = create_function('$t', '$t[] = $post_type_comment_action; return $t;'); add_filter('bp_akismet_get_activity_types', $comment_akismet_history); // Make sure the activity change won't edit the comment if sync is on remove_action('bp_activity_before_save', 'bp_blogs_sync_activity_edit_to_post_comment', 20); // Save the updated activity $activity->save(); // Restore the action add_action('bp_activity_before_save', 'bp_blogs_sync_activity_edit_to_post_comment', 20); // Remove the "new_blog_comment" activity type whitelist so we don't break anything remove_filter('bp_akismet_get_activity_types', $comment_akismet_history); }
/** * Remove a synced activity comment from the activity stream. * * @since 2.5.0 * * @param bool $deleted True when a comment post type activity was successfully removed. * @param int $comment_id ID of the comment to be removed. * @param object $activity_post_object The post type tracking args object. * @param string $activity_type The post type comment activity type. * * @return bool True on success. False on error. */ function bp_blogs_post_type_remove_comment($deleted, $comment_id, $activity_post_object, $activity_type = '') { // Remove synced activity comments, if needed. if (!bp_disable_blogforum_comments()) { // Get associated activity ID from comment meta $activity_id = get_comment_meta($comment_id, 'bp_activity_comment_id', true); /** * Delete the associated activity comment & also remove * child post comments and associated activity comments. */ if (!empty($activity_id)) { // fetch the activity comments for the activity item $activity = bp_activity_get(array('in' => $activity_id, 'display_comments' => 'stream', 'spam' => 'all')); // get all activity comment IDs for the pending deleted item if (!empty($activity['activities'])) { $activity_ids = bp_activity_recurse_comments_activity_ids($activity); $activity_ids[] = $activity_id; // delete activity items foreach ($activity_ids as $activity_id) { bp_activity_delete(array('id' => $activity_id)); } // remove associated blog comments bp_blogs_remove_associated_blog_comments($activity_ids); // rebuild activity comment tree BP_Activity_Activity::rebuild_activity_comment_tree($activity['activities'][0]->item_id); // Set the result $deleted = true; } } } // Backcompat for comments about the 'post' post type. if ('new_blog_comment' === $activity_type) { /** * Fires after a blog comment activity item was removed from activity stream. * * @since 1.0.0 * * @param int $value ID for the blog associated with the removed comment. * @param int $comment_id ID of the comment being removed. * @param int $value ID of the current logged in user. */ do_action('bp_blogs_remove_comment', get_current_blog_id(), $comment_id, bp_loggedin_user_id()); } return $deleted; }