BBP_Topics_Admin

Loads Forums topics admin area

Description

Source

File: bp-forums/admin/topics.php

class BBP_Topics_Admin {

	/** Variables *************************************************************/

	/**
	 * @var The post type of this admin component
	 */
	private $post_type = '';

	/** Functions *************************************************************/

	/**
	 * The main Forums topics admin loader
	 *
	 * @since bbPress (r2515)
	 *
	 * @uses BBP_Topics_Admin::setup_globals() Setup the globals needed
	 * @uses BBP_Topics_Admin::setup_actions() Setup the hooks and actions
	 * @uses BBP_Topics_Admin::setup_help() Setup the help text
	 */
	public function __construct() {
		$this->setup_globals();
		$this->setup_actions();
	}

	/**
	 * Setup the admin hooks, actions and filters
	 *
	 * @since bbPress (r2646)
	 * @access private
	 *
	 * @uses add_action() To add various actions
	 * @uses add_filter() To add various filters
	 * @uses bbp_get_forum_post_type() To get the forum post type
	 * @uses bbp_get_topic_post_type() To get the topic post type
	 * @uses bbp_get_reply_post_type() To get the reply post type
	 */
	private function setup_actions() {

		// Add some general styling to the admin area
		add_action( 'bbp_admin_head',        array( $this, 'admin_head'       ) );

		// Messages
		add_filter( 'post_updated_messages', array( $this, 'updated_messages' ) );

		// Topic column headers.
		add_filter( 'manage_' . $this->post_type . '_posts_columns',        array( $this, 'column_headers' ) );

		// Topic columns (in post row)
		add_action( 'manage_' . $this->post_type . '_posts_custom_column',  array( $this, 'column_data' ), 10, 2 );
		add_filter( 'post_row_actions',                                     array( $this, 'row_actions' ), 10, 2 );

		// Topic metabox actions
		add_action( 'add_meta_boxes', array( $this, 'attributes_metabox'      ) );
		add_action( 'save_post',      array( $this, 'attributes_metabox_save' ) );

		// Check if there are any bbp_toggle_topic_* requests on admin_init, also have a message displayed
		add_action( 'load-edit.php',  array( $this, 'toggle_topic'        ) );
		add_action( 'admin_notices',  array( $this, 'toggle_topic_notice' ) );

		// Anonymous metabox actions
		add_action( 'add_meta_boxes', array( $this, 'author_metabox'      ) );

		// Add ability to filter topics and replies per forum
		add_filter( 'restrict_manage_posts', array( $this, 'filter_dropdown'  ) );
		add_filter( 'bbp_request',           array( $this, 'filter_post_rows' ) );

		// Contextual Help
		add_action( 'load-edit.php',     array( $this, 'edit_help' ) );
		add_action( 'load-post.php',     array( $this, 'new_help'  ) );
		add_action( 'load-post-new.php', array( $this, 'new_help'  ) );
	}

	/**
	 * Should we bail out of this method?
	 *
	 * @since bbPress (r4067)
	 * @return boolean
	 */
	private function bail() {
		if ( !isset( get_current_screen()->post_type ) || ( $this->post_type !== get_current_screen()->post_type ) )
			return true;

		return false;
	}

	/**
	 * Admin globals
	 *
	 * @since bbPress (r2646)
	 * @access private
	 */
	private function setup_globals() {
		$this->post_type = bbp_get_topic_post_type();
	}

	/** Contextual Help *******************************************************/

