bbp_split_topic_handler( string $action = '' )

Split topic handler

Description

Handles the front end split topic submission

Parameters

$action

(string) (Optional) The requested action to compare this function to

Default value: ''

Source

File: bp-forums/topics/functions.php

function bbp_split_topic_handler( $action = '' ) {

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

	global $wpdb;

	// 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>: Reply ID to split the topic from not found!', 'buddyboss' ) );
	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.', 'buddyboss' ) );

	/** 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.', 'buddyboss' ) );

	// 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?', 'buddyboss' ) );
		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 the permissions to edit the source discussion.', 'buddyboss' ) );

	// How to Split
	if ( !empty( $_POST['bbp_topic_split_option'] ) )
		$split_option = (string) trim( $_POST['bbp_topic_split_option'] );

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

	// 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>: Destination discussion ID not found!', 'buddyboss' ) );
				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 discussion you want to split to was not found!', 'buddyboss' ) );

				// 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 the permissions to edit the destination discussion!', 'buddyboss' ) );

				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 = esc_attr( strip_tags( $_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 discussion. Please try again.', 'buddyboss' ) );
					}

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

				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_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( $_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.
	$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( __( '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 ) ) {
				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
	wp_safe_redirect( bbp_get_topic_permalink( $destination_topic->ID ) );

	// For good measure
	exit();
}

Changelog

Changelog
Version Description
bbPress (r2756) 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.