BP_REST_Topics_Actions_Endpoint::split_item( WP_REST_Request $request )
Split Topic
Description
Parameters
- $request
-
(Required) Full details about the request.
Return
(WP_REST_Response) | WP_Error
Source
File: bp-forums/classes/class-bp-rest-topics-actions-endpoint.php
public function split_item( $request ) {
global $wpdb;
// Prevent debug notices.
$split_option = false;
/** Split Reply */
if ( empty( $request['reply_id'] ) ) {
return new WP_Error(
'bp_rest_bbp_split_topic_reply_id',
__( 'Reply ID to split the topic from not found!', 'buddyboss' ),
array(
'status' => 404,
)
);
} else {
$from_reply_id = (int) $request['reply_id'];
}
$from_reply = bbp_get_reply( $from_reply_id );
// Reply exists.
if ( empty( $from_reply ) ) {
return new WP_Error(
'bp_rest_bbp_split_topic_r_not_found',
__( 'The reply you want to split from was not found.', 'buddyboss' ),
array(
'status' => 404,
)
);
}
/** Topic to Split */
// Get the topic being split.
$source_topic = bbp_get_topic( $from_reply->post_parent );
// No topic.
if ( empty( $source_topic ) ) {
return new WP_Error(
'bp_rest_bbp_split_topic_source_not_found',
__( 'The topic you want to split was not found.', 'buddyboss' ),
array(
'status' => 404,
)
);
}
// Use cannot edit topic.
if ( ! current_user_can( 'edit_topic', $source_topic->ID ) ) {
return new WP_Error(
'bp_rest_bbp_split_topic_source_permission',
__( 'Sorry, You do not have the permissions to edit the source discussion.', 'buddyboss' ),
array(
'status' => rest_authorization_required_code(),
)
);
}
// How to Split.
if ( ! empty( $request['split_option'] ) ) {
$split_option = (string) trim( $request['split_option'] );
}
if ( empty( $split_option ) || ! in_array( $split_option, array( 'existing', 'reply' ), true ) ) {
return new WP_Error(
'bp_rest_bbp_split_topic_option',
__( 'Sorry, You need to choose a valid split option.', 'buddyboss' ),
array(
'status' => 404,
)
);
// Valid Split Option.
} else {
// What kind of split.
switch ( $split_option ) {
// Into an existing topic.
case 'existing':
// Get destination topic id.
if ( empty( $request['destination_id'] ) ) {
return new WP_Error(
'bp_rest_bbp_split_topic_destination_id',
__( 'Sorry, Destination discussion ID not found!', 'buddyboss' ),
array(
'status' => 404,
)
);
} else {
$destination_topic_id = (int) $request['destination_id'];
}
// Get the destination topic.
$destination_topic = bbp_get_topic( $destination_topic_id );
// No destination topic.
if ( empty( $destination_topic ) ) {
return new WP_Error(
'bp_rest_bbp_split_topic_destination_not_found',
__( 'Sorry, The discussion you want to split to was not found!', 'buddyboss' ),
array(
'status' => 404,
)
);
}
// User cannot edit the destination topic.
if ( ! current_user_can( 'edit_topic', $destination_topic->ID ) ) {
return new WP_Error(
'bp_rest_bbp_split_topic_destination_permission',
__( 'Sorry, You do not have the permissions to edit the destination discussion!', 'buddyboss' ),
array(
'status' => rest_authorization_required_code(),
)
);
}
break;
// Split at reply into a new topic.
case 'reply':
default:
// User needs to be able to publish topics.
if ( current_user_can( 'publish_topics' ) ) {
// Use the new title that was passed.
if ( ! empty( $request['new_destination_title'] ) ) {
$destination_topic_title = esc_attr( wp_strip_all_tags( $request['new_destination_title'] ) );
// Use the source topic title.
} else {
$destination_topic_title = $source_topic->post_title;
}
// Update the topic.
$destination_topic_id = wp_update_post(
array(
'ID' => $from_reply->ID,
'post_title' => $destination_topic_title,
'post_name' => false,
'post_type' => bbp_get_topic_post_type(),
'post_parent' => $source_topic->post_parent,
'menu_order' => 0,
'guid' => '',
)
);
$destination_topic = bbp_get_topic( $destination_topic_id );
// Make sure the new topic knows its a topic.
bbp_update_topic_topic_id( $from_reply->ID );
// Shouldn't happen.
if (
false === $destination_topic_id
|| is_wp_error( $destination_topic_id )
|| empty( $destination_topic )
) {
return new WP_Error(
'bp_rest_bbp_split_topic_destination_reply',
__( 'Sorry, There was a problem converting the reply into the discussion. Please try again.', 'buddyboss' ),
array(
'status' => 404,
)
);
}
// User cannot publish posts.
} else {
return new WP_Error(
'bp_rest_bbp_split_topic_destination_permission',
__( 'Sorry, You do not have the permissions to create new topics. The reply could not be converted into a discussion.', 'buddyboss' ),
array(
'status' => rest_authorization_required_code(),
)
);
}
break;
}
}
/** No Errors - Do the Spit */
// Update counts, etc...
do_action( 'bbp_pre_split_topic', $from_reply->ID, $source_topic->ID, $destination_topic->ID );
/** Date Check */
// Check if the destination topic is older than the from reply.
if ( strtotime( $from_reply->post_date ) < strtotime( $destination_topic->post_date ) ) {
// Set destination topic post_date to 1 second before from reply.
$destination_post_date = gmdate( 'Y-m-d H:i:s', strtotime( $from_reply->post_date ) - 1 );
// Update destination topic.
wp_update_post(
array(
'ID' => $destination_topic_id,
'post_date' => $destination_post_date,
'post_date_gmt' => get_gmt_from_date( $destination_post_date ),
)
);
}
/** Subscriptions */
// Copy the subscribers.
if ( ! empty( $request['subscribers'] ) && true === $request['subscribers'] && bbp_is_subscriptions_active() ) {
// Get the subscribers.
$subscribers = bbp_get_topic_subscribers( $source_topic->ID );
if ( ! empty( $subscribers ) ) {
// Add subscribers to new topic.
foreach ( (array) $subscribers as $subscriber ) {
bbp_add_user_subscription( $subscriber, $destination_topic->ID );
}
}
}
/** Favorites */
// Copy the favoriters if told to.
if ( ! empty( $request['favorites'] ) && ( true === $request['favorites'] ) ) {
// Get the favoriters.
$favoriters = bbp_get_topic_favoriters( $source_topic->ID );
if ( ! empty( $favoriters ) ) {
// Add the favoriters to new topic.
foreach ( (array) $favoriters as $favoriter ) {
bbp_add_user_favorite( $favoriter, $destination_topic->ID );
}
}
}
/** Tags */
// Copy the tags if told to.
if ( ! empty( $request['tags'] ) && ( true === $request['tags'] ) ) {
// Get the source topic tags.
$source_topic_tags = wp_get_post_terms( $source_topic->ID, bbp_get_topic_tag_tax_id(), array( 'fields' => 'names' ) );
if ( ! empty( $source_topic_tags ) ) {
wp_set_post_terms( $destination_topic->ID, $source_topic_tags, bbp_get_topic_tag_tax_id(), true );
}
}
/** Split Replies */
// get_posts() is not used because it doesn't allow us to use '>='.
// comparision without a filter.
// phpcs:ignore
$replies = (array) $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$wpdb->posts} WHERE {$wpdb->posts}.post_date >= %s AND {$wpdb->posts}.post_parent = %d AND {$wpdb->posts}.post_type = %s ORDER BY {$wpdb->posts}.post_date ASC", $from_reply->post_date, $source_topic->ID, bbp_get_reply_post_type() ) );
// Make sure there are replies to loop through.
if ( ! empty( $replies ) && ! is_wp_error( $replies ) ) {
// Calculate starting point for reply positions.
switch ( $split_option ) {
// Get topic reply count for existing topic.
case 'existing':
$reply_position = bbp_get_topic_reply_count( $destination_topic->ID );
break;
// Account for new lead topic.
case 'reply':
$reply_position = 1;
break;
}
// Save reply ids.
$reply_ids = array();
// Change the post_parent of each reply to the destination topic id.
foreach ( $replies as $reply ) {
// Bump the reply position each iteration through the loop.
$reply_position++;
// Update the reply.
wp_update_post(
array(
'ID' => $reply->ID,
'post_title' => sprintf(
/* translators: Topic Title. */
__( 'Reply To: %s', 'buddyboss' ),
$destination_topic->post_title
),
'post_name' => false, // will be automatically generated.
'post_parent' => $destination_topic->ID,
'menu_order' => $reply_position,
'guid' => '',
)
);
// Gather reply ids.
$reply_ids[] = $reply->ID;
// Adjust reply meta values.
bbp_update_reply_topic_id( $reply->ID, $destination_topic->ID );
bbp_update_reply_forum_id( $reply->ID, bbp_get_topic_forum_id( $destination_topic->ID ) );
// Adjust reply to values.
$reply_to = bbp_get_reply_to( $reply->ID );
// Not a reply to a reply that moved over.
if ( ! in_array( $reply_to, $reply_ids, true ) ) {
bbp_update_reply_to( $reply->ID, 0 );
}
// New topic from reply can't be a reply to.
if ( ( $from_reply->ID === $destination_topic->ID ) && ( $from_reply->ID === $reply_to ) ) {
bbp_update_reply_to( $reply->ID, 0 );
}
// Do additional actions per split reply.
do_action( 'bbp_split_topic_reply', $reply->ID, $destination_topic->ID );
}
// Remove reply to from new topic.
if ( $from_reply->ID === $destination_topic->ID ) {
delete_post_meta( $from_reply->ID, '_bbp_reply_to' );
}
// Set the last reply ID and freshness.
$last_reply_id = $reply->ID;
$freshness = $reply->post_date;
// Set the last reply ID and freshness to the from_reply.
} else {
$last_reply_id = $from_reply->ID;
$freshness = $from_reply->post_date;
}
// It is a new topic and we need to set some default metas to make.
// the topic display in bbp_has_topics() list.
if ( 'reply' === $split_option ) {
bbp_update_topic_last_reply_id( $destination_topic->ID, $last_reply_id );
bbp_update_topic_last_active_id( $destination_topic->ID, $last_reply_id );
bbp_update_topic_last_active_time( $destination_topic->ID, $freshness );
}
// Update source topic ID last active.
bbp_update_topic_last_reply_id( $source_topic->ID );
bbp_update_topic_last_active_id( $source_topic->ID );
bbp_update_topic_last_active_time( $source_topic->ID );
/** Successful Split */
// Update counts, etc...
do_action( 'bbp_post_split_topic', $from_reply->ID, $source_topic->ID, $destination_topic->ID );
/**
* Fires after a list of topic is split via the REST API.
*
* @param array $from_reply Reply ID to start split from.
* @param array $source_topic Source topic.
* @param array $destination_topic Destination topic.
* @param WP_REST_Request $request The request sent to the API.
*
* @since 0.1.0
*/
do_action( 'bp_rest_split_get_item', $from_reply, $source_topic, $destination_topic, $request );
return $this->get_item(
array(
'id' => $destination_topic->ID,
'context' => 'view',
)
);
}
Changelog
| Version | Description |
|---|---|
| 0.1.0 | Introduced. |
Questions?
We're always happy to help with code or other questions you might have! Search our developer docs, contact support, or connect with our sales team.