	/**
	 * Contextual help for Forums topic edit page
	 *
	 * @since bbPress (r3119)
	 * @uses get_current_screen()
	 */
	public function edit_help() {

		if ( $this->bail() ) return;

		// Overview
		get_current_screen()->add_help_tab( array(
			'id'		=> 'overview',
			'title'		=> __( 'Overview', 'buddyboss' ),
			'content'	=>
				'<p>' . __( 'This screen displays the individual discussions on your site. You can customize the display of this screen to suit your workflow.', 'buddyboss' ) . '</p>'
		) );

		// Screen Content
		get_current_screen()->add_help_tab( array(
			'id'		=> 'screen-content',
			'title'		=> __( 'Screen Content', 'buddyboss' ),
			'content'	=>
				'<p>' . __( 'You can customize the display of this screen\'s contents in a number of ways:', 'buddyboss' ) . '</p>' .
				'<ul>' .
					'<li>' . __( 'You can hide/display columns based on your needs and decide how many discussions to list per screen using the Screen Options tab.',                                                                                                                                'buddyboss' ) . '</li>' .
					'<li>' . __( 'You can filter the list of discussions by discussion status using the text links in the upper left to show All, Published, or Trashed discussions. The default view is to show all discussions.',                                                                                 'buddyboss' ) . '</li>' .
					'<li>' . __( 'You can refine the list to show only discussions from a specific month by using the dropdown menus above the discussions list. Click the Filter button after making your selection. You also can refine the list by clicking on the discussion creator in the discussions list.', 'buddyboss' ) . '</li>' .
				'</ul>'
		) );

		// Available Actions
		get_current_screen()->add_help_tab( array(
			'id'		=> 'action-links',
			'title'		=> __( 'Available Actions', 'buddyboss' ),
			'content'	=>
				'<p>' . __( 'Hovering over a row in the discussions list will display action links that allow you to manage your discussion. You can perform the following actions:', 'buddyboss' ) . '</p>' .
				'<ul>' .
					'<li>' . __( '<strong>Edit</strong> takes you to the editing screen for that discussion. You can also reach that screen by clicking on the discussion title.',                                                                                 'buddyboss' ) . '</li>' .
					'<li>' . __( '<strong>Trash</strong> removes your discussion from this list and places it in the trash, from which you can permanently delete it.',                                                                                       'buddyboss' ) . '</li>' .
					'<li>' . __( '<strong>Spam</strong> removes your discussion from this list and places it in the spam queue, from which you can permanently delete it.',                                                                                   'buddyboss' ) . '</li>' .
					'<li>' . __( '<strong>Preview</strong> will show you what your draft discussion will look like if you publish it. View will take you to your live site to view the discussion. Which link is available depends on your discussion\'s status.', 'buddyboss' ) . '</li>' .
					'<li>' . __( '<strong>Close</strong> will mark the selected discussion as "closed" and disable the option to post new replies to the discussion.',                                                                                 'buddyboss' ) . '</li>' .
					'<li>' . __( '<strong>Stick</strong> will keep the selected discussion "pinned" to the top the parent forum discussion list.',                                                                                                     'buddyboss' ) . '</li>' .
					'<li>' . __( '<strong>Stick <em>(to front)</em></strong> will keep the selected discussion "pinned" to the top of ALL forums and be visable in any forums discussions list.',                                                      'buddyboss' ) . '</li>' .
				'</ul>'
		) );

		// Bulk Actions
		get_current_screen()->add_help_tab( array(
			'id'		=> 'bulk-actions',
			'title'		=> __( 'Bulk Actions', 'buddyboss' ),
			'content'	=>
				'<p>' . __( 'You can also edit or move multiple discussions to the trash at once. Select the discussions you want to act on using the checkboxes, then select the action you want to take from the Bulk Actions menu and click Apply.',           'buddyboss' ) . '</p>' .
				'<p>' . __( 'When using Bulk Edit, you can change the status (Published, Private, etc.) and add discussion tags for all selected discussions at once. To remove a discussion from the grouping, just click the x next to its name in the Bulk Edit area that appears.', 'buddyboss' ) . '</p>'
		) );

		// Help Sidebar
		get_current_screen()->set_help_sidebar(
			'<p><strong>' . __( 'For more information:', 'buddyboss' ) . '</strong></p>' .
			'<p>' . __( '<a href="https://www.buddyboss.com/resources/">Documentation</a>',     'buddyboss' ) . '</p>'
		);
	}

	/**
	 * Contextual help for Forums topic edit page
	 *
	 * @since bbPress (r3119)
	 * @uses get_current_screen()
	 */
	public function new_help() {

		if ( $this->bail() ) return;

		$customize_display = '<p>' . __( 'The title field and the big discussion editing Area are fixed in place, but you can reposition all the other boxes using drag and drop, and can minimize or expand them by clicking the title bar of each box. Use the Screen Options tab to unhide more boxes (Excerpt, Send Trackbacks, Custom Fields, Discussion, Slug, Author) or to choose a 1- or 2-column layout for this screen.', 'buddyboss' ) . '</p>';

		get_current_screen()->add_help_tab( array(
			'id'      => 'customize-display',
			'title'   => __( 'Customizing This Display', 'buddyboss' ),
			'content' => $customize_display,
		) );

		get_current_screen()->add_help_tab( array(
			'id'      => 'title-topic-editor',
			'title'   => __( 'Title and Discussion Editor', 'buddyboss' ),
			'content' =>
				'<p>' . __( '<strong>Title</strong> - Enter a title for your discussion. After you enter a title, you\'ll see the permalink below, which you can edit.', 'buddyboss' ) . '</p>' .
				'<p>' . __( '<strong>Discussion Editor</strong> - Enter the text for your discussion. There are two modes of editing: Visual and HTML. Choose the mode by clicking on the appropriate tab. Visual mode gives you a WYSIWYG editor. Click the last icon in the row to get a second row of controls. The HTML mode allows you to enter raw HTML along with your discussion text. You can insert media files by clicking the icons above the discussion editor and following the directions. You can go to the distraction-free writing screen via the Fullscreen icon in Visual mode (second to last in the top row) or the Fullscreen button in HTML mode (last in the row). Once there, you can make buttons visible by hovering over the top area. Exit Fullscreen back to the regular discussion editor.', 'buddyboss' ) . '</p>'
		) );

		$publish_box = '<p>' . __( '<strong>Publish</strong> - You can set the terms of publishing your discussion in the Publish box. For Status, Visibility, and Publish (immediately), click on the Edit link to reveal more options. Visibility includes options for password-protecting a discussion or making it stay at the top of your blog indefinitely (sticky). Publish (immediately) allows you to set a future or past date and time, so you can schedule a discussion to be published in the future or backdate a discussion.', 'buddyboss' ) . '</p>';

		if ( current_theme_supports( 'topic-thumbnails' ) && post_type_supports( 'topic', 'thumbnail' ) ) {
			$publish_box .= '<p>' . __( '<strong>Featured Image</strong> - This allows you to associate an image with your discussion without inserting it. This is usually useful only if your theme makes use of the featured image as a discussion thumbnail on the home page, a custom header, etc.', 'buddyboss' ) . '</p>';
		}

		get_current_screen()->add_help_tab( array(
			'id'      => 'topic-attributes',
			'title'   => __( 'Discussion Attributes', 'buddyboss' ),
			'content' =>
				'<p>' . __( 'Select the attributes that your discussion should have:', 'buddyboss' ) . '</p>' .
				'<ul>' .
					'<li>' . __( '<strong>Forum</strong> dropdown determines the parent forum that the discussion belongs to. Select the forum or category from the dropdown, or leave the default (No Forum) to post the discussion without an assigned forum.', 'buddyboss' ) . '</li>' .
					'<li>' . __( '<strong>Discussion Type</strong> dropdown indicates the sticky status of the discussion. Selecting the super sticky option would stick the discussion to the front of your forums, i.e. the discussion index, sticky option would stick the discussion to its respective forum. Selecting normal would not stick the discussion anywhere.', 'buddyboss' ) . '</li>' .
				'</ul>'
		) );

		get_current_screen()->add_help_tab( array(
			'id'      => 'publish-box',
			'title'   => __( 'Publish Box', 'buddyboss' ),
			'content' => $publish_box,
		) );

		get_current_screen()->set_help_sidebar(
			'<p><strong>' . __( 'For more information:', 'buddyboss' ) . '</strong></p>' .
			'<p>' . __( '<a href="https://www.buddyboss.com/resources/">Documentation</a>',     'buddyboss' ) . '</p>'
		);
	}

