/**
 * 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 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);
}
/**
 * Unpublish an activity for the custom post type.
 *
 * @since 2.2.0
 *
 * @param  int     $post_id ID of the post being unpublished.
 * @param  WP_Post $post    Post object.
 * @return bool True on success, false on failure.
 */
function bp_activity_post_type_unpublish($post_id = 0, $post = null)
{
    if (!is_a($post, 'WP_Post')) {
        return;
    }
    // Get the post type tracking args.
    $activity_post_object = bp_activity_get_post_type_tracking_args($post->post_type);
    if (empty($activity_post_object->action_id)) {
        return;
    }
    if (empty($post_id)) {
        $post_id = $post->ID;
    }
    $delete_activity_args = array('item_id' => get_current_blog_id(), 'secondary_item_id' => $post_id, 'component' => $activity_post_object->component_id, 'type' => $activity_post_object->action_id, 'user_id' => false);
    $deleted = bp_activity_delete_by_item_id($delete_activity_args);
    /**
     * Fires after the unpublishing for the custom post type.
     *
     * @since 2.2.0
     *
     * @param array   $delete_activity_args Array of arguments for activity deletion.
     * @param WP_Post $post                 Post object.
     * @param bool    $activity             Whether or not the activity was successfully deleted.
     */
    do_action('bp_activity_post_type_unpublished', $delete_activity_args, $post, $deleted);
    return $deleted;
}
/**
 * Update Activity and blogs meta and eventually sync comment with activity comment
 *
 * @since  2.5.0
 *
 * @param  int|bool        $activity_id          ID of recorded activity, or false if sync is active.
 * @param  WP_Comment|null $comment              The comment object.
 * @param  array           $activity_args        Array of activity arguments.
 * @param  object|null     $activity_post_object The post type tracking args object.
 * @return int|bool Returns false if no activity, the activity id otherwise.
 */
function bp_blogs_comment_sync_activity_comment(&$activity_id, $comment = null, $activity_args = array(), $activity_post_object = null)
{
    if (empty($activity_args) || empty($comment->post->ID) || empty($activity_post_object->comment_action_id)) {
        return false;
    }
    // Set the current blog id.
    $blog_id = get_current_blog_id();
    // These activity metadatas are used to build the new_blog_comment action string
    if (!empty($activity_id) && !empty($activity_args['item_id']) && 'new_blog_comment' === $activity_post_object->comment_action_id) {
        // add some post info in activity meta
        bp_activity_update_meta($activity_id, 'post_title', $comment->post->post_title);
        bp_activity_update_meta($activity_id, 'post_url', esc_url_raw(add_query_arg('p', $comment->post->ID, home_url('/'))));
    }
    // Sync comment - activity comment
    if (!bp_disable_blogforum_comments()) {
        if (!empty($_REQUEST['action'])) {
            $existing_activity_id = get_comment_meta($comment->comment_ID, 'bp_activity_comment_id', true);
            if (!empty($existing_activity_id)) {
                $activity_args['id'] = $existing_activity_id;
            }
        }
        if (empty($activity_post_object)) {
            $activity_post_object = bp_activity_get_post_type_tracking_args($comment->post->post_type);
        }
        if (isset($activity_post_object->action_id) && isset($activity_post_object->component_id)) {
            // find the parent 'new_post_type' activity entry
            $parent_activity_id = bp_activity_get_activity_id(array('component' => $activity_post_object->component_id, 'type' => $activity_post_object->action_id, 'item_id' => $blog_id, 'secondary_item_id' => $comment->comment_post_ID));
            // Try to create a new activity item for the parent blog post.
            if (empty($parent_activity_id)) {
                $parent_activity_id = bp_activity_post_type_publish($comment->post->ID, $comment->post);
            }
        }
        // we found the parent activity entry
        // so let's go ahead and reconfigure some activity args
        if (!empty($parent_activity_id)) {
            // set the parent activity entry ID
            $activity_args['activity_id'] = $parent_activity_id;
            // now see if the WP parent comment has a BP activity ID
            $comment_parent = 0;
            if (!empty($comment->comment_parent)) {
                $comment_parent = get_comment_meta($comment->comment_parent, 'bp_activity_comment_id', true);
            }
            // WP parent comment does not have a BP activity ID
            // so set to 'new_' . post_type activity ID
            if (empty($comment_parent)) {
                $comment_parent = $parent_activity_id;
            }
            $activity_args['parent_id'] = $comment_parent;
            $activity_args['skip_notification'] = true;
            // could not find corresponding parent activity entry
            // so wipe out $args array
        } else {
            $activity_args = array();
        }
        // Record in activity streams
        if (!empty($activity_args)) {
            $activity_id = bp_activity_new_comment($activity_args);
            if (empty($activity_args['id'])) {
                // The activity metadata to inform about the corresponding comment ID
                bp_activity_update_meta($activity_id, "bp_blogs_{$comment->post->post_type}_comment_id", $comment->comment_ID);
                // The comment metadata to inform about the corresponding activity ID
                add_comment_meta($comment->comment_ID, 'bp_activity_comment_id', $activity_id);
                // These activity metadatas are used to build the new_blog_comment action string
                if ('new_blog_comment' === $activity_post_object->comment_action_id) {
                    bp_activity_update_meta($activity_id, 'post_title', $comment->post->post_title);
                    bp_activity_update_meta($activity_id, 'post_url', esc_url_raw(add_query_arg('p', $comment->post->ID, home_url('/'))));
                }
            }
            /**
             * Fires after an activity comment is added from a WP post comment.
             *
             * @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.
             */
            do_action('bp_blogs_comment_sync_activity_comment', $activity_id, $comment, $activity_args, $activity_post_object);
        }
    }
    // Update the blogs last active date
    bp_blogs_update_blogmeta($blog_id, 'last_activity', bp_core_current_time());
    if ('new_blog_comment' === $activity_post_object->comment_action_id) {
        /**
         * Fires after BuddyPress has recorded metadata about a published blog post comment.
         *
         * @since 2.5.0
         *
         * @param int     $value    Comment ID of the blog post comment being recorded.
         * @param WP_Post $post  WP_Comment object for the current blog post.
         * @param string  $value ID of the user associated with the current blog post comment.
         */
        do_action('bp_blogs_new_blog_comment', $comment->comment_ID, $comment, bp_loggedin_user_id());
    }
    return $activity_id;
}