BP_REST_Topics_Actions_Endpoint::merge_item( WP_REST_Request $request )

Merge Topic

Description

Parameters

$request

(WP_REST_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 merge_item( $request ) {

		// Define local variable(s).
		$source_topic_id      = 0;
		$destination_topic_id = 0;
		$source_topic         = 0;
		$destination_topic    = 0;
		$subscribers          = array();
		$favoriters           = array();
		$replies              = array();

		// Topic id.
		if ( empty( $request['id'] ) ) {
			return new WP_Error(
				'bp_rest_topic_invalid_id',
				__( 'Invalid topic ID.', 'buddyboss' ),
				array(
					'status' => 404,
				)
			);
		} else {
			$source_topic_id = (int) $request['id'];
		}

		// Source topic not found.
		$source_topic = bbp_get_topic( $source_topic_id );
		if ( empty( $source_topic ) ) {
			return new WP_Error(
				'bp_rest_bbp_merge_topic_source_not_found',
				__( 'The topic you want to merge was not found.', 'buddyboss' ),
				array(
					'status' => 404,
				)
			);
		}

		// Cannot edit source topic.
		if ( ! current_user_can( 'edit_topic', $source_topic->ID ) ) {
			return new WP_Error(
				'bp_rest_bbp_merge_topic_source_permission',
				__( 'Sorry, You do not have permission to edit the source topic.', 'buddyboss' ),
				array(
					'status' => rest_authorization_required_code(),
				)
			);
		}

		/** Destination Topic */
		// Topic id.
		if ( empty( $request['destination_id'] ) ) {
			return new WP_Error(
				'bp_rest_bbp_merge_topic_destination_id',
				__( 'Sorry, Destination discussion ID not found.', 'buddyboss' ),
				array(
					'status' => 404,
				)
			);
		} else {
			$destination_topic_id = (int) $request['destination_id'];
		}

		// Destination topic not found.
		$destination_topic = bbp_get_topic( $destination_topic_id );
		if ( empty( $destination_topic ) ) {
			return new WP_Error(
				'bp_rest_bbp_merge_topic_destination_not_found',
				__( 'Sorry, The discussion you want to merge to was not found.', 'buddyboss' ),
				array(
					'status' => 404,
				)
			);
		}

		// Cannot edit destination topic.
		if ( ! current_user_can( 'edit_topic', $destination_topic->ID ) ) {
			return new WP_Error(
				'bp_rest_bbp_merge_topic_destination_permission',
				__( 'Sorry, You do not have the permissions to edit the destination discussion.', 'buddyboss' ),
				array(
					'status' => rest_authorization_required_code(),
				)
			);
		}

		/** No Errors */
		// Update counts, etc...
		do_action( 'bbp_merge_topic', $destination_topic->ID, $source_topic->ID );

		/** Date Check */
		// Check if the destination topic is older than the source topic.
		if ( strtotime( $source_topic->post_date ) < strtotime( $destination_topic->post_date ) ) {

			// Set destination topic post_date to 1 second before source topic.
			$destination_post_date = gmdate( 'Y-m-d H:i:s', strtotime( $source_topic->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 */
		// Get subscribers from source topic.
		$subscribers = bbp_get_topic_subscribers( $source_topic->ID );

		// Remove the topic from everybody's subscriptions.
		if ( ! empty( $subscribers ) ) {

			// Loop through each user.
			foreach ( (array) $subscribers as $subscriber ) {

				// Shift the subscriber if told to.
				if ( ! empty( $request['subscribers'] ) && ( true === $request['subscribers'] ) && bbp_is_subscriptions_active() ) {
					bbp_add_user_subscription( $subscriber, $destination_topic->ID );
				}

				// Remove old subscription.
				bbp_remove_user_subscription( $subscriber, $source_topic->ID );
			}
		}

		/** Favorites */
		// Get favoriters from source topic.
		$favoriters = bbp_get_topic_favoriters( $source_topic->ID );

		// Remove the topic from everybody's favorites.
		if ( ! empty( $favoriters ) ) {

			// Loop through each user.
			foreach ( (array) $favoriters as $favoriter ) {

				// Shift the favoriter if told to.
				if ( ! empty( $request['favorites'] ) && true === $request['favorites'] ) {
					bbp_add_user_favorite( $favoriter, $destination_topic->ID );
				}

				// Remove old favorite.
				bbp_remove_user_favorite( $favoriter, $source_topic->ID );
			}
		}

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

		// Tags to possibly merge.
		if ( ! empty( $source_topic_tags ) && ! is_wp_error( $source_topic_tags ) ) {

			// Shift the tags if told to.
			if ( ! empty( $request['tags'] ) && ( true === $request['tags'] ) ) {
				wp_set_post_terms( $destination_topic->ID, $source_topic_tags, bbp_get_topic_tag_tax_id(), true );
			}

			// Delete the tags from the source topic.
			wp_delete_object_term_relationships( $source_topic->ID, bbp_get_topic_tag_tax_id() );
		}

		/** Source Topic */
		// Status.
		bbp_open_topic( $source_topic->ID );

		// Sticky.
		bbp_unstick_topic( $source_topic->ID );

		// Get the replies of the source topic.
		$replies = (array) get_posts(
			array(
				'post_parent'    => $source_topic->ID,
				'post_type'      => bbp_get_reply_post_type(),
				'posts_per_page' => - 1,
				'order'          => 'ASC',
			)
		);

		// Prepend the source topic to its replies array for processing.
		array_unshift( $replies, $source_topic );

		if ( ! empty( $replies ) ) {

			/** Merge Replies */
			// 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'  => sprintf(
							/* translators: Topic Title. */
							__( 'Reply To: %s', 'buddyboss' ),
							$destination_topic->post_title
						),
						'post_name'   => false,
						'post_type'   => bbp_get_reply_post_type(),
						'post_parent' => $destination_topic->ID,
						'guid'        => '',
					)
				);

				// 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 );
				if ( empty( $reply_to ) ) {
					bbp_update_reply_to( $reply->ID, $source_topic->ID );
				}

				// Do additional actions per merged reply.
				do_action( 'bbp_merged_topic_reply', $reply->ID, $destination_topic->ID );
			}
		}

		/** Successful Merge */
		// Update topic's last meta data.
		bbp_update_topic_last_reply_id( $destination_topic->ID );
		bbp_update_topic_last_active_id( $destination_topic->ID );
		bbp_update_topic_last_active_time( $destination_topic->ID );

		// Send the post parent of the source topic as it has been shifted.
		// (possibly to a new forum) so we need to update the counts of the.
		// old forum as well as the new one.
		do_action( 'bbp_merged_topic', $destination_topic->ID, $source_topic->ID, $source_topic->post_parent );

		/**
		 * Fires after a list of topic is merged via the REST API.
		 *
		 * @param array           $destination_topic Destination topic.
		 * @param array           $source_topic      Source topic.
		 * @param WP_REST_Request $request           The request sent to the API.
		 *
		 * @since 0.1.0
		 */
		do_action( 'bp_rest_topic_get_item', $destination_topic, $source_topic, $request );

		return $this->get_item(
			array(
				'id'      => $destination_topic->ID,
				'context' => 'view',
			)
		);
	}

Changelog

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.