	/**
	 * Add the topic attributes metabox
	 *
	 * @since bbPress (r2744)
	 *
	 * @uses bbp_get_topic_post_type() To get the topic post type
	 * @uses add_meta_box() To add the metabox
	 * @uses do_action() Calls 'bbp_topic_attributes_metabox'
	 */
	public function attributes_metabox() {

		if ( $this->bail() ) return;

		add_meta_box (
			'bbp_topic_attributes',
			__( 'Discussion Attributes', 'buddyboss' ),
			'bbp_topic_metabox',
			$this->post_type,
			'side',
			'high'
		);

		do_action( 'bbp_topic_attributes_metabox' );
	}

	/**
	 * Pass the topic attributes for processing
	 *
	 * @since bbPress (r2746)
	 *
	 * @param int $topic_id Topic id
	 * @uses current_user_can() To check if the current user is capable of
	 *                           editing the topic
	 * @uses do_action() Calls 'bbp_topic_attributes_metabox_save' with the
	 *                    topic id and parent id
	 * @return int Parent id
	 */
	public function attributes_metabox_save( $topic_id ) {

		if ( $this->bail() ) return $topic_id;

		// Bail if doing an autosave
		if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
			return $topic_id;

		// Bail if not a post request
		if ( ! bbp_is_post_request() )
			return $topic_id;

		// Nonce check
		if ( empty( $_POST['bbp_topic_metabox'] ) || !wp_verify_nonce( $_POST['bbp_topic_metabox'], 'bbp_topic_metabox_save' ) )
			return $topic_id;

		// Bail if current user cannot edit this topic
		if ( !current_user_can( 'edit_topic', $topic_id ) )
			return $topic_id;

		// Get the forum ID
		$forum_id = !empty( $_POST['parent_id'] ) ? (int) $_POST['parent_id'] : 0;

		// Get topic author data
		$anonymous_data = bbp_filter_anonymous_post_data();
		$author_id      = bbp_get_topic_author_id( $topic_id );
		$is_edit        = (bool) isset( $_POST['save'] );

		// Formally update the topic
		bbp_update_topic( $topic_id, $forum_id, $anonymous_data, $author_id, $is_edit );

		// Stickies
		if ( !empty( $_POST['bbp_stick_topic'] ) && in_array( $_POST['bbp_stick_topic'], array( 'stick', 'super', 'unstick' ) ) ) {

			// What's the haps?
			switch ( $_POST['bbp_stick_topic'] ) {

				// Sticky in this forum
				case 'stick'   :
					bbp_stick_topic( $topic_id );
					break;

				// Super sticky in all forums
				case 'super'   :
					bbp_stick_topic( $topic_id, true );
					break;

				// Normal
				case 'unstick' :
				default        :
					bbp_unstick_topic( $topic_id );
					break;
			}
		}

		// Allow other fun things to happen
		do_action( 'bbp_topic_attributes_metabox_save', $topic_id, $forum_id       );
		do_action( 'bbp_author_metabox_save',           $topic_id, $anonymous_data );

		return $topic_id;
	}

	/**
	 * Add the author info metabox
	 *
	 * @since bbPress (r2828)
	 *
	 * @uses bbp_get_topic() To get the topic
	 * @uses bbp_get_reply() To get the reply
	 * @uses bbp_get_topic_post_type() To get the topic post type
	 * @uses bbp_get_reply_post_type() To get the reply post type
	 * @uses add_meta_box() To add the metabox
	 * @uses do_action() Calls 'bbp_author_metabox' with the topic/reply
	 *                    id
	 */
	public function author_metabox() {

		if ( $this->bail() ) return;

		// Bail if post_type is not a topic
		if ( empty( $_GET['action'] ) || ( 'edit' !== $_GET['action'] ) )
			return;

		// Add the metabox
		add_meta_box(
			'bbp_author_metabox',
			__( 'Author Information', 'buddyboss' ),
			'bbp_author_metabox',
			$this->post_type,
			'side',
			'high'
		);

		do_action( 'bbp_author_metabox', get_the_ID() );
	}

