bbp_split_topic_handler( string $action = '' )

Split topic handler


Description Description

Handles the front end split topic submission


Parameters Parameters

$action

(Optional) The requested action to compare this function to

Default value: ''


Top ↑

Source Source

File: includes/topics/functions.php

function bbp_split_topic_handler( $action = '' ) {

	// Bail if action is not 'bbp-split-topic'
	if ( 'bbp-split-topic' !== $action ) {
		return;
	}

	// Prevent debug notices
	$from_reply_id = $destination_topic_id = 0;
	$destination_topic_title = '';
	$destination_topic = $from_reply = $source_topic = '';
	$split_option = false;

	/** Split Reply ***********************************************************/

	if ( empty( $_POST['bbp_reply_id'] ) ) {
		bbp_add_error( 'bbp_split_topic_reply_id', __( '<strong>ERROR</strong>: A reply ID is required.', 'bbpress' ) );
	} else {
		$from_reply_id = (int) $_POST['bbp_reply_id'];
	}

	$from_reply = bbp_get_reply( $from_reply_id );

	// Reply exists
	if ( empty( $from_reply ) ) {
		bbp_add_error( 'bbp_split_topic_r_not_found', __( '<strong>ERROR</strong>: The reply you want to split from was not found.', 'bbpress' ) );
	}

	/** Topic to Split ********************************************************/

	// Get the topic being split
	$source_topic = bbp_get_topic( $from_reply->post_parent );

	// No topic
	if ( empty( $source_topic ) ) {
		bbp_add_error( 'bbp_split_topic_source_not_found', __( '<strong>ERROR</strong>: The topic you want to split was not found.', 'bbpress' ) );
	}

	// Nonce check failed
	if ( ! bbp_verify_nonce_request( 'bbp-split-topic_' . $source_topic->ID ) ) {
		bbp_add_error( 'bbp_split_topic_nonce', __( '<strong>ERROR</strong>: Are you sure you wanted to do that?', 'bbpress' ) );
		return;
	}

	// Use cannot edit topic
	if ( ! current_user_can( 'edit_topic', $source_topic->ID ) ) {
		bbp_add_error( 'bbp_split_topic_source_permission', __( '<strong>ERROR</strong>: You do not have permission to edit the source topic.', 'bbpress' ) );
	}

	// How to Split
	if ( ! empty( $_POST['bbp_topic_split_option'] ) ) {
		$split_option = sanitize_key( $_POST['bbp_topic_split_option'] );
	}

	// Invalid split option
	if ( empty( $split_option ) || ! in_array( $split_option, array( 'existing', 'reply' ), true ) ) {
		bbp_add_error( 'bbp_split_topic_option', __( '<strong>ERROR</strong>: You need to choose a valid split option.', 'bbpress' ) );

	// Valid Split Option
	} else {

		// What kind of split
		switch ( $split_option ) {

			// Into an existing topic
			case 'existing' :

				// Get destination topic id
				if ( empty( $_POST['bbp_destination_topic'] ) ) {
					bbp_add_error( 'bbp_split_topic_destination_id', __( '<strong>ERROR</strong>: A topic ID is required.', 'bbpress' ) );
				} else {
					$destination_topic_id = (int) $_POST['bbp_destination_topic'];
				}

				// Get the destination topic
				$destination_topic = bbp_get_topic( $destination_topic_id );

				// No destination topic
				if ( empty( $destination_topic ) ) {
					bbp_add_error( 'bbp_split_topic_destination_not_found', __( '<strong>ERROR</strong>: The topic you want to split to was not found.', 'bbpress' ) );
				}

				// User cannot edit the destination topic
				if ( ! current_user_can( 'edit_topic', $destination_topic->ID ) ) {
					bbp_add_error( 'bbp_split_topic_destination_permission', __( '<strong>ERROR</strong>: You do not have permission to edit the destination topic.', 'bbpress' ) );
				}

				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( $_POST['bbp_topic_split_destination_title'] ) ) {
						$destination_topic_title = sanitize_text_field( $_POST['bbp_topic_split_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 ) ) {
						bbp_add_error( 'bbp_split_topic_destination_reply', __( '<strong>ERROR</strong>: There was a problem converting the reply into the topic. Please try again.', 'bbpress' ) );
					}

				// User cannot publish posts
				} else {
					bbp_add_error( 'bbp_split_topic_destination_permission', __( '<strong>ERROR</strong>: You do not have permission to create new topics. The reply could not be converted into a topic.', 'bbpress' ) );
				}

				break;
		}
	}

	// Bail if there are errors
	if ( bbp_has_errors() ) {
		return;
	}

	/** 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 = date( '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( $_POST['bbp_topic_subscribers'] ) && "1" === $_POST['bbp_topic_subscribers'] && bbp_is_subscriptions_active() ) {

		// Get the subscribers
		$subscribers = bbp_get_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( $_POST['bbp_topic_favoriters'] ) && ( "1" === $_POST['bbp_topic_favoriters'] ) ) {

		// 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( $_POST['bbp_topic_tags'] ) && ( "1" === $_POST['bbp_topic_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.
	$bbp_db  = bbp_db();
	$query   = $bbp_db->prepare( "SELECT * FROM {$bbp_db->posts} WHERE {$bbp_db->posts}.post_date >= %s AND {$bbp_db->posts}.post_parent = %d AND {$bbp_db->posts}.post_type = %s ORDER BY {$bbp_db->posts}.post_date ASC", $from_reply->post_date, $source_topic->ID, bbp_get_reply_post_type() );
	$replies = (array) $bbp_db->get_results( $query );

	// Make sure there are replies to loop through
	if ( ! empty( $replies ) && ! is_wp_error( $replies ) ) {

		// Save reply ids
		$reply_ids = array();

		// Change the post_parent of each reply to the destination topic id
		foreach ( $replies as $reply ) {

			// Update the reply
			wp_update_post( array(
				'ID'          => $reply->ID,
				'post_title'  => '',
				'post_name'   => false, // will be automatically generated
				'post_parent' => $destination_topic->ID,
				'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 position
			bbp_update_reply_position( $reply->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 );

	// Redirect back to the topic
	bbp_redirect( bbp_get_topic_permalink( $destination_topic->ID ) );
}

Top ↑

Changelog Changelog

Changelog
Version Description
2.0.0 Introduced.

Top ↑

User Contributed Notes User Contributed Notes

You must log in before being able to contribute a note or feedback.