BP_REST_Reply_Endpoint::create_item( WP_REST_Request $request )

Create a reply.

Description

Parameters

$request

(Required) Full details about the request.

Return

(WP_REST_Response) | WP_Error

Source

File: bp-forums/classes/class-bp-rest-reply-endpoint.php

	public function create_item( $request ) {

		$reply = $this->prepare_reply_for_database( $request );

		// Define local variable(s).
		$forum_id       = 0;
		$reply_author   = 0;
		$reply_to       = 0;
		$reply_title    = '';
		$reply_content  = '';
		$anonymous_data = array();

		/** Reply Author */
		// User is anonymous.
		if ( bbp_is_anonymous() ) {

			$anonymous_args = array(
				'bbp_anonymous_name'    => ! empty( $request['anonymous_name'] ) ? sanitize_text_field( $request['anonymous_name'] ) : '',
				'bbp_anonymous_email'   => ! empty( $request['anonymous_email'] ) ? sanitize_email( $request['anonymous_email'] ) : '',
				'bbp_anonymous_website' => ! empty( $request['anonymous_website'] ) ? sanitize_text_field( $request['anonymous_website'] ) : '',
			);

			// Filter anonymous data (variable is used later).
			$anonymous_data = bbp_filter_anonymous_post_data( $anonymous_args );

			// Anonymous data checks out, so set cookies, etc...
			if ( ! empty( $anonymous_data ) && is_array( $anonymous_data ) ) {
				bbp_set_current_anonymous_user_data( $anonymous_data );
			}

			// User is logged in.
		} else {

			// User cannot create replies.
			if ( ! current_user_can( 'publish_replies' ) ) {
				return new WP_Error(
					'bp_rest_bbp_reply_permission',
					__( 'Sorry, You do not have permission to reply.', 'buddyboss' ),
					array(
						'status' => rest_authorization_required_code(),
					)
				);
			}

			// Reply author is current user.
			$reply_author = bbp_get_current_user_id();
		}

		/** Topic ID */
		// Topic id was not passed.
		if ( empty( $reply->bbp_topic_id ) ) {
			return new WP_Error(
				'bp_rest_bbp_reply_topic_id',
				__( 'Sorry, Discussion ID is missing.', 'buddyboss' ),
				array(
					'status' => 400,
				)
			);

			// Topic id is not a number.
		} elseif ( ! is_numeric( $reply->bbp_topic_id ) ) {
			return new WP_Error(
				'bp_rest_bbp_reply_topic_id',
				__( 'Sorry, Discussion ID must be a number.', 'buddyboss' ),
				array(
					'status' => 400,
				)
			);
			// Topic id might be valid.
		} else {
			// Get the topic id.
			$posted_topic_id = intval( $reply->bbp_topic_id );

			// Topic id is a negative number.
			if ( 0 > $posted_topic_id ) {
				return new WP_Error(
					'bp_rest_bbp_reply_topic_id',
					__( 'Sorry, Discussion ID cannot be a negative number.', 'buddyboss' ),
					array(
						'status' => 400,
					)
				);

				// Topic does not exist.
			} elseif ( ! bbp_get_topic( $posted_topic_id ) ) {
				return new WP_Error(
					'bp_rest_bbp_reply_topic_id',
					__( 'Sorry, Discussion does not exist.', 'buddyboss' ),
					array(
						'status' => 400,
					)
				);

				// Use the POST'ed topic id.
			} else {
				$topic_id = $posted_topic_id;
			}
		}

		/** Forum ID */
		// Try to use the forum id of the topic.
		if ( ! isset( $reply->bbp_forum_id ) && ! empty( $topic_id ) ) {
			$forum_id = bbp_get_topic_forum_id( $topic_id );

			// Error check the POST'ed forum id.
		} elseif ( isset( $reply->bbp_forum_id ) ) {

			// Empty Forum id was passed.
			if ( empty( $reply->bbp_forum_id ) ) {
				return new WP_Error(
					'bp_rest_bbp_reply_forum_id',
					__( 'Sorry, Forum ID is missing.', 'buddyboss' ),
					array(
						'status' => 400,
					)
				);

				// Forum id is not a number.
			} elseif ( ! is_numeric( $reply->bbp_forum_id ) ) {
				return new WP_Error(
					'bp_rest_bbp_reply_forum_id',
					__( 'Sorry, Forum ID must be a number.', 'buddyboss' ),
					array(
						'status' => 400,
					)
				);

				// Forum id might be valid.
			} else {

				// Get the forum id.
				$posted_forum_id = intval( $reply->bbp_forum_id );

				// Forum id is empty.
				if ( 0 === $posted_forum_id ) {
					return new WP_Error(
						'bp_rest_bbp_topic_forum_id',
						__( 'Sorry, Forum ID is missing.', 'buddyboss' ),
						array(
							'status' => 400,
						)
					);

					// Forum id is a negative number.
				} elseif ( 0 > $posted_forum_id ) {
					return new WP_Error(
						'bp_rest_bbp_topic_forum_id',
						__( 'Sorry, Forum ID cannot be a negative number.', 'buddyboss' ),
						array(
							'status' => 400,
						)
					);

					// Forum does not exist.
				} elseif ( ! bbp_get_forum( $posted_forum_id ) ) {
					return new WP_Error(
						'bp_rest_bbp_topic_forum_id',
						__( 'Sorry, Forum does not exist.', 'buddyboss' ),
						array(
							'status' => 400,
						)
					);

					// Use the POST'ed forum id.
				} else {
					$forum_id = $posted_forum_id;
				}
			}
		}

		// Forum exists.
		if ( ! empty( $forum_id ) ) {

			// Forum is a category.
			if ( bbp_is_forum_category( $forum_id ) ) {
				return new WP_Error(
					'bp_rest_bbp_new_reply_forum_category',
					__( 'This forum is a category. No replies can be created in this forum.', 'buddyboss' ),
					array(
						'status' => 400,
					)
				);

				// Forum is not a category.
			} else {

				// Forum is closed and user cannot access.
				if ( bbp_is_forum_closed( $forum_id ) && ! current_user_can( 'edit_forum', $forum_id ) ) {
					return new WP_Error(
						'bp_rest_bbp_new_reply_forum_closed',
						__( 'This forum has been closed to new replies.', 'buddyboss' ),
						array(
							'status' => 400,
						)
					);
				}

				/**
				 * Added logic for group forum
				 * Current user is part of that group or not.
				 * We need to check manually because bbpress updating that caps only on group forum page and
				 * in API those conditional tag will not work.
				 */
				$group_ids = bbp_get_forum_group_ids( $forum_id );
				if ( ! empty( $group_ids ) ) {
					$is_member = false;
					foreach ( $group_ids as $group_id ) {
						if ( groups_is_user_member( get_current_user_id(), $group_id ) ) {
							$is_member = true;
							break;
						}
					}
				}

				// Forum is private and user cannot access.
				if ( bbp_is_forum_private( $forum_id ) ) {
					if (
						( empty( $group_ids ) && ! current_user_can( 'read_private_forums' ) )
						|| ( ! empty( $group_ids ) && ! $is_member )
					) {
						return new WP_Error(
							'bp_rest_bbp_new_reply_forum_private',
							__( 'This forum is private and you do not have the capability to read or create new replies in it.', 'buddyboss' ),
							array(
								'status' => 400,
							)
						);
					}

					// Forum is hidden and user cannot access.
				} elseif ( bbp_is_forum_hidden( $forum_id ) ) {
					if (
						( empty( $group_ids ) && ! current_user_can( 'read_hidden_forums' ) )
						|| ( ! empty( $group_ids ) && ! $is_member )
					) {
						return new WP_Error(
							'bp_rest_bbp_new_reply_forum_hidden',
							__( 'This forum is hidden and you do not have the capability to read or create new replies in it.', 'buddyboss' ),
							array(
								'status' => 400,
							)
						);
					}
				}
			}
		}

		/** Unfiltered HTML */
		// Remove kses filters from title and content for capable users and if the nonce is verified.
		if ( current_user_can( 'unfiltered_html' ) ) {
			remove_filter( 'bbp_new_reply_pre_title', 'wp_filter_kses' );
			remove_filter( 'bbp_new_reply_pre_content', 'bbp_encode_bad', 10 );
			remove_filter( 'bbp_new_reply_pre_content', 'bbp_filter_kses', 30 );
		}

		/** Reply Title */
		if ( ! empty( $reply->bbp_reply_title ) ) {
			$reply_title = esc_attr( wp_strip_all_tags( $reply->bbp_reply_title ) );
		}

		// Filter and sanitize.
		$reply_title = apply_filters( 'bbp_new_reply_pre_title', $reply_title );

		/** Reply Content */
		if ( ! empty( $reply->bbp_reply_content ) ) {
			$reply_content = $reply->bbp_reply_content;
		}

		// Filter and sanitize.
		$reply_content = apply_filters( 'bbp_new_reply_pre_content', $reply_content );

		// No reply content.
		if (
			empty( $reply_content )
			&& empty( $request['bbp_media'] )
			&& empty( $request['bbp_media_gif'] )
		) {
			return new WP_Error(
				'bp_rest_bbp_reply_content',
				__( 'Sorry, Your reply cannot be empty.', 'buddyboss' ),
				array(
					'status' => 400,
				)
			);
		}

		// Filter and sanitize.
		$reply_content = apply_filters( 'bbp_new_reply_pre_content', $reply_content );

		/** Reply Flooding */
		if ( ! bbp_check_for_flood( $anonymous_data, $reply_author ) ) {
			return new WP_Error(
				'bp_rest_bbp_reply_flood',
				__( 'Slow down; you move too fast.', 'buddyboss' ),
				array(
					'status' => 400,
				)
			);
		}

		/** Reply Duplicate */
		if ( ! bbp_check_for_duplicate(
			array(
				'post_type'      => bbp_get_reply_post_type(),
				'post_author'    => $reply_author,
				'post_content'   => $reply_content,
				'post_parent'    => $topic_id,
				'anonymous_data' => $anonymous_data,
			)
		) ) {
			return new WP_Error(
				'bp_rest_bbp_reply_duplicate',
				__( 'Duplicate reply detected; it looks as though you\'ve already said that!', 'buddyboss' ),
				array(
					'status' => 400,
				)
			);
		}

		/** Reply Blacklist */
		if ( ! bbp_check_for_blacklist( $anonymous_data, $reply_author, $reply_title, $reply_content ) ) {
			return new WP_Error(
				'bp_rest_bbp_reply_blacklist',
				__( 'Sorry, Your reply cannot be created at this time.', 'buddyboss' ),
				array(
					'status' => 400,
				)
			);
		}

		/** Reply Status */
		// Maybe put into moderation.
		if ( ! bbp_check_for_moderation( $anonymous_data, $reply_author, $reply_title, $reply_content ) ) {
			$reply_status = bbp_get_pending_status_id();

			// Default.
		} else {
			$reply_status = bbp_get_public_status_id();
		}

		/** Reply To */
		// Handle Reply To of the reply; $_REQUEST for non-JS submissions.
		if ( isset( $reply->bbp_reply_to ) ) {
			$reply_to = bbp_validate_reply_to( $reply->bbp_reply_to );
		}

		/** Topic Closed */
		// If topic is closed, moderators can still reply.
		if ( bbp_is_topic_closed( $topic_id ) && ! current_user_can( 'moderate' ) ) {
			return new WP_Error(
				'bp_rest_bbp_reply_topic_closed',
				__( 'Sorry, Discussion is closed.', 'buddyboss' ),
				array(
					'status' => 400,
				)
			);
		}

		/** Topic Tags */
		// Either replace terms.
		if ( bbp_allow_topic_tags() && current_user_can( 'assign_topic_tags' ) && ! empty( $reply->bbp_topic_tags ) ) {
			$terms = esc_attr( wp_strip_all_tags( $reply->bbp_topic_tags ) );

			// ...or remove them.
		} elseif ( isset( $reply->bbp_topic_tags ) ) {
			$terms = '';

			// Existing terms.
		} else {
			$terms = bbp_get_topic_tag_names( $topic_id );
		}

		/** Additional Actions (Before Save) */
		do_action( 'bbp_new_reply_pre_extras', $topic_id, $forum_id );

		// Bail if errors.
		if ( bbp_has_errors() ) {
			return;
		}

		/** No Errors */

		// Add the content of the form to $reply_data as an array.
		// Just in time manipulation of reply data before being created.
		$reply_data = apply_filters(
			'bbp_new_reply_pre_insert',
			array(
				'post_author'    => $reply_author,
				'post_title'     => $reply_title,
				'post_content'   => $reply_content,
				'post_status'    => $reply_status,
				'post_parent'    => $topic_id,
				'post_type'      => bbp_get_reply_post_type(),
				'comment_status' => 'closed',
				'menu_order'     => bbp_get_topic_reply_count( $topic_id, false ) + 1,
			)
		);

		// Insert reply.
		$reply_id = wp_insert_post( $reply_data );

		if ( empty( $reply_id ) || is_wp_error( $reply_id ) ) {
			$append_error = (
				( is_wp_error( $reply_id ) && $reply_id->get_error_message() )
				? __( 'The following problem(s) have been found with your reply: ', 'buddyboss' ) . $reply_id->get_error_message()
				: __( 'We are facing a problem to creating a reply.', 'buddyboss' )
			);

			return new WP_Error(
				'bp_rest_bbp_reply_error',
				$append_error,
				array(
					'status' => 400,
				)
			);
		}

		/** Topic Tags */
		// Just in time manipulation of reply terms before being edited.
		$terms = apply_filters( 'bbp_new_reply_pre_set_terms', $terms, $topic_id, $reply_id );

		// Insert terms.
		$terms = wp_set_post_terms( $topic_id, $terms, bbp_get_topic_tag_tax_id(), true );

		// Term error.
		if ( is_wp_error( $terms ) ) {
			return new WP_Error(
				'bp_rest_bbp_reply_tags',
				__( 'There was a problem adding the tags to the topic.', 'buddyboss' ),
				array(
					'status' => 400,
				)
			);
		}

		/** Trash Check */
		// If this reply starts as trash, add it to pre_trashed_replies.
		// for the topic, so it is properly restored.
		if ( bbp_is_topic_trash( $topic_id ) || ( bbp_get_trash_status_id() === $reply_data['post_status'] ) ) {

			// Trash the reply.
			wp_trash_post( $reply_id );

			// Only add to pre-trashed array if topic is trashed.
			if ( bbp_is_topic_trash( $topic_id ) ) {

				// Get pre_trashed_replies for topic.
				$pre_trashed_replies = (array) get_post_meta( $topic_id, '_bbp_pre_trashed_replies', true );

				// Add this reply to the end of the existing replies.
				$pre_trashed_replies[] = $reply_id;

				// Update the pre_trashed_reply post meta.
				update_post_meta( $topic_id, '_bbp_pre_trashed_replies', $pre_trashed_replies );
			}

			/** Spam Check */
			// If reply or topic are spam, officially spam this reply.
		} elseif ( bbp_is_topic_spam( $topic_id ) || ( bbp_get_spam_status_id() === $reply_data['post_status'] ) ) {
			add_post_meta( $reply_id, '_bbp_spam_meta_status', bbp_get_public_status_id() );

			// Only add to pre-spammed array if topic is spam.
			if ( bbp_is_topic_spam( $topic_id ) ) {

				// Get pre_spammed_replies for topic.
				$pre_spammed_replies = (array) get_post_meta( $topic_id, '_bbp_pre_spammed_replies', true );

				// Add this reply to the end of the existing replies.
				$pre_spammed_replies[] = $reply_id;

				// Update the pre_spammed_replies post meta.
				update_post_meta( $topic_id, '_bbp_pre_spammed_replies', $pre_spammed_replies );
			}
		}

		/** Update counts, etc... */
		do_action( 'bbp_new_reply', $reply_id, $topic_id, $forum_id, $anonymous_data, $reply_author, false, $reply_to );

		/** Additional Actions (After Save) */
		do_action( 'bbp_new_reply_post_extras', $reply_id );

		$reply         = get_post( $reply_id );
		$fields_update = $this->update_additional_fields_for_object( $reply, $request );

		if ( is_wp_error( $fields_update ) ) {
			return $fields_update;
		}

		/**
		 * Fires after a reply is created via the REST API.
		 *
		 * @param array           $reply    Created reply.
		 * @param array           $topic_id Reply's topic ID.
		 * @param array           $forum_id Reply's form ID.
		 * @param WP_REST_Request $request  The request sent to the API.
		 *
		 * @since 0.1.0
		 */
		do_action( 'bp_rest_reply_create_item', $reply, $topic_id, $forum_id, $request );

		return $this->get_item(
			array(
				'id'      => $reply_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.