	/**
	 * Add some general styling to the admin area
	 *
	 * @since bbPress (r2464)
	 *
	 * @uses bbp_get_forum_post_type() To get the forum post type
	 * @uses bbp_get_topic_post_type() To get the topic post type
	 * @uses bbp_get_reply_post_type() To get the reply post type
	 * @uses sanitize_html_class() To sanitize the classes
	 * @uses do_action() Calls 'bbp_admin_head'
	 */
	public function admin_head() {

		if ( $this->bail() ) return;

		?>

		<style media="screen">
		/*<![CDATA[*/

			strong.label {
				display: inline-block;
				width: 60px;
			}

			.column-bbp_forum_topic_count,
			.column-bbp_forum_reply_count,
			.column-bbp_topic_reply_count,
			.column-bbp_topic_voice_count {
				width: 8% !important;
			}

			.column-author,
			.column-bbp_reply_author,
			.column-bbp_topic_author {
				width: 10% !important;
			}

			.column-bbp_topic_forum,
			.column-bbp_reply_forum,
			.column-bbp_reply_topic {
				width: 10% !important;
			}

			.column-bbp_forum_freshness,
			.column-bbp_topic_freshness {
				width: 10% !important;
			}

			.column-bbp_forum_created,
			.column-bbp_topic_created,
			.column-bbp_reply_created {
				width: 15% !important;
			}

			.status-closed {
				background-color: #eaeaea;
			}

			.status-spam {
				background-color: #faeaea;
			}

		/*]]>*/
		</style>

		<?php
	}

	/**
	 * Toggle topic
	 *
	 * Handles the admin-side opening/closing, sticking/unsticking and
	 * spamming/unspamming of topics
	 *
	 * @since bbPress (r2727)
	 *
	 * @uses bbp_get_topic() To get the topic
	 * @uses current_user_can() To check if the user is capable of editing
	 *                           the topic
	 * @uses wp_die() To die if the user isn't capable or the post wasn't
	 *                 found
	 * @uses check_admin_referer() To verify the nonce and check referer
	 * @uses bbp_is_topic_open() To check if the topic is open
	 * @uses bbp_close_topic() To close the topic
	 * @uses bbp_open_topic() To open the topic
	 * @uses bbp_is_topic_sticky() To check if the topic is a sticky or
	 *                              super sticky
	 * @uses bbp_unstick_topic() To unstick the topic
	 * @uses bbp_stick_topic() To stick the topic
	 * @uses bbp_is_topic_spam() To check if the topic is marked as spam
	 * @uses bbp_unspam_topic() To unmark the topic as spam
	 * @uses bbp_spam_topic() To mark the topic as spam
	 * @uses do_action() Calls 'bbp_toggle_topic_admin' with success, post
	 *                    data, action and message
	 * @uses add_query_arg() To add custom args to the url
	 * @uses wp_safe_redirect() Redirect the page to custom url
	 */
	public function toggle_topic() {

		if ( $this->bail() ) return;

		// Only proceed if GET is a topic toggle action
		if ( bbp_is_get_request() && !empty( $_GET['action'] ) && in_array( $_GET['action'], array( 'bbp_toggle_topic_close', 'bbp_toggle_topic_stick', 'bbp_toggle_topic_spam' ) ) && !empty( $_GET['topic_id'] ) ) {
			$action    = $_GET['action'];            // What action is taking place?
			$topic_id  = (int) $_GET['topic_id'];    // What's the topic id?
			$success   = false;                      // Flag
			$post_data = array( 'ID' => $topic_id ); // Prelim array
			$topic     = bbp_get_topic( $topic_id );

			// Bail if topic is missing
			if ( empty( $topic ) )
				wp_die( __( 'The discussion was not found!', 'buddyboss' ) );

			if ( !current_user_can( 'moderate', $topic->ID ) ) // What is the user doing here?
				wp_die( __( 'You do not have the permission to do that!', 'buddyboss' ) );

			switch ( $action ) {
				case 'bbp_toggle_topic_close' :
					check_admin_referer( 'close-topic_' . $topic_id );

					$is_open = bbp_is_topic_open( $topic_id );
					$message = true === $is_open ? 'closed' : 'opened';
					$success = true === $is_open ? bbp_close_topic( $topic_id ) : bbp_open_topic( $topic_id );

					break;

				case 'bbp_toggle_topic_stick' :
					check_admin_referer( 'stick-topic_' . $topic_id );

					$is_sticky = bbp_is_topic_sticky( $topic_id );
					$is_super  = false === $is_sticky && !empty( $_GET['super'] ) && ( "1" === $_GET['super'] ) ? true : false;
					$message   = true  === $is_sticky ? 'unsticked'     : 'sticked';
					$message   = true  === $is_super  ? 'super_sticked' : $message;
					$success   = true  === $is_sticky ? bbp_unstick_topic( $topic_id ) : bbp_stick_topic( $topic_id, $is_super );

					break;

				case 'bbp_toggle_topic_spam'  :
					check_admin_referer( 'spam-topic_' . $topic_id );

					$is_spam = bbp_is_topic_spam( $topic_id );
					$message = true === $is_spam ? 'unspammed' : 'spammed';
					$success = true === $is_spam ? bbp_unspam_topic( $topic_id ) : bbp_spam_topic( $topic_id );

					break;
			}

			$message = array( 'bbp_topic_toggle_notice' => $message, 'topic_id' => $topic->ID );

			if ( false === $success || is_wp_error( $success ) )
				$message['failed'] = '1';

			// Do additional topic toggle actions (admin side)
			do_action( 'bbp_toggle_topic_admin', $success, $post_data, $action, $message );

			// Redirect back to the topic
			$redirect = add_query_arg( $message, remove_query_arg( array( 'action', 'topic_id' ) ) );
			wp_safe_redirect( $redirect );

			// For good measure
			exit();
		}
	}

