' );
$has_audio = ! empty( $media['has']['audio'] ) && $media['has']['audio'];
$has_videos = ! empty( $media['has']['videos'] ) && $media['has']['videos'];
$has_feat_image = ! empty( $media['has']['featured_images'] ) && $media['has']['featured_images'];
$has_galleries = ! empty( $media['has']['galleries'] ) && $media['has']['galleries'];
$has_images = ! empty( $media['has']['images'] ) && $media['has']['images'];
$has_embeds = false;
// Embeds must be subtracted from the paragraph count.
if ( ! empty( $media['has']['embeds'] ) ) {
$has_embeds = $media['has']['embeds'] > 0;
$para_count -= $media['has']['embeds'];
}
$extracted_media = array();
$use_media_type = '';
$image_source = '';
// If it's a short article and there's an embed/audio/video, use it.
if ( $para_count <= 3 ) {
if ( $has_embeds ) {
$use_media_type = 'embeds';
} elseif ( $has_audio ) {
$use_media_type = 'audio';
} elseif ( $has_videos ) {
$use_media_type = 'videos';
}
}
// If not, or in any other situation, try to use an image.
if ( ! $use_media_type && $has_images ) {
$use_media_type = 'images';
$image_source = 'html';
// Featured Image > Galleries > inline .
if ( $has_feat_image ) {
$image_source = 'featured_images';
} elseif ( $has_galleries ) {
$image_source = 'galleries';
}
}
// Extract an item from the $media results.
if ( $use_media_type ) {
if ( $use_media_type === 'images' ) {
$extracted_media = wp_list_filter( $media[ $use_media_type ], array( 'source' => $image_source ) );
$extracted_media = array_shift( $extracted_media );
} else {
$extracted_media = array_shift( $media[ $use_media_type ] );
}
/**
* Filter the results of the media extractor when creating an Activity summary.
*
* @since 2.3.0
*
* @param array $extracted_media Extracted media item. See {@link BP_Media_Extractor::extract()} for format.
* @param string $content Content of the activity item.
* @param array $activity The data passed to bp_activity_add() or the values from an Activity obj.
* @param array $media All results from the media extraction.
* See {@link BP_Media_Extractor::extract()} for format.
* @param string $use_media_type The kind of media item that was preferentially extracted.
* @param string $image_source If $use_media_type was "images", the preferential source of the image.
* Otherwise empty.
*/
$extracted_media = apply_filters(
'bp_activity_create_summary_extractor_result',
$extracted_media,
$content,
$activity,
$media,
$use_media_type,
$image_source
);
}
// Generate a text excerpt for this activity item (and remove any oEmbeds URLs).
$summary_parts = array(
str_replace(
array( "\n", "\r" ),
' ',
trim( bp_create_excerpt( html_entity_decode( $content ), 225, $bp_excerpt_args ) )
),
);
if ( $use_media_type === 'embeds' ) {
$summary_parts[] = PHP_EOL . PHP_EOL . $extracted_media['url'];
} elseif ( $use_media_type === 'images' ) {
$extracted_media_url = isset( $extracted_media['url'] ) ? $extracted_media['url'] : '';
$image_tag = sprintf( '
', esc_url( $extracted_media_url ) );
if ( $post_url ) {
$image_tag = sprintf( '%2$s ', esc_url( $post_url ), trim( $image_tag ) );
array_unshift( $summary_parts, $image_tag );
}
} elseif ( in_array( $use_media_type, array( 'audio', 'videos' ), true ) ) {
$summary_parts[] = PHP_EOL . PHP_EOL . $extracted_media['original']; // Full shortcode.
}
if ( $post_title ) {
array_unshift( $summary_parts, $post_title );
}
// Join summary parts.
$summary = implode( '', $summary_parts );
/**
* Filters the newly-generated summary for the activity item.
*
* @since 2.3.0
*
* @param string $summary Activity summary HTML.
* @param string $content Content of the activity item.
* @param array $activity The data passed to bp_activity_add() or the values from an Activity obj.
* @param array $extracted_media Media item extracted. See {@link BP_Media_Extractor::extract()} for format.
*/
return apply_filters( 'bp_activity_create_summary', $summary, $content, $activity, $extracted_media );
}
/**
* Fetch whether the current user is allowed to mark items as spam.
*
* @since 1.6.0
*
* @return bool True if user is allowed to mark activity items as spam.
*/
function bp_activity_user_can_mark_spam() {
/**
* Filters whether the current user should be able to mark items as spam.
*
* @since 1.6.0
*
* @param bool $moderate Whether or not the current user has bp_moderate capability.
*/
return apply_filters( 'bp_activity_user_can_mark_spam', bp_current_user_can( 'bp_moderate' ) );
}
/**
* Mark an activity item as spam.
*
* @since 1.6.0
*
* @todo We should probably save $source to activity meta.
*
* @param BP_Activity_Activity $activity The activity item to be spammed.
* @param string $source Optional. Default is "by_a_person" (ie, a person has
* manually marked the activity as spam). BP core also
* accepts 'by_akismet'.
*/
function bp_activity_mark_as_spam( &$activity, $source = 'by_a_person' ) {
$bp = buddypress();
$activity->is_spam = 1;
// Clear the activity stream first page cache.
wp_cache_delete( 'bp_activity_sitewide_front', 'bp' );
if ( 'activity_comment' === $activity->type ) {
$activity_id = $activity->item_id;
} else {
$activity_id = $activity->id;
}
// Clear the activity comment cache for this activity item.
wp_cache_delete( $activity_id, 'bp_activity_comments' );
// If Akismet is active, and this was a manual spam/ham request, stop Akismet checking the activity.
if ( 'by_a_person' == $source && !empty( $bp->activity->akismet ) ) {
remove_action( 'bp_activity_before_save', array( $bp->activity->akismet, 'check_activity' ), 4 );
// Build data package for Akismet.
$activity_data = BP_Akismet::build_akismet_data_package( $activity );
// Tell Akismet this is spam.
$activity_data = $bp->activity->akismet->send_akismet_request( $activity_data, 'submit', 'spam' );
// Update meta.
add_action( 'bp_activity_after_save', array( $bp->activity->akismet, 'update_activity_spam_meta' ), 1, 1 );
}
/**
* Fires at the end of the process to mark an activity item as spam.
*
* @since 1.6.0
*
* @param BP_Activity_Activity $activity Activity item being marked as spam.
* @param string $source Source of determination of spam status. For example
* "by_a_person" or "by_akismet".
*/
do_action( 'bp_activity_mark_as_spam', $activity, $source );
}
/**
* Mark an activity item as ham.
*
* @since 1.6.0
*
* @param BP_Activity_Activity $activity The activity item to be hammed. Passed by reference.
* @param string $source Optional. Default is "by_a_person" (ie, a person has
* manually marked the activity as spam). BP core also accepts
* 'by_akismet'.
*/
function bp_activity_mark_as_ham( &$activity, $source = 'by_a_person' ) {
$bp = buddypress();
$activity->is_spam = 0;
// Clear the activity stream first page cache.
wp_cache_delete( 'bp_activity_sitewide_front', 'bp' );
if ( 'activity_comment' === $activity->type ) {
$activity_id = $activity->item_id;
} else {
$activity_id = $activity->id;
}
// Clear the activity comment cache for this activity item.
wp_cache_delete( $activity_id, 'bp_activity_comments' );
// If Akismet is active, and this was a manual spam/ham request, stop Akismet checking the activity.
if ( 'by_a_person' == $source && !empty( $bp->activity->akismet ) ) {
remove_action( 'bp_activity_before_save', array( $bp->activity->akismet, 'check_activity' ), 4 );
// Build data package for Akismet.
$activity_data = BP_Akismet::build_akismet_data_package( $activity );
// Tell Akismet this is spam.
$activity_data = $bp->activity->akismet->send_akismet_request( $activity_data, 'submit', 'ham' );
// Update meta.
add_action( 'bp_activity_after_save', array( $bp->activity->akismet, 'update_activity_ham_meta' ), 1, 1 );
}
/**
* Fires at the end of the process to mark an activity item as ham.
*
* @since 1.6.0
*
* @param BP_Activity_Activity $activity Activity item being marked as ham.
* @param string $source Source of determination of ham status. For example
* "by_a_person" or "by_akismet".
*/
do_action( 'bp_activity_mark_as_ham', $activity, $source );
}
/* Emails *********************************************************************/
/**
* Send email and BP notifications when a user is mentioned in an update.
*
* @since 1.2.0
*
* @param int $activity_id The ID of the activity update.
* @param int $receiver_user_id The ID of the user who is receiving the update.
*/
function bp_activity_at_message_notification( $activity_id, $receiver_user_id ) {
$notifications = BP_Core_Notification::get_all_for_user( $receiver_user_id, 'all' );
// Don't leave multiple notifications for the same activity item.
foreach ( $notifications as $notification ) {
if ( $activity_id == $notification->item_id ) {
return;
}
}
$activity = new BP_Activity_Activity( $activity_id );
$email_type = 'activity-at-message';
$group_name = '';
$message_link = bp_activity_get_permalink( $activity_id );
$poster_name = bp_core_get_user_displayname( $activity->user_id );
remove_filter( 'bp_get_activity_content_body', 'convert_smilies' );
remove_filter( 'bp_get_activity_content_body', 'wpautop' );
remove_filter( 'bp_get_activity_content_body', 'bp_activity_truncate_entry', 5 );
/** This filter is documented in bp-activity/bp-activity-template.php */
$content = apply_filters_ref_array( 'bp_get_activity_content_body', array( $activity->content, &$activity ) );
add_filter( 'bp_get_activity_content_body', 'convert_smilies' );
add_filter( 'bp_get_activity_content_body', 'wpautop' );
add_filter( 'bp_get_activity_content_body', 'bp_activity_truncate_entry', 5 );
// Now email the user with the contents of the message (if they have enabled email notifications).
if ( 'no' != bp_get_user_meta( $receiver_user_id, 'notification_activity_new_mention', true ) ) {
if ( bp_is_active( 'groups' ) && bp_is_group() ) {
$email_type = 'groups-at-message';
$group_name = bp_get_current_group_name();
}
$unsubscribe_args = array(
'user_id' => $receiver_user_id,
'notification_type' => $email_type,
);
$args = array(
'tokens' => array(
'activity' => $activity,
'usermessage' => wp_strip_all_tags( $content ),
'group.name' => $group_name,
'mentioned.url' => $message_link,
'poster.name' => $poster_name,
'receiver-user.id' => $receiver_user_id,
'unsubscribe' => esc_url( bp_email_get_unsubscribe_link( $unsubscribe_args ) ),
),
);
bp_send_email( $email_type, $receiver_user_id, $args );
}
/**
* Fires after the sending of an @mention email notification.
*
* @since 1.5.0
* @since 2.5.0 $subject, $message, $content arguments unset and deprecated.
*
* @param BP_Activity_Activity $activity Activity Item object.
* @param string $deprecated Removed in 2.5; now an empty string.
* @param string $deprecated Removed in 2.5; now an empty string.
* @param string $deprecated Removed in 2.5; now an empty string.
* @param int $receiver_user_id The ID of the user who is receiving the update.
*/
do_action( 'bp_activity_sent_mention_email', $activity, '', '', '', $receiver_user_id );
}
/**
* Send email and BP notifications when an activity item receives a comment.
*
* @since 1.2.0
* @since 2.5.0 Updated to use new email APIs.
*
* @param int $comment_id The comment id.
* @param int $commenter_id The ID of the user who posted the comment.
* @param array $params {@link bp_activity_new_comment()}.
*/
function bp_activity_new_comment_notification( $comment_id = 0, $commenter_id = 0, $params = array() ) {
$original_activity = new BP_Activity_Activity( $params['activity_id'] );
$poster_name = bp_core_get_user_displayname( $commenter_id );
$thread_link = bp_activity_get_permalink( $params['activity_id'] );
remove_filter( 'bp_get_activity_content_body', 'convert_smilies' );
remove_filter( 'bp_get_activity_content_body', 'wpautop' );
remove_filter( 'bp_get_activity_content_body', 'bp_activity_truncate_entry', 5 );
/** This filter is documented in bp-activity/bp-activity-template.php */
$content = apply_filters_ref_array( 'bp_get_activity_content_body', array( $params['content'], &$original_activity ) );
add_filter( 'bp_get_activity_content_body', 'convert_smilies' );
add_filter( 'bp_get_activity_content_body', 'wpautop' );
add_filter( 'bp_get_activity_content_body', 'bp_activity_truncate_entry', 5 );
if ( $original_activity->user_id != $commenter_id ) {
// Send an email if the user hasn't opted-out.
if ( 'no' != bp_get_user_meta( $original_activity->user_id, 'notification_activity_new_reply', true ) ) {
$unsubscribe_args = array(
'user_id' => $original_activity->user_id,
'notification_type' => 'activity-comment',
);
$args = array(
'tokens' => array(
'comment.id' => $comment_id,
'commenter.id' => $commenter_id,
'usermessage' => wp_strip_all_tags( $content ),
'original_activity.user_id' => $original_activity->user_id,
'poster.name' => $poster_name,
'thread.url' => esc_url( $thread_link ),
'unsubscribe' => esc_url( bp_email_get_unsubscribe_link( $unsubscribe_args ) ),
),
);
bp_send_email( 'activity-comment', $original_activity->user_id, $args );
}
/**
* Fires at the point that notifications should be sent for activity comments.
*
* @since 2.6.0
*
* @param BP_Activity_Activity $original_activity The original activity.
* @param int $comment_id ID for the newly received comment.
* @param int $commenter_id ID of the user who made the comment.
* @param array $params Arguments used with the original activity comment.
*/
do_action( 'bp_activity_sent_reply_to_update_notification', $original_activity, $comment_id, $commenter_id, $params );
}
/*
* If this is a reply to another comment, send an email notification to the
* author of the immediate parent comment.
*/
if ( empty( $params['parent_id'] ) || ( $params['activity_id'] == $params['parent_id'] ) ) {
return;
}
$parent_comment = new BP_Activity_Activity( $params['parent_id'] );
if ( $parent_comment->user_id != $commenter_id && $original_activity->user_id != $parent_comment->user_id ) {
// Send an email if the user hasn't opted-out.
if ( 'no' != bp_get_user_meta( $parent_comment->user_id, 'notification_activity_new_reply', true ) ) {
$unsubscribe_args = array(
'user_id' => $parent_comment->user_id,
'notification_type' => 'activity-comment-author',
);
$args = array(
'tokens' => array(
'comment.id' => $comment_id,
'commenter.id' => $commenter_id,
'usermessage' => wp_strip_all_tags( $content ),
'parent-comment-user.id' => $parent_comment->user_id,
'poster.name' => $poster_name,
'thread.url' => esc_url( $thread_link ),
'unsubscribe' => esc_url( bp_email_get_unsubscribe_link( $unsubscribe_args ) ),
),
);
bp_send_email( 'activity-comment-author', $parent_comment->user_id, $args );
}
/**
* Fires at the point that notifications should be sent for comments on activity replies.
*
* @since 2.6.0
*
* @param BP_Activity_Activity $parent_comment The parent activity.
* @param int $comment_id ID for the newly received comment.
* @param int $commenter_id ID of the user who made the comment.
* @param array $params Arguments used with the original activity comment.
*/
do_action( 'bp_activity_sent_reply_to_reply_notification', $parent_comment, $comment_id, $commenter_id, $params );
}
}
/**
* Helper method to map action arguments to function parameters.
*
* @since 1.9.0
*
* @param int $comment_id ID of the comment being notified about.
* @param array $params Parameters to use with notification.
*/
function bp_activity_new_comment_notification_helper( $comment_id, $params ) {
bp_activity_new_comment_notification( $comment_id, $params['user_id'], $params );
}
add_action( 'bp_activity_comment_posted', 'bp_activity_new_comment_notification_helper', 10, 2 );
/** Embeds *******************************************************************/
/**
* Set up activity oEmbed cache during the activity loop.
*
* During an activity loop, this function sets up the hooks necessary to grab
* each item's embeds from the cache, or put them in the cache if they are
* not there yet.
*
* This does not cover recursive activity comments, as they do not use a real loop.
* For that, see {@link bp_activity_comment_embed()}.
*
* @since 1.5.0
*
* @see BP_Embed
* @see bp_embed_activity_cache()
* @see bp_embed_activity_save_cache()
*
*/
function bp_activity_embed() {
add_filter( 'embed_post_id', 'bp_get_activity_id' );
add_filter( 'oembed_dataparse', 'bp_activity_oembed_dataparse', 10, 2 );
add_filter( 'bp_embed_get_cache', 'bp_embed_activity_cache', 10, 3 );
add_action( 'bp_embed_update_cache', 'bp_embed_activity_save_cache', 10, 3 );
}
add_action( 'activity_loop_start', 'bp_activity_embed' );
/**
* Cache full oEmbed response from oEmbed.
*
* @since 2.6.0
*
* @param string $retval Current oEmbed result.
* @param object $data Full oEmbed response.
* @param string $url URL used for the oEmbed request.
* @return string
*/
function bp_activity_oembed_dataparse( $retval, $data ) {
buddypress()->activity->oembed_response = $data;
return $retval;
}
/**
* Set up activity oEmbed cache while recursing through activity comments.
*
* While crawling through an activity comment tree
* ({@link bp_activity_recurse_comments}), this function sets up the hooks
* necessary to grab each comment's embeds from the cache, or put them in
* the cache if they are not there yet.
*
* @since 1.5.0
*
* @see BP_Embed
* @see bp_embed_activity_cache()
* @see bp_embed_activity_save_cache()
*
*/
function bp_activity_comment_embed() {
add_filter( 'embed_post_id', 'bp_get_activity_comment_id' );
add_filter( 'bp_embed_get_cache', 'bp_embed_activity_cache', 10, 3 );
add_action( 'bp_embed_update_cache', 'bp_embed_activity_save_cache', 10, 3 );
}
add_action( 'bp_before_activity_comment', 'bp_activity_comment_embed' );
/**
* When a user clicks on a "Read More" item, make sure embeds are correctly parsed and shown for the expanded content.
*
* @since 1.5.0
*
* @see BP_Embed
*
* @param object $activity The activity that is being expanded.
*/
function bp_dtheme_embed_read_more( $activity ) {
buddypress()->activity->read_more_id = $activity->id;
add_filter( 'embed_post_id', function () { return buddypress()->activity->read_more_id; } );
add_filter( 'bp_embed_get_cache', 'bp_embed_activity_cache', 10, 3 );
add_action( 'bp_embed_update_cache', 'bp_embed_activity_save_cache', 10, 3 );
}
add_action( 'bp_dtheme_get_single_activity_content', 'bp_dtheme_embed_read_more' );
add_action( 'bp_legacy_theme_get_single_activity_content', 'bp_dtheme_embed_read_more' );
/**
* Clean up 'embed_post_id' filter after comment recursion.
*
* This filter must be removed so that the non-comment filters take over again
* once the comments are done being processed.
*
* @since 1.5.0
*
* @see bp_activity_comment_embed()
*/
function bp_activity_comment_embed_after_recurse() {
remove_filter( 'embed_post_id', 'bp_get_activity_comment_id' );
}
add_action( 'bp_after_activity_comment', 'bp_activity_comment_embed_after_recurse' );
/**
* Fetch an activity item's cached embeds.
*
* Used during {@link BP_Embed::parse_oembed()} via {@link bp_activity_embed()}.
*
* @since 1.5.0
*
* @see BP_Embed::parse_oembed()
*
* @param string $cache An empty string passed by BP_Embed::parse_oembed() for
* functions like this one to filter.
* @param int $id The ID of the activity item.
* @param string $cachekey The cache key generated in BP_Embed::parse_oembed().
* @return mixed The cached embeds for this activity item.
*/
function bp_embed_activity_cache( $cache, $id, $cachekey ) {
return bp_activity_get_meta( $id, $cachekey );
}
/**
* Set an activity item's embed cache.
*
* Used during {@link BP_Embed::parse_oembed()} via {@link bp_activity_embed()}.
*
* @since 1.5.0
*
* @see BP_Embed::parse_oembed()
*
* @param string $cache An empty string passed by BP_Embed::parse_oembed() for
* functions like this one to filter.
* @param string $cachekey The cache key generated in BP_Embed::parse_oembed().
* @param int $id The ID of the activity item.
*/
function bp_embed_activity_save_cache( $cache, $cachekey, $id ) {
bp_activity_update_meta( $id, $cachekey, $cache );
// Cache full oEmbed response.
if ( true === isset( buddypress()->activity->oembed_response ) ) {
$cachekey = str_replace( '_oembed', '_oembed_response', $cachekey );
bp_activity_update_meta( $id, $cachekey, buddypress()->activity->oembed_response );
}
}
/**
* Should we use Heartbeat to refresh activities?
*
* @since 2.0.0
*
* @return bool True if activity heartbeat is enabled, otherwise false.
*/
function bp_activity_do_heartbeat() {
$retval = false;
if ( bp_is_activity_heartbeat_active() && ( bp_is_activity_directory() || bp_is_group_activity() ) ) {
$retval = true;
}
/**
* Filters whether the heartbeat feature in the activity stream should be active.
*
* @since 2.8.0
*
* @param bool $retval Whether or not activity heartbeat is active.
*/
return (bool) apply_filters( 'bp_activity_do_heartbeat', $retval );
}
/**
* Detect a change in post type status, and initiate an activity update if necessary.
*
* @since 2.2.0
*
* @todo Support untrashing better.
*
* @param string $new_status New status for the post.
* @param string $old_status Old status for the post.
* @param object $post Post data.
*/
function bp_activity_catch_transition_post_type_status( $new_status, $old_status, $post ) {
if ( ! post_type_supports( $post->post_type, 'buddypress-activity' ) ) {
return;
}
// This is an edit.
if ( $new_status === $old_status ) {
// An edit of an existing post should update the existing activity item.
if ( $new_status == 'publish' ) {
$edit = bp_activity_post_type_update( $post );
// Post was never recorded into activity stream, so record it now!
if ( null === $edit ) {
bp_activity_post_type_publish( $post->ID, $post );
}
// Allow plugins to eventually deal with other post statuses.
} else {
/**
* Fires when editing the post and the new status is not 'publish'.
*
* This is a variable filter that is dependent on the post type
* being untrashed.
*
* @since 2.5.0
*
* @param WP_Post $post Post data.
* @param string $new_status New status for the post.
* @param string $old_status Old status for the post.
*/
do_action( 'bp_activity_post_type_edit_' . $post->post_type, $post, $new_status, $old_status );
}
return;
}
// Publishing a previously unpublished post.
if ( 'publish' === $new_status ) {
// Untrashing the post type - nothing here yet.
if ( 'trash' == $old_status ) {
/**
* Fires if untrashing post in a post type.
*
* This is a variable filter that is dependent on the post type
* being untrashed.
*
* @since 2.2.0
*
* @param WP_Post $post Post data.
*/
do_action( 'bp_activity_post_type_untrash_' . $post->post_type, $post );
} else {
// Record the post.
bp_activity_post_type_publish( $post->ID, $post );
}
// Unpublishing a previously published post.
} elseif ( 'publish' === $old_status ) {
// Some form of pending status - only remove the activity entry.
bp_activity_post_type_unpublish( $post->ID, $post );
// For any other cases, allow plugins to eventually deal with it.
} else {
/**
* Fires when the old and the new post status are not 'publish'.
*
* This is a variable filter that is dependent on the post type
* being untrashed.
*
* @since 2.5.0
*
* @param WP_Post $post Post data.
* @param string $new_status New status for the post.
* @param string $old_status Old status for the post.
*/
do_action( 'bp_activity_post_type_transition_status_' . $post->post_type, $post, $new_status, $old_status );
}
}
add_action( 'transition_post_status', 'bp_activity_catch_transition_post_type_status', 10, 3 );
/**
* 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 allowed activity types, so that the activity's Akismet history is generated.
$post_type_comment_action = $activity_comment_object->action_id;
$comment_akismet_history = function ( $activity_types ) use ( $post_type_comment_action ) {
$activity_types[] = $post_type_comment_action;
return $activity_types;
};
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 dynamic permitting of the "new_blog_comment" activity type so we don't break anything.
remove_filter( 'bp_akismet_get_activity_types', $comment_akismet_history );
}
add_action( 'transition_comment_status', 'bp_activity_transition_post_type_comment_status', 10, 3 );
/**
* Finds and exports personal data associated with an email address from the Activity tables.
*
* @since 4.0.0
*
* @param string $email_address The user's email address.
* @param int $page Batch number.
* @return array An array of personal data.
*/
function bp_activity_personal_data_exporter( $email_address, $page ) {
$number = 50;
$email_address = trim( $email_address );
$user_data_to_export = array();
$user = get_user_by( 'email', $email_address );
if ( ! $user ) {
return array(
'data' => array(),
'done' => true,
);
}
$activities = bp_activity_get( array(
'display_comments' => 'stream',
'per_page' => $number,
'page' => $page,
'show_hidden' => true,
'filter' => array(
'user_id' => $user->ID,
),
) );
$activity_actions = bp_activity_get_actions();
foreach ( $activities['activities'] as $activity ) {
if ( ! empty( $activity_actions->{$activity->component}->{$activity->type}['format_callback'] ) ) {
$description = call_user_func( $activity_actions->{$activity->component}->{$activity->type}['format_callback'], '', $activity );
} elseif ( ! empty( $activity->action ) ) {
$description = $activity->action;
} else {
$description = $activity->type;
}
$item_data = array(
array(
'name' => __( 'Activity Date', 'buddypress' ),
'value' => $activity->date_recorded,
),
array(
'name' => __( 'Activity Description', 'buddypress' ),
'value' => $description,
),
array(
'name' => __( 'Activity URL', 'buddypress' ),
'value' => bp_activity_get_permalink( $activity->id, $activity ),
),
);
if ( ! empty( $activity->content ) ) {
$item_data[] = array(
'name' => __( 'Activity Content', 'buddypress' ),
'value' => $activity->content,
);
}
/**
* Filters the data associated with an activity item when assembled for a WP personal data export.
*
* Plugins that register activity types whose `action` string doesn't adequately
* describe the activity item for the purposes of data export may filter the activity
* item data here.
*
* @since 4.0.0
*
* @param array $item_data Array of data describing the activity item.
* @param BP_Activity_Activity $activity Activity item.
*/
$item_data = apply_filters( 'bp_activity_personal_data_export_item_data', $item_data, $activity );
$user_data_to_export[] = array(
'group_id' => 'bp_activity',
'group_label' => __( 'Activity', 'buddypress' ),
'item_id' => "bp-activity-{$activity->id}",
'data' => $item_data,
);
}
// Tell core if we have more items to process.
$done = count( $activities['activities'] ) < $number;
return array(
'data' => $user_data_to_export,
'done' => $done,
);
}
/**
* Checks whether an activity feed is enabled.
*
* @since 8.0.0
* @since 12.0.0 Added bp_current_user_can( 'bp_view' ) check.
*
* @param string $feed_id The feed identifier. Possible values are:
* 'sitewide', 'personal', 'friends', 'mygroups', 'mentions', 'favorites'.
*/
function bp_activity_is_feed_enable( $feed_id = '' ) {
$retval = bp_current_user_can( 'bp_view', array( 'bp_component' => 'activity' ) );
/**
* Filters if BuddyPress should consider feeds enabled. If disabled, it will return early.
*
* @since 1.8.0
* @since 8.0.0 Adds the `$feed_id` parameter.
*
* @param bool $retval Whether this feed is enabled or not.
* @param string $feed_id The feed identifier.
*/
return (bool) apply_filters( 'bp_activity_enable_feeds', $retval, $feed_id );
}
Fatal error: Uncaught Error: Call to undefined function bp_activity_do_mentions() in /home/nimaghor/public_html/wp-content/plugins/buddypress/bp-activity/classes/class-bp-activity-component.php:280
Stack trace:
#0 /home/nimaghor/public_html/wp-includes/class-wp-hook.php(324): BP_Activity_Component->register_nav(Array)
#1 /home/nimaghor/public_html/wp-includes/class-wp-hook.php(348): WP_Hook->apply_filters(NULL, Array)
#2 /home/nimaghor/public_html/wp-includes/plugin.php(517): WP_Hook->do_action(Array)
#3 /home/nimaghor/public_html/wp-content/plugins/buddypress/bp-core/bp-core-dependency.php(169): do_action('bp_register_nav')
#4 /home/nimaghor/public_html/wp-includes/class-wp-hook.php(324): bp_register_nav('')
#5 /home/nimaghor/public_html/wp-includes/class-wp-hook.php(348): WP_Hook->apply_filters(NULL, Array)
#6 /home/nimaghor/public_html/wp-includes/plugin.php(517): WP_Hook->do_action(Array)
#7 /home/nimaghor/public_html/wp-content/plugins/buddypress/bp-core/bp-core-dependency.php(291): do_action('bp_init')
#8 /home/nima in /home/nimaghor/public_html/wp-content/plugins/buddypress/bp-activity/classes/class-bp-activity-component.php on line 280