	/**
	 * Toggle topic notices
	 *
	 * Display the success/error notices from
	 * {@link BBP_Admin::toggle_topic()}
	 *
	 * @since bbPress (r2727)
	 *
	 * @uses bbp_get_topic() To get the topic
	 * @uses bbp_get_topic_title() To get the topic title of the topic
	 * @uses esc_html() To sanitize the topic title
	 * @uses apply_filters() Calls 'bbp_toggle_topic_notice_admin' with
	 *                        message, topic id, notice and is it a failure
	 */
	public function toggle_topic_notice() {

		if ( $this->bail() ) return;

		// Only proceed if GET is a topic toggle action
		if ( bbp_is_get_request() && !empty( $_GET['bbp_topic_toggle_notice'] ) && in_array( $_GET['bbp_topic_toggle_notice'], array( 'opened', 'closed', 'super_sticked', 'sticked', 'unsticked', 'spammed', 'unspammed' ) ) && !empty( $_GET['topic_id'] ) ) {
			$notice     = $_GET['bbp_topic_toggle_notice'];         // Which notice?
			$topic_id   = (int) $_GET['topic_id'];                  // What's the topic id?
			$is_failure = !empty( $_GET['failed'] ) ? true : false; // Was that a failure?

			// Bais if no topic_id or notice
			if ( empty( $notice ) || empty( $topic_id ) )
				return;

			// Bail if topic is missing
			$topic = bbp_get_topic( $topic_id );
			if ( empty( $topic ) )
				return;

			$topic_title = bbp_get_topic_title( $topic->ID );

			switch ( $notice ) {
				case 'opened'    :
					$message = $is_failure === true ? sprintf( __( 'There was a problem opening the discussion "%1$s".',           'buddyboss' ), $topic_title ) : sprintf( __( 'Discussion "%1$s" successfully opened.',           'buddyboss' ), $topic_title );
					break;

				case 'closed'    :
					$message = $is_failure === true ? sprintf( __( 'There was a problem closing the discussion "%1$s".',           'buddyboss' ), $topic_title ) : sprintf( __( 'Discussion "%1$s" successfully closed.',           'buddyboss' ), $topic_title );
					break;

				case 'super_sticked' :
					$message = $is_failure === true ? sprintf( __( 'There was a problem sticking the discussion "%1$s" to front.', 'buddyboss' ), $topic_title ) : sprintf( __( 'Discussion "%1$s" successfully sticked to front.', 'buddyboss' ), $topic_title );
					break;

				case 'sticked'   :
					$message = $is_failure === true ? sprintf( __( 'There was a problem sticking the discussion "%1$s".',          'buddyboss' ), $topic_title ) : sprintf( __( 'Discussion "%1$s" successfully sticked.',          'buddyboss' ), $topic_title );
					break;

				case 'unsticked' :
					$message = $is_failure === true ? sprintf( __( 'There was a problem unsticking the discussion "%1$s".',        'buddyboss' ), $topic_title ) : sprintf( __( 'Discussion "%1$s" successfully unsticked.',        'buddyboss' ), $topic_title );
					break;

				case 'spammed'   :
					$message = $is_failure === true ? sprintf( __( 'There was a problem marking the discussion "%1$s" as spam.',   'buddyboss' ), $topic_title ) : sprintf( __( 'Discussion "%1$s" successfully marked as spam.',   'buddyboss' ), $topic_title );
					break;

				case 'unspammed' :
					$message = $is_failure === true ? sprintf( __( 'There was a problem unmarking the discussion "%1$s" as spam.', 'buddyboss' ), $topic_title ) : sprintf( __( 'Discussion "%1$s" successfully unmarked as spam.', 'buddyboss' ), $topic_title );
					break;
			}

			// Do additional topic toggle notice filters (admin side)
			$message = apply_filters( 'bbp_toggle_topic_notice_admin', $message, $topic->ID, $notice, $is_failure );

			?>

			<div id="message" class="<?php echo $is_failure === true ? 'error' : 'updated'; ?> fade">
				<p style="line-height: 150%"><?php echo esc_html( $message ); ?></p>
			</div>

			<?php
		}
	}

	/**
	 * Manage the column headers for the topics page
	 *
	 * @since bbPress (r2485)
	 *
	 * @param array $columns The columns
	 * @uses apply_filters() Calls 'bbp_admin_topics_column_headers' with
	 *                        the columns
	 * @return array $columns Forums topic columns
	 */
	public function column_headers( $columns ) {

		if ( $this->bail() ) return $columns;

		$columns = array(
			'cb'                    => '<input type="checkbox" />',
			'title'                 => __( 'Discussions',  'buddyboss' ),
			'bbp_topic_forum'       => __( 'Forum',        'buddyboss' ),
			'bbp_topic_reply_count' => __( 'Replies',      'buddyboss' ),
			'bbp_topic_voice_count' => __( 'Members',      'buddyboss' ),
			'bbp_topic_author'      => __( 'Author',       'buddyboss' ),
			'bbp_topic_created'     => __( 'Created',      'buddyboss' ),
			'bbp_topic_freshness'   => __( 'Last Post',    'buddyboss' )
		);

		return apply_filters( 'bbp_admin_topics_column_headers', $columns );
	}

	/**
	 * Print extra columns for the topics page
	 *
	 * @since bbPress (r2485)
	 *
	 * @param string $column Column
	 * @param int $topic_id Topic id
	 * @uses bbp_get_topic_forum_id() To get the forum id of the topic
	 * @uses bbp_forum_title() To output the topic's forum title
	 * @uses apply_filters() Calls 'topic_forum_row_actions' with an array
	 *                        of topic forum actions
	 * @uses bbp_get_forum_permalink() To get the forum permalink
	 * @uses admin_url() To get the admin url of post.php
	 * @uses bbp_topic_reply_count() To output the topic reply count
	 * @uses bbp_topic_voice_count() To output the topic voice count
	 * @uses bbp_topic_author_display_name() To output the topic author name
	 * @uses get_the_date() Get the topic creation date
	 * @uses get_the_time() Get the topic creation time
	 * @uses esc_attr() To sanitize the topic creation time
	 * @uses bbp_get_topic_last_active_time() To get the time when the topic was
	 *                                    last active
	 * @uses do_action() Calls 'bbp_admin_topics_column_data' with the
	 *                    column and topic id
	 */
	public function column_data( $column, $topic_id ) {

		if ( $this->bail() ) return;

		// Get topic forum ID
		$forum_id = bbp_get_topic_forum_id( $topic_id );

		// Populate column data
		switch ( $column ) {

			// Forum
			case 'bbp_topic_forum' :

				// Output forum name
				if ( !empty( $forum_id ) ) {

					// Forum Title
					$forum_title = bbp_get_forum_title( $forum_id );
					if ( empty( $forum_title ) ) {
						$forum_title = esc_html__( 'No Forum', 'buddyboss' );
					}

					// Output the title
					echo $forum_title;

				} else {
					esc_html_e( '(No Forum)', 'buddyboss' );
				}

				break;

			// Reply Count
			case 'bbp_topic_reply_count' :
				bbp_topic_reply_count( $topic_id );
				break;

			// Reply Count
			case 'bbp_topic_voice_count' :
				bbp_topic_voice_count( $topic_id );
				break;

			// Author
			case 'bbp_topic_author' :
				bbp_topic_author_display_name( $topic_id );
				break;

			// Freshness
			case 'bbp_topic_created':
				printf( '%1$s <br /> %2$s',
					get_the_date(),
					esc_attr( get_the_time() )
				);

				break;

			// Freshness
			case 'bbp_topic_freshness' :
				$last_active = bbp_get_topic_last_active_time( $topic_id, false );
				if ( !empty( $last_active ) ) {
					echo esc_html( $last_active );
				} else {
					esc_html_e( 'No Replies', 'buddyboss' ); // This should never happen
				}

				break;

			// Do an action for anything else
			default :
				do_action( 'bbp_admin_topics_column_data', $column, $topic_id );
				break;
		}
	}

	/**
	 * Topic Row actions
	 *
	 * Remove the quick-edit action link under the topic title and add the
	 * content and close/stick/spam links
	 *
	 * @since bbPress (r2485)
	 *
	 * @param array $actions Actions
	 * @param array $topic Topic object
	 * @uses bbp_get_topic_post_type() To get the topic post type
	 * @uses bbp_topic_content() To output topic content
	 * @uses bbp_get_topic_permalink() To get the topic link
	 * @uses bbp_get_topic_title() To get the topic title
	 * @uses current_user_can() To check if the current user can edit or
	 *                           delete the topic
	 * @uses bbp_is_topic_open() To check if the topic is open
	 * @uses bbp_is_topic_spam() To check if the topic is marked as spam
	 * @uses bbp_is_topic_sticky() To check if the topic is a sticky or a
	 *                              super sticky
	 * @uses get_post_type_object() To get the topic post type object
	 * @uses add_query_arg() To add custom args to the url
	 * @uses remove_query_arg() To remove custom args from the url
	 * @uses wp_nonce_url() To nonce the url
	 * @uses get_delete_post_link() To get the delete post link of the topic
	 * @return array $actions Actions
	 */
	public function row_actions( $actions, $topic ) {

		if ( $this->bail() ) return $actions;

		unset( $actions['inline hide-if-no-js'] );
		
		//simple hack to show the discussion content
		bbp_topic_content( $topic->ID );

		// Show view link if it's not set, the topic is trashed and the user can view trashed topics
		if ( empty( $actions['view'] ) && ( bbp_get_trash_status_id() === $topic->post_status ) && current_user_can( 'view_trash' ) )
			$actions['view'] = '<a href="' . esc_url( bbp_get_topic_permalink( $topic->ID ) ) . '" title="' . esc_attr( sprintf( __( 'View "%s"', 'buddyboss' ), bbp_get_topic_title( $topic->ID ) ) ) . '" rel="permalink">' . esc_html__( 'View', 'buddyboss' ) . '</a>';

		// Only show the actions if the user is capable of viewing them :)
		if ( current_user_can( 'moderate', $topic->ID ) ) {

			// Close
			// Show the 'close' and 'open' link on published and closed posts only
			if ( in_array( $topic->post_status, array( bbp_get_public_status_id(), bbp_get_closed_status_id() ) ) ) {
				$close_uri = wp_nonce_url( add_query_arg( array( 'topic_id' => $topic->ID, 'action' => 'bbp_toggle_topic_close' ), remove_query_arg( array( 'bbp_topic_toggle_notice', 'topic_id', 'failed', 'super' ) ) ), 'close-topic_' . $topic->ID );
				if ( bbp_is_topic_open( $topic->ID ) )
					$actions['closed'] = '<a href="' . esc_url( $close_uri ) . '" title="' . esc_attr__( 'Close this discussion', 'buddyboss' ) . '">' . __( 'Close', 'buddyboss' ) . '</a>';
				else
					$actions['closed'] = '<a href="' . esc_url( $close_uri ) . '" title="' . esc_attr__( 'Open this discussion',  'buddyboss' ) . '">' . __( 'Open', 'buddyboss' ) . '</a>';
			}

			// Dont show sticky if topic links is spam or trash
			if ( !bbp_is_topic_spam( $topic->ID ) && !bbp_is_topic_trash( $topic->ID ) ) {

				// Sticky
				$stick_uri  = wp_nonce_url( add_query_arg( array( 'topic_id' => $topic->ID, 'action' => 'bbp_toggle_topic_stick' ), remove_query_arg( array( 'bbp_topic_toggle_notice', 'topic_id', 'failed', 'super' ) ) ), 'stick-topic_'  . $topic->ID );
				if ( bbp_is_topic_sticky( $topic->ID ) ) {
					$actions['stick'] = '<a href="' . esc_url( $stick_uri ) . '" title="' . esc_attr__( 'Unstick this discussion', 'buddyboss' ) . '">' . esc_html__( 'Unstick', 'buddyboss' ) . '</a>';
				} else {
					$super_uri        = wp_nonce_url( add_query_arg( array( 'topic_id' => $topic->ID, 'action' => 'bbp_toggle_topic_stick', 'super' => '1' ), remove_query_arg( array( 'bbp_topic_toggle_notice', 'topic_id', 'failed', 'super' ) ) ), 'stick-topic_'  . $topic->ID );
					$actions['stick'] = '<a href="' . esc_url( $stick_uri ) . '" title="' . esc_attr__( 'Stick this discussion to its forum', 'buddyboss' ) . '">' . esc_html__( 'Stick', 'buddyboss' ) . '</a> <a href="' . esc_url( $super_uri ) . '" title="' . esc_attr__( 'Stick this discussion to front', 'buddyboss' ) . '">' . esc_html__( '(to front)', 'buddyboss' ) . '</a>';
				}
			}

			// Spam
			$spam_uri  = wp_nonce_url( add_query_arg( array( 'topic_id' => $topic->ID, 'action' => 'bbp_toggle_topic_spam' ), remove_query_arg( array( 'bbp_topic_toggle_notice', 'topic_id', 'failed', 'super' ) ) ), 'spam-topic_'  . $topic->ID );
			if ( bbp_is_topic_spam( $topic->ID ) )
				$actions['spam'] = '<a href="' . esc_url( $spam_uri ) . '" title="' . esc_attr__( 'Mark the discussion as not spam', 'buddyboss' ) . '">' . esc_html__( 'Not spam', 'buddyboss' ) . '</a>';
			else
				$actions['spam'] = '<a href="' . esc_url( $spam_uri ) . '" title="' . esc_attr__( 'Mark this discussion as spam',    'buddyboss' ) . '">' . esc_html__( 'Spam',     'buddyboss' ) . '</a>';

		}

		// Do not show trash links for spam topics, or spam links for trashed topics
		if ( current_user_can( 'delete_topic', $topic->ID ) ) {
			if ( bbp_get_trash_status_id() === $topic->post_status ) {
				$post_type_object   = get_post_type_object( bbp_get_topic_post_type() );
				$actions['untrash'] = "<a title='" . esc_attr__( 'Restore this item from the Trash', 'buddyboss' ) . "' href='" . esc_url( wp_nonce_url( add_query_arg( array( '_wp_http_referer' => add_query_arg( array( 'post_type' => bbp_get_topic_post_type() ), admin_url( 'edit.php' ) ) ), admin_url( sprintf( $post_type_object->_edit_link . '&amp;action=untrash', $topic->ID ) ) ), 'untrash-' . $topic->post_type . '_' . $topic->ID ) ) . "'>" . esc_html__( 'Restore', 'buddyboss' ) . "</a>";
			} elseif ( EMPTY_TRASH_DAYS ) {
				$actions['trash'] = "<a class='submitdelete' title='" . esc_attr__( 'Move this item to the Trash', 'buddyboss' ) . "' href='" . esc_url( add_query_arg( array( '_wp_http_referer' => add_query_arg( array( 'post_type' => bbp_get_topic_post_type() ), admin_url( 'edit.php' ) ) ), get_delete_post_link( $topic->ID ) ) ) . "'>" . esc_html__( 'Trash', 'buddyboss' ) . "</a>";
			}

			if ( bbp_get_trash_status_id() === $topic->post_status || !EMPTY_TRASH_DAYS ) {
				$actions['delete'] = "<a class='submitdelete' title='" . esc_attr__( 'Delete this item permanently', 'buddyboss' ) . "' href='" . esc_url( add_query_arg( array( '_wp_http_referer' => add_query_arg( array( 'post_type' => bbp_get_topic_post_type() ), admin_url( 'edit.php' ) ) ), get_delete_post_link( $topic->ID, '', true ) ) ) . "'>" . esc_html__( 'Delete Permanently', 'buddyboss' ) . "</a>";
			} elseif ( bbp_get_spam_status_id() === $topic->post_status ) {
				unset( $actions['trash'] );
			}
		}

		return $actions;
	}

	/**
	 * Add forum dropdown to topic and reply list table filters
	 *
	 * @since bbPress (r2991)
	 *
	 * @uses bbp_get_reply_post_type() To get the reply post type
	 * @uses bbp_get_topic_post_type() To get the topic post type
	 * @uses bbp_dropdown() To generate a forum dropdown
	 * @return bool False. If post type is not topic or reply
	 */
	public function filter_dropdown() {

		if ( $this->bail() ) return;

		// Add Empty Spam button
		if ( !empty( $_GET['post_status'] ) && ( bbp_get_spam_status_id() === $_GET['post_status'] ) && current_user_can( 'moderate' ) ) {
			wp_nonce_field( 'bulk-destroy', '_destroy_nonce' );
			$title = esc_attr__( 'Empty Spam', 'buddyboss' );
			submit_button( $title, 'button-secondary apply', 'delete_all', false );
		}

		// Get which forum is selected
		$selected = !empty( $_GET['bbp_forum_id'] ) ? $_GET['bbp_forum_id'] : '';

		// Show the forums dropdown
		bbp_dropdown( array(
			'selected'  => $selected,
			'show_none' => __( 'In all forums', 'buddyboss' )
		) );
	}

	/**
	 * Adjust the request query and include the forum id
	 *
	 * @since bbPress (r2991)
	 *
	 * @param array $query_vars Query variables from {@link WP_Query}
	 * @uses is_admin() To check if it's the admin section
	 * @uses bbp_get_topic_post_type() To get the topic post type
	 * @uses bbp_get_reply_post_type() To get the reply post type
	 * @return array Processed Query Vars
	 */
	function filter_post_rows( $query_vars ) {

		if ( $this->bail() ) return $query_vars;

		// Add post_parent query_var if one is present
		if ( !empty( $_GET['bbp_forum_id'] ) ) {
			$query_vars['meta_key']   = '_bbp_forum_id';
			$query_vars['meta_value'] = $_GET['bbp_forum_id'];
		}

		// Return manipulated query_vars
		return $query_vars;
	}

	/**
	 * Custom user feedback messages for topic post type
	 *
	 * @since bbPress (r3080)
	 *
	 * @global int $post_ID
	 * @uses bbp_get_topic_permalink()
	 * @uses wp_post_revision_title()
	 * @uses esc_url()
	 * @uses add_query_arg()
	 *
	 * @param array $messages
	 *
	 * @return array
	 */
	public function updated_messages( $messages ) {
		global $post_ID;

		if ( $this->bail() ) return $messages;

		// URL for the current topic
		$topic_url = bbp_get_topic_permalink( $post_ID );

		// Current topic's post_date
		$post_date = bbp_get_global_post_field( 'post_date', 'raw' );

		// Messages array
		$messages[$this->post_type] = array(
			0 =>  '', // Left empty on purpose

			// Updated
			1 =>  sprintf( __( 'Discussion updated. <a href="%s">View discussion</a>', 'buddyboss' ), $topic_url ),

			// Custom field updated
			2 => __( 'Custom field updated.', 'buddyboss' ),

			// Custom field deleted
			3 => __( 'Custom field deleted.', 'buddyboss' ),

			// Discussion updated
			4 => __( 'Discussion updated.', 'buddyboss' ),

			// Restored from revision
			// translators: %s: date and time of the revision
			5 => isset( $_GET['revision'] )
					? sprintf( __( 'Discussion restored to revision from %s', 'buddyboss' ), wp_post_revision_title( (int) $_GET['revision'], false ) )
					: false,

			// Discussion created
			6 => sprintf( __( 'Discussion created. <a href="%s">View discussion</a>', 'buddyboss' ), $topic_url ),

			// Discussion saved
			7 => __( 'Discussion saved.', 'buddyboss' ),

			// Discussion submitted
			8 => sprintf( __( 'Discussion submitted. <a target="_blank" href="%s">Preview discussion</a>', 'buddyboss' ), esc_url( add_query_arg( 'preview', 'true', $topic_url ) ) ),

			// Discussion scheduled
			9 => sprintf( __( 'Discussion scheduled for: <strong>%1$s</strong>. <a target="_blank" href="%2$s">Preview discussion</a>', 'buddyboss' ),
					// translators: Publish box date format, see http://php.net/date
					date_i18n( __( 'M j, Y @ G:i', 'buddyboss' ),
					strtotime( $post_date ) ),
					$topic_url ),

			// Discussion draft updated
			10 => sprintf( __( 'Discussion draft updated. <a target="_blank" href="%s">Preview discussion</a>', 'buddyboss' ), esc_url( add_query_arg( 'preview', 'true', $topic_url ) ) ),
		);

		return $messages;
	}
}

Changelog

Changelog
Version Description
bbPress (r2464) Introduced.

Methods

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.