PluginProbe
bbPress / 2.6.6
bbPress v2.6.6
2.6.17 trunk 2.0 2.0-beta-1 2.0-beta-2b 2.0-beta-3 2.0-beta-3b 2.0-rc-2 2.0-rc-3 2.0-rc-4 2.0-rc-5 2.0.1 2.0.2 2.0.3 2.1 2.1-beta-1 2.1-rc1 2.1-rc2 2.1-rc3 2.1-rc4 2.1.1 2.1.2 2.1.3 2.2 2.2.1 All 72 releases
← All changes | includes/admin/topics.php +741 -509 2.2.12.6.6 View file →
@@ -7,17 +7,17 @@
7 7 * @subpackage Administration
8 8 */
9 9
10 10 // Exit if accessed directly
11 -if ( !defined( 'ABSPATH' ) ) exit;
11 +defined( 'ABSPATH' ) || exit;
12 12
13 -if ( !class_exists( 'BBP_Topics_Admin' ) ) :
13 +if ( ! class_exists( 'BBP_Topics_Admin' ) ) :
14 14 /**
15 15 * Loads bbPress topics admin area
16 16 *
17 17 * @package bbPress
18 18 * @subpackage Administration
19 - * @since bbPress (r2464)
19 + * @since 2.0.0 bbPress (r2464)
20 20 */
21 21 class BBP_Topics_Admin {
22 22
23 23 /** Variables *************************************************************/
@@ -31,13 +31,9 @@
31 31
32 32 /**
33 33 * The main bbPress topics admin loader
34 34 *
35 - * @since bbPress (r2515)
36 - *
37 - * @uses BBP_Topics_Admin::setup_globals() Setup the globals needed
38 - * @uses BBP_Topics_Admin::setup_actions() Setup the hooks and actions
39 - * @uses BBP_Topics_Admin::setup_help() Setup the help text
35 + * @since 2.0.0 bbPress (r2515)
40 36 */
41 37 public function __construct() {
42 38 $this->setup_globals();
43 39 $this->setup_actions();
@@ -45,70 +41,64 @@
45 41
46 42 /**
47 43 * Setup the admin hooks, actions and filters
48 44 *
49 - * @since bbPress (r2646)
45 + * @since 2.0.0 bbPress (r2646)
46 + * @since 2.6.0 bbPress (r6101) Added bulk actions
47 + *
50 48 * @access private
51 - *
52 - * @uses add_action() To add various actions
53 - * @uses add_filter() To add various filters
54 - * @uses bbp_get_forum_post_type() To get the forum post type
55 - * @uses bbp_get_topic_post_type() To get the topic post type
56 - * @uses bbp_get_reply_post_type() To get the reply post type
57 49 */
58 50 private function setup_actions() {
59 51
60 - // Add some general styling to the admin area
61 - add_action( 'bbp_admin_head', array( $this, 'admin_head' ) );
62 -
63 52 // Messages
64 53 add_filter( 'post_updated_messages', array( $this, 'updated_messages' ) );
65 54
55 + // Topic bulk actions, added in WordPress 4.7, see #WP16031.
56 + if ( bbp_get_major_wp_version() >= 4.7 ) {
57 + add_filter( 'bulk_actions-edit-topic', array( $this, 'bulk_actions' ) );
58 + add_filter( 'handle_bulk_actions-edit-topic', array( $this, 'handle_bulk_actions' ), 10, 3 );
59 + add_filter( 'bulk_post_updated_messages', array( $this, 'bulk_post_updated_messages' ), 10, 2 );
60 + }
61 +
66 62 // Topic column headers.
67 - add_filter( 'manage_' . $this->post_type . '_posts_columns', array( $this, 'topics_column_headers' ) );
63 + add_filter( 'manage_' . $this->post_type . '_posts_columns', array( $this, 'column_headers' ) );
68 64
69 65 // Topic columns (in post row)
70 - add_action( 'manage_' . $this->post_type . '_posts_custom_column', array( $this, 'topics_column_data' ), 10, 2 );
71 - add_filter( 'post_row_actions', array( $this, 'topics_row_actions' ), 10, 2 );
66 + add_action( 'manage_' . $this->post_type . '_posts_custom_column', array( $this, 'column_data' ), 10, 2 );
67 + add_filter( 'post_row_actions', array( $this, 'row_actions' ), 10, 2 );
72 68
73 - // Topic metabox actions
74 - add_action( 'add_meta_boxes', array( $this, 'attributes_metabox' ) );
75 - add_action( 'save_post', array( $this, 'attributes_metabox_save' ) );
69 + // Topic meta-box actions
70 + add_action( 'add_meta_boxes', array( $this, 'attributes_metabox' ) );
71 + add_action( 'add_meta_boxes', array( $this, 'author_metabox' ) );
72 + add_action( 'add_meta_boxes', array( $this, 'replies_metabox' ) );
73 + add_action( 'add_meta_boxes', array( $this, 'engagements_metabox' ) );
74 + add_action( 'add_meta_boxes', array( $this, 'favorites_metabox' ) );
75 + add_action( 'add_meta_boxes', array( $this, 'subscriptions_metabox' ) );
76 + add_action( 'add_meta_boxes', array( $this, 'comments_metabox' ) );
77 + add_action( 'save_post', array( $this, 'save_meta_boxes' ) );
76 78
77 79 // Check if there are any bbp_toggle_topic_* requests on admin_init, also have a message displayed
78 80 add_action( 'load-edit.php', array( $this, 'toggle_topic' ) );
79 - add_action( 'admin_notices', array( $this, 'toggle_topic_notice' ) );
81 + add_action( 'load-edit.php', array( $this, 'toggle_topic_notice' ) );
80 82
81 - // Anonymous metabox actions
82 - add_action( 'add_meta_boxes', array( $this, 'author_metabox' ) );
83 - add_action( 'save_post', array( $this, 'author_metabox_save' ) );
84 -
85 83 // Add ability to filter topics and replies per forum
86 84 add_filter( 'restrict_manage_posts', array( $this, 'filter_dropdown' ) );
87 85 add_filter( 'bbp_request', array( $this, 'filter_post_rows' ) );
88 86
87 + // Empty spam
88 + add_filter( 'manage_posts_extra_tablenav', array( $this, 'filter_empty_spam' ) );
89 +
89 90 // Contextual Help
90 91 add_action( 'load-edit.php', array( $this, 'edit_help' ) );
92 + add_action( 'load-post.php', array( $this, 'new_help' ) );
91 93 add_action( 'load-post-new.php', array( $this, 'new_help' ) );
92 94 }
93 95
94 96 /**
95 - * Should we bail out of this method?
97 + * Admin globals
96 98 *
97 - * @since bbPress (r4067)
98 - * @return boolean
99 - */
100 - private function bail() {
101 - if ( !isset( get_current_screen()->post_type ) || ( $this->post_type != get_current_screen()->post_type ) )
102 - return true;
103 -
104 - return false;
105 - }
106 -
107 - /**
108 - * Admin globals
99 + * @since 2.0.0 bbPress (r2646)
109 100 *
110 - * @since bbPress (r2646)
111 101 * @access private
112 102 */
113 103 private function setup_globals() {
114 104 $this->post_type = bbp_get_topic_post_type();
@@ -118,15 +108,12 @@
118 108
119 109 /**
120 110 * Contextual help for bbPress topic edit page
121 111 *
122 - * @since bbPress (r3119)
123 - * @uses get_current_screen()
112 + * @since 2.0.0 bbPress (r3119)
124 113 */
125 114 public function edit_help() {
126 115
127 - if ( $this->bail() ) return;
128 -
129 116 // Overview
130 117 get_current_screen()->add_help_tab( array(
131 118 'id' => 'overview',
132 119 'title' => __( 'Overview', 'bbpress' ),
@@ -140,11 +127,12 @@
140 127 'title' => __( 'Screen Content', 'bbpress' ),
141 128 'content' =>
142 129 '<p>' . __( 'You can customize the display of this screen&#8217;s contents in a number of ways:', 'bbpress' ) . '</p>' .
143 130 '<ul>' .
144 - '<li>' . __( 'You can hide/display columns based on your needs and decide how many topics to list per screen using the Screen Options tab.', 'bbpress' ) . '</li>' .
145 - '<li>' . __( 'You can filter the list of topics by topic status using the text links in the upper left to show All, Published, or Trashed topics. The default view is to show all topics.', 'bbpress' ) . '</li>' .
146 - '<li>' . __( 'You can refine the list to show only topics from a specific month by using the dropdown menus above the topics list. Click the Filter button after making your selection. You also can refine the list by clicking on the topic creator in the topics list.', 'bbpress' ) . '</li>' .
131 + '<li>' . __( 'You can hide/display columns based on your needs and decide how many topics to list per screen using the Screen Options tab.', 'bbpress' ) . '</li>' .
132 + '<li>' . __( 'You can filter the list of topics by topic status using the text links in the upper left to show All, Published, Draft, Pending, Trashed, Closed, or Spam topics. The default view is to show all topics.', 'bbpress' ) . '</li>' .
133 + '<li>' . __( 'You can view topics in a simple title list or with an excerpt. Choose the view you prefer by clicking on the icons at the top of the list on the right.', 'bbpress' ) . '</li>' .
134 + '<li>' . __( 'You can refine the list to show only topics in a specific forum or from a specific month by using the dropdown menus above the topics list. Click the Filter button after making your selection.', 'bbpress' ) . '</li>' .
147 135 '</ul>'
148 136 ) );
149 137
150 138 // Available Actions
@@ -153,15 +141,16 @@
153 141 'title' => __( 'Available Actions', 'bbpress' ),
154 142 'content' =>
155 143 '<p>' . __( 'Hovering over a row in the topics list will display action links that allow you to manage your topic. You can perform the following actions:', 'bbpress' ) . '</p>' .
156 144 '<ul>' .
157 - '<li>' . __( '<strong>Edit</strong> takes you to the editing screen for that topic. You can also reach that screen by clicking on the topic title.', 'bbpress' ) . '</li>' .
158 - '<li>' . __( '<strong>Trash</strong> removes your topic from this list and places it in the trash, from which you can permanently delete it.', 'bbpress' ) . '</li>' .
159 - '<li>' . __( '<strong>Spam</strong> removes your topic from this list and places it in the spam queue, from which you can permanently delete it.', 'bbpress' ) . '</li>' .
160 - '<li>' . __( '<strong>Preview</strong> will show you what your draft topic will look like if you publish it. View will take you to your live site to view the topic. Which link is available depends on your topic&#8217;s status.', 'bbpress' ) . '</li>' .
161 - '<li>' . __( '<strong>Close</strong> will mark the selected topic as &#8217;closed&#8217; and disable the option to post new replies to the topic.', 'bbpress' ) . '</li>' .
162 - '<li>' . __( '<strong>Stick</strong> will keep the selected topic &#8217;pinned&#8217; to the top the parent forum topic list.', 'bbpress' ) . '</li>' .
163 - '<li>' . __( '<strong>Stick <em>(to front)</em></strong> will keep the selected topic &#8217;pinned&#8217; to the top of ALL forums and be visable in any forums topics list.', 'bbpress' ) . '</li>' .
145 + '<li>' . __( '<strong>Edit</strong> takes you to the editing screen for that topic. You can also reach that screen by clicking on the topic title.', 'bbpress' ) . '</li>' .
146 + '<li>' . __( '<strong>Stick</strong> will keep the selected topic &#8217;pinned&#8217; to the top the parent forum topic list.', 'bbpress' ) . '</li>' .
147 + '<li>' . __( '<strong>Stick <em>(to front)</em></strong> will keep the selected topic &#8217;pinned&#8217; to the top of ALL forums and be visable in any forums topics list.', 'bbpress' ) . '</li>' .
148 + '<li>' . __( '<strong>Approve</strong> will change the status from pending to publish.', 'bbpress' ) . '</li>' .
149 + '<li>' . __( '<strong>Close</strong> will mark the selected topic as &#8217;closed&#8217; and disable the ability to post new replies to it.', 'bbpress' ) . '</li>' .
150 + '<li>' . __( '<strong>Spam</strong> removes your topic from this list and places it in the spam queue, from which you can permanently delete it.', 'bbpress' ) . '</li>' .
151 + '<li>' . __( '<strong>Trash</strong> removes your topic from this list and places it in the trash, from which you can permanently delete it.', 'bbpress' ) . '</li>' .
152 + '<li>' . __( '<strong>View</strong> will take you to your live site to view the topic.', 'bbpress' ) . '</li>' .
164 153 '</ul>'
165 154 ) );
166 155
167 156 // Bulk Actions
@@ -168,9 +157,9 @@
168 157 get_current_screen()->add_help_tab( array(
169 158 'id' => 'bulk-actions',
170 159 'title' => __( 'Bulk Actions', 'bbpress' ),
171 160 'content' =>
172 - '<p>' . __( 'You can also edit or move multiple topics to the trash at once. Select the topics you want to act on using the checkboxes, then select the action you want to take from the Bulk Actions menu and click Apply.', 'bbpress' ) . '</p>' .
161 + '<p>' . __( 'You can also edit, spam, or move multiple topics to the trash at once. Select the topics you want to act on using the checkboxes, then select the action you want to take from the Bulk Actions menu and click Apply.', 'bbpress' ) . '</p>' .
173 162 '<p>' . __( 'When using Bulk Edit, you can change the metadata (categories, author, etc.) for all selected topics at once. To remove a topic from the grouping, just click the x next to its name in the Bulk Edit area that appears.', 'bbpress' ) . '</p>'
174 163 ) );
175 164
176 165 // Help Sidebar
@@ -175,10 +164,10 @@
175 164
176 165 // Help Sidebar
177 166 get_current_screen()->set_help_sidebar(
178 167 '<p><strong>' . __( 'For more information:', 'bbpress' ) . '</strong></p>' .
179 - '<p>' . __( '<a href="http://codex.bbpress.org" target="_blank">bbPress Documentation</a>', 'bbpress' ) . '</p>' .
180 - '<p>' . __( '<a href="http://bbpress.org/forums/" target="_blank">bbPress Support Forums</a>', 'bbpress' ) . '</p>'
168 + '<p>' . __( '<a href="https://codex.bbpress.org" target="_blank">bbPress Documentation</a>', 'bbpress' ) . '</p>' .
169 + '<p>' . __( '<a href="https://bbpress.org/forums/" target="_blank">bbPress Support Forums</a>', 'bbpress' ) . '</p>'
181 170 );
182 171 }
183 172
184 173 /**
@@ -183,15 +172,12 @@
183 172
184 173 /**
185 174 * Contextual help for bbPress topic edit page
186 175 *
187 - * @since bbPress (r3119)
188 - * @uses get_current_screen()
176 + * @since 2.0.0 bbPress (r3119)
189 177 */
190 178 public function new_help() {
191 179
192 - if ( $this->bail() ) return;
193 -
194 180 $customize_display = '<p>' . __( 'The title field and the big topic 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.', 'bbpress' ) . '</p>';
195 181
196 182 get_current_screen()->add_help_tab( array(
197 183 'id' => 'customize-display',
@@ -208,13 +194,9 @@
208 194 ) );
209 195
210 196 $publish_box = '<p>' . __( '<strong>Publish</strong> - You can set the terms of publishing your topic 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 topic 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 topic to be published in the future or backdate a topic.', 'bbpress' ) . '</p>';
211 197
212 - if ( current_theme_supports( 'topic-formats' ) && topic_type_supports( 'topic', 'topic-formats' ) ) {
213 - $publish_box .= '<p>' . __( '<strong>topic Format</strong> - This designates how your theme will display a specific topic. For example, you could have a <em>standard</em> blog topic with a title and paragraphs, or a short <em>aside</em> that omits the title and contains a short text blurb. Please refer to the Codex for <a href="http://codex.wordpress.org/Post_Formats#Supported_Formats">descriptions of each topic format</a>. Your theme could enable all or some of 10 possible formats.', 'bbpress' ) . '</p>';
214 - }
215 -
216 - if ( current_theme_supports( 'topic-thumbnails' ) && topic_type_supports( 'topic', 'thumbnail' ) ) {
198 + if ( current_theme_supports( 'topic-thumbnails' ) && post_type_supports( bbp_get_topic_post_type(), 'thumbnail' ) ) {
217 199 $publish_box .= '<p>' . __( '<strong>Featured Image</strong> - This allows you to associate an image with your topic without inserting it. This is usually useful only if your theme makes use of the featured image as a topic thumbnail on the home page, a custom header, etc.', 'bbpress' ) . '</p>';
218 200 }
219 201
220 202 get_current_screen()->add_help_tab( array(
@@ -222,9 +204,9 @@
222 204 'title' => __( 'Topic Attributes', 'bbpress' ),
223 205 'content' =>
224 206 '<p>' . __( 'Select the attributes that your topic should have:', 'bbpress' ) . '</p>' .
225 207 '<ul>' .
226 - '<li>' . __( '<strong>Forum</strong> dropdown determines the parent forum that the topic belongs to. Select the forum or category from the dropdown, or leave the default (No Forum) to post the topic without an assigned forum.', 'bbpress' ) . '</li>' .
208 + '<li>' . __( '<strong>Forum</strong> dropdown determines the parent forum that the topic belongs to. Select the forum or category from the dropdown, or leave the default "No forum" to post the topic without an assigned forum.', 'bbpress' ) . '</li>' .
227 209 '<li>' . __( '<strong>Topic Type</strong> dropdown indicates the sticky status of the topic. Selecting the super sticky option would stick the topic to the front of your forums, i.e. the topic index, sticky option would stick the topic to its respective forum. Selecting normal would not stick the topic anywhere.', 'bbpress' ) . '</li>' .
228 210 '</ul>'
229 211 ) );
230 212
@@ -233,264 +215,340 @@
233 215 'title' => __( 'Publish Box', 'bbpress' ),
234 216 'content' => $publish_box,
235 217 ) );
236 218
237 - get_current_screen()->add_help_tab( array(
238 - 'id' => 'discussion-settings',
239 - 'title' => __( 'Discussion Settings', 'bbpress' ),
240 - 'content' =>
241 - '<p>' . __( '<strong>Send Trackbacks</strong> - Trackbacks are a way to notify legacy blog systems that you&#8217;ve linked to them. Enter the URL(s) you want to send trackbacks. If you link to other WordPress sites they&#8217;ll be notified automatically using pingbacks, and this field is unnecessary.', 'bbpress' ) . '</p>' .
242 - '<p>' . __( '<strong>Discussion</strong> - You can turn comments and pings on or off, and if there are comments on the topic, you can see them here and moderate them.', 'bbpress' ) . '</p>'
243 - ) );
244 -
245 219 get_current_screen()->set_help_sidebar(
246 220 '<p><strong>' . __( 'For more information:', 'bbpress' ) . '</strong></p>' .
247 - '<p>' . __( '<a href="http://codex.bbpress.org" target="_blank">bbPress Documentation</a>', 'bbpress' ) . '</p>' .
248 - '<p>' . __( '<a href="http://bbpress.org/forums/" target="_blank">bbPress Support Forums</a>', 'bbpress' ) . '</p>'
221 + '<p>' . __( '<a href="https://codex.bbpress.org" target="_blank">bbPress Documentation</a>', 'bbpress' ) . '</p>' .
222 + '<p>' . __( '<a href="https://bbpress.org/forums/" target="_blank">bbPress Support Forums</a>', 'bbpress' ) . '</p>'
249 223 );
250 224 }
251 225
252 226 /**
253 - * Add the topic attributes metabox
227 + * Add spam/unspam bulk actions to the bulk action dropdown.
254 228 *
255 - * @since bbPress (r2744)
229 + * @since 2.6.0 bbPress (r6101)
256 230 *
257 - * @uses bbp_get_topic_post_type() To get the topic post type
258 - * @uses add_meta_box() To add the metabox
259 - * @uses do_action() Calls 'bbp_topic_attributes_metabox'
231 + * @param array $actions The list of bulk actions.
232 + * @return array The filtered list of bulk actions.
260 233 */
261 - public function attributes_metabox() {
234 + public function bulk_actions( $actions ) {
262 235
263 - if ( $this->bail() ) return;
236 + if ( current_user_can( 'moderate' ) ) {
237 + if ( bbp_get_spam_status_id() === get_query_var( 'post_status' ) ) {
238 + $actions['unspam'] = esc_html__( 'Unspam', 'bbpress' );
239 + } else {
240 + $actions['spam'] = esc_html__( 'Spam', 'bbpress' );
241 + }
242 + }
264 243
265 - add_meta_box (
266 - 'bbp_topic_attributes',
267 - __( 'Topic Attributes', 'bbpress' ),
268 - 'bbp_topic_metabox',
269 - $this->post_type,
270 - 'side',
271 - 'high'
272 - );
244 + return $actions;
245 + }
273 246
274 - do_action( 'bbp_topic_attributes_metabox' );
247 + /**
248 + * Add custom bulk action updated messages for topics.
249 + *
250 + * @since 2.6.0 bbPress (r6101)
251 + *
252 + * @param array $bulk_messages Arrays of messages, each keyed by the corresponding post type.
253 + * @param array $bulk_counts Array of item counts for each message, used to build internationalized strings.
254 + */
255 + public function bulk_post_updated_messages( $bulk_messages, $bulk_counts ) {
256 + $bulk_messages['topic']['updated'] = _n( '%s topic updated.', '%s topics updated.', $bulk_counts['updated'], 'bbpress' );
257 + $bulk_messages['topic']['locked'] = ( 1 === $bulk_counts['locked'] )
258 + ? __( '1 topic not updated, somebody is editing it.', 'bbpress' )
259 + : _n( '%s topic not updated, somebody is editing it.', '%s topics not updated, somebody is editing them.', $bulk_counts['locked'], 'bbpress' );
260 +
261 + return $bulk_messages;
275 262 }
276 263
277 264 /**
278 - * Pass the topic attributes for processing
265 + * Handle spam/unspam bulk actions.
279 266 *
280 - * @since bbPress (r2746)
267 + * @since 2.6.0 bbPress (r6101)
281 268 *
282 - * @param int $topic_id Topic id
283 - * @uses current_user_can() To check if the current user is capable of
284 - * editing the topic
285 - * @uses do_action() Calls 'bbp_topic_attributes_metabox_save' with the
286 - * topic id and parent id
287 - * @return int Parent id
269 + * @param string $sendback The sendback URL.
270 + * @param string $doaction The action to be taken.
271 + * @param array $post_ids The post IDS to take the action on.
272 + * @return string The sendback URL.
288 273 */
289 - public function attributes_metabox_save( $topic_id ) {
274 + public function handle_bulk_actions( $sendback, $doaction, $post_ids ) {
290 275
291 - if ( $this->bail() ) return $topic_id;
276 + $sendback = remove_query_arg( array( 'spam', 'unspam' ), $sendback );
277 + $updated = $locked = 0;
292 278
293 - // Bail if doing an autosave
294 - if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
295 - return $topic_id;
279 + if ( 'spam' === $doaction ) {
296 280
297 - // Bail if not a post request
298 - if ( 'POST' != strtoupper( $_SERVER['REQUEST_METHOD'] ) )
299 - return $topic_id;
281 + foreach ( (array) $post_ids as $post_id ) {
282 + if ( ! current_user_can( 'moderate', $post_id ) ) {
283 + wp_die( esc_html__( 'Sorry, you are not allowed to spam this item.', 'bbpress' ) );
284 + }
300 285
301 - // Nonce check
302 - if ( empty( $_POST['bbp_topic_metabox'] ) || !wp_verify_nonce( $_POST['bbp_topic_metabox'], 'bbp_topic_metabox_save' ) )
303 - return $topic_id;
286 + if ( wp_check_post_lock( $post_id ) ) {
287 + $locked++;
288 + continue;
289 + }
304 290
305 - // Bail if current user cannot edit this topic
306 - if ( !current_user_can( 'edit_topic', $topic_id ) )
307 - return $topic_id;
291 + if ( ! bbp_spam_topic( $post_id ) ) {
292 + wp_die( esc_html__( 'Error in spamming topic.', 'bbpress' ) );
293 + }
308 294
309 - // Get the forum ID
310 - $forum_id = !empty( $_POST['parent_id'] ) ? (int) $_POST['parent_id'] : 0;
295 + $updated++;
296 + }
311 297
312 - // Formally update the topic
313 - bbp_update_topic( $topic_id, $forum_id );
298 + $sendback = add_query_arg( array(
299 + 'updated' => $updated,
300 + 'ids' => implode( ',', $post_ids ),
301 + 'locked' => $locked
302 + ), $sendback );
314 303
315 - // Stickies
316 - if ( !empty( $_POST['bbp_stick_topic'] ) && in_array( $_POST['bbp_stick_topic'], array( 'stick', 'super', 'unstick' ) ) ) {
304 + } elseif ( 'unspam' === $doaction ) {
317 305
318 - // What's the haps?
319 - switch ( $_POST['bbp_stick_topic'] ) {
306 + foreach ( (array) $post_ids as $post_id ) {
307 + if ( ! current_user_can( 'moderate', $post_id ) ) {
308 + wp_die( esc_html__( 'Sorry, you are not allowed to unspam this topic.', 'bbpress' ) );
309 + }
320 310
321 - // Sticky in this forum
322 - case 'stick' :
323 - bbp_stick_topic( $topic_id );
324 - break;
311 + if ( wp_check_post_lock( $post_id ) ) {
312 + $locked++;
313 + continue;
314 + }
325 315
326 - // Super sticky in all forums
327 - case 'super' :
328 - bbp_stick_topic( $topic_id, true );
329 - break;
316 + if ( ! bbp_unspam_topic( $post_id ) ) {
317 + wp_die( esc_html__( 'Error in unspamming topic.', 'bbpress' ) );
318 + }
330 319
331 - // Normal
332 - case 'unstick' :
333 - default :
334 - bbp_unstick_topic( $topic_id );
335 - break;
320 + $updated++;
336 321 }
322 +
323 + $sendback = add_query_arg( array(
324 + 'updated' => $updated,
325 + 'ids' => implode( ',', $post_ids ),
326 + 'locked' => $locked
327 + ), $sendback );
337 328 }
338 329
339 - // Allow other fun things to happen
340 - do_action( 'bbp_topic_attributes_metabox_save', $topic_id, $forum_id );
330 + return $sendback;
331 + }
341 332
342 - return $topic_id;
333 + /**
334 + * Add the topic attributes meta-box
335 + *
336 + * @since 2.0.0 bbPress (r2744)
337 + */
338 + public function attributes_metabox() {
339 + add_meta_box(
340 + 'bbp_topic_attributes',
341 + esc_html__( 'Topic Attributes', 'bbpress' ),
342 + 'bbp_topic_metabox',
343 + $this->post_type,
344 + 'side',
345 + 'high'
346 + );
343 347 }
344 348
345 349 /**
346 - * Add the author info metabox
350 + * Add the author info meta-box
347 351 *
348 - * @since bbPress (r2828)
349 - *
350 - * @uses bbp_get_topic() To get the topic
351 - * @uses bbp_get_reply() To get the reply
352 - * @uses bbp_get_topic_post_type() To get the topic post type
353 - * @uses bbp_get_reply_post_type() To get the reply post type
354 - * @uses add_meta_box() To add the metabox
355 - * @uses do_action() Calls 'bbp_author_metabox' with the topic/reply
356 - * id
352 + * @since 2.0.0 bbPress (r2828)
357 353 */
358 354 public function author_metabox() {
359 355
360 - if ( $this->bail() ) return;
361 -
362 356 // Bail if post_type is not a topic
363 - if ( empty( $_GET['action'] ) || ( 'edit' != $_GET['action'] ) )
357 + if ( empty( $_GET['action'] ) || ( 'edit' !== $_GET['action'] ) ) {
364 358 return;
359 + }
365 360
366 - // Add the metabox
361 + // Add the meta-box
367 362 add_meta_box(
368 363 'bbp_author_metabox',
369 - __( 'Author Information', 'bbpress' ),
364 + esc_html__( 'Author Information', 'bbpress' ),
370 365 'bbp_author_metabox',
371 366 $this->post_type,
372 367 'side',
373 368 'high'
374 369 );
375 -
376 - do_action( 'bbp_author_metabox', get_the_ID() );
377 370 }
378 371
379 372 /**
380 - * Save the author information for the topic
373 + * Add the replies meta-box
381 374 *
382 - * @since bbPress (r2828)
375 + * Allows viewing & moderating of replies to a topic, based on the way
376 + * comments are visible on a blog post.
383 377 *
384 - * @param int $post_id Topic or reply id
385 - * @uses bbp_get_topic() To get the topic
386 - * @uses bbp_get_reply() To get the reply
387 - * @uses current_user_can() To check if the current user can edit the
388 - * topic or reply
389 - * @uses bbp_filter_author_post_data() To filter the author data
390 - * @uses update_post_meta() To update the anonymous user data
391 - * @uses do_action() Calls 'bbp_author_metabox_save' with the topic id and
392 - * anonymous data
393 - * @return int Topic or reply id
378 + * @since 2.6.0 bbPress (r5886)
394 379 */
395 - public function author_metabox_save( $post_id ) {
380 + public function replies_metabox() {
396 381
397 - if ( $this->bail() ) return $post_id;
382 + // Bail if post_type is not a reply
383 + if ( empty( $_GET['action'] ) || ( 'edit' !== $_GET['action'] ) ) {
384 + return;
385 + }
398 386
399 - // Bail if no post_id
400 - if ( empty( $post_id ) )
401 - return $post_id;
387 + // Add the meta-box
388 + add_meta_box(
389 + 'bbp_topic_replies_metabox',
390 + esc_html__( 'Replies', 'bbpress' ),
391 + 'bbp_topic_replies_metabox',
392 + $this->post_type,
393 + 'normal',
394 + 'high'
395 + );
396 + }
402 397
403 - // Bail if doing an autosave
404 - if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
405 - return $post_id;
398 + /**
399 + * Add the engagements meta-box
400 + *
401 + * Allows viewing of users who have engaged in a topic.
402 + *
403 + * @since 2.6.0 bbPress (r6333)
404 + */
405 + public function engagements_metabox() {
406 406
407 - // Bail if not a post request
408 - if ( 'POST' != strtoupper( $_SERVER['REQUEST_METHOD'] ) )
409 - return $post_id;
407 + // Bail when creating a new topic
408 + if ( empty( $_GET['action'] ) || ( 'edit' !== $_GET['action'] ) ) {
409 + return;
410 + }
410 411
411 - // Bail if user cannot edit topics
412 - if ( !current_user_can( 'edit_topic', $post_id ) )
413 - return $post_id;
412 + // Bail if no engagements
413 + if ( ! bbp_is_engagements_active() ) {
414 + return;
415 + }
414 416
415 - $anonymous_data = bbp_filter_anonymous_post_data();
417 + // Add the meta-box
418 + add_meta_box(
419 + 'bbp_topic_engagements_metabox',
420 + esc_html__( 'Engagements', 'bbpress' ),
421 + 'bbp_topic_engagements_metabox',
422 + $this->post_type,
423 + 'side',
424 + 'low'
425 + );
426 + }
416 427
417 - update_post_meta( $post_id, '_bbp_anonymous_name', $anonymous_data['bbp_anonymous_name'] );
418 - update_post_meta( $post_id, '_bbp_anonymous_email', $anonymous_data['bbp_anonymous_email'] );
419 - update_post_meta( $post_id, '_bbp_anonymous_website', $anonymous_data['bbp_anonymous_website'] );
428 + /**
429 + * Add the favorites meta-box
430 + *
431 + * Allows viewing of users who have favorited a topic.
432 + *
433 + * @since 2.6.0 bbPress (r6197)
434 + */
435 + public function favorites_metabox() {
420 436
421 - do_action( 'bbp_author_metabox_save', $post_id, $anonymous_data );
437 + // Bail if post_type is not a reply
438 + if ( empty( $_GET['action'] ) || ( 'edit' !== $_GET['action'] ) ) {
439 + return;
440 + }
422 441
423 - return $post_id;
442 + // Bail if no favorites
443 + if ( ! bbp_is_favorites_active() ) {
444 + return;
445 + }
446 +
447 + // Add the meta-box
448 + add_meta_box(
449 + 'bbp_topic_favorites_metabox',
450 + esc_html__( 'Favorites', 'bbpress' ),
451 + 'bbp_topic_favorites_metabox',
452 + $this->post_type,
453 + 'normal',
454 + 'high'
455 + );
424 456 }
425 457
426 458 /**
427 - * Add some general styling to the admin area
459 + * Add the subscriptions meta-box
428 460 *
429 - * @since bbPress (r2464)
461 + * Allows viewing of users who have subscribed to a topic.
430 462 *
431 - * @uses bbp_get_forum_post_type() To get the forum post type
432 - * @uses bbp_get_topic_post_type() To get the topic post type
433 - * @uses bbp_get_reply_post_type() To get the reply post type
434 - * @uses sanitize_html_class() To sanitize the classes
435 - * @uses do_action() Calls 'bbp_admin_head'
463 + * @since 2.6.0 bbPress (r6197)
436 464 */
437 - public function admin_head() {
465 + public function subscriptions_metabox() {
438 466
439 - if ( $this->bail() ) return;
467 + // Bail if post_type is not a reply
468 + if ( empty( $_GET['action'] ) || ( 'edit' !== $_GET['action'] ) ) {
469 + return;
470 + }
440 471
441 - ?>
472 + // Bail if no subscriptions
473 + if ( ! bbp_is_subscriptions_active() ) {
474 + return;
475 + }
442 476
443 - <style type="text/css" media="screen">
444 - /*<![CDATA[*/
477 + // Add the meta-box
478 + add_meta_box(
479 + 'bbp_topic_subscriptions_metabox',
480 + esc_html__( 'Subscriptions', 'bbpress' ),
481 + 'bbp_topic_subscriptions_metabox',
482 + $this->post_type,
483 + 'normal',
484 + 'high'
485 + );
486 + }
445 487
446 - strong.label {
447 - display: inline-block;
448 - width: 60px;
449 - }
488 + /**
489 + * Remove comments & discussion meta-boxes if comments are not supported
490 + *
491 + * @since 2.6.0 bbPress (r6186)
492 + */
493 + public function comments_metabox() {
494 + if ( ! post_type_supports( $this->post_type, 'comments' ) ) {
495 + remove_meta_box( 'commentstatusdiv', $this->post_type, 'normal' );
496 + remove_meta_box( 'commentsdiv', $this->post_type, 'normal' );
497 + }
498 + }
450 499
451 - .column-bbp_forum_topic_count,
452 - .column-bbp_forum_reply_count,
453 - .column-bbp_topic_reply_count,
454 - .column-bbp_topic_voice_count {
455 - width: 8% !important;
456 - }
500 + /**
501 + * Pass the topic attributes for processing
502 + *
503 + * @since 2.0.0 bbPress (r2746)
504 + *
505 + * @param int $topic_id Topic id
506 + * @return int Parent id
507 + */
508 + public function save_meta_boxes( $topic_id ) {
457 509
458 - .column-author,
459 - .column-bbp_reply_author,
460 - .column-bbp_topic_author {
461 - width: 10% !important;
462 - }
510 + // Bail if doing an autosave
511 + if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
512 + return $topic_id;
513 + }
463 514
464 - .column-bbp_topic_forum,
465 - .column-bbp_reply_forum,
466 - .column-bbp_reply_topic {
467 - width: 10% !important;
468 - }
515 + // Bail if not a post request
516 + if ( ! bbp_is_post_request() ) {
517 + return $topic_id;
518 + }
469 519
470 - .column-bbp_forum_freshness,
471 - .column-bbp_topic_freshness {
472 - width: 10% !important;
473 - }
520 + // Check action exists
521 + if ( empty( $_POST['action'] ) ) {
522 + return $topic_id;
523 + }
474 524
475 - .column-bbp_forum_created,
476 - .column-bbp_topic_created,
477 - .column-bbp_reply_created {
478 - width: 15% !important;
479 - }
525 + // Nonce check
526 + if ( empty( $_POST['bbp_topic_metabox'] ) || ! wp_verify_nonce( $_POST['bbp_topic_metabox'], 'bbp_topic_metabox_save' ) ) {
527 + return $topic_id;
528 + }
480 529
481 - .status-closed {
482 - background-color: #eaeaea;
483 - }
530 + // Bail if current user cannot edit this topic
531 + if ( ! current_user_can( 'edit_topic', $topic_id ) ) {
532 + return $topic_id;
533 + }
484 534
485 - .status-spam {
486 - background-color: #faeaea;
487 - }
535 + // Get the forum ID
536 + $forum_id = ! empty( $_POST['parent_id'] ) ? (int) $_POST['parent_id'] : 0;
488 537
489 - /*]]>*/
490 - </style>
538 + // Get topic author data
539 + $anonymous_data = bbp_filter_anonymous_post_data();
540 + $author_id = bbp_get_topic_author_id( $topic_id );
541 + $is_edit = ( isset( $_POST['hidden_post_status'] ) && ( $_POST['hidden_post_status'] !== 'draft' ) );
491 542
492 - <?php
543 + // Formally update the topic
544 + bbp_update_topic( $topic_id, $forum_id, $anonymous_data, $author_id, $is_edit );
545 +
546 + // Allow other fun things to happen
547 + do_action( 'bbp_topic_attributes_metabox_save', $topic_id, $forum_id );
548 + do_action( 'bbp_author_metabox_save', $topic_id, $anonymous_data );
549 +
550 + return $topic_id;
493 551 }
494 552
495 553 /**
496 554 * Toggle topic
@@ -497,96 +555,119 @@
497 555 *
498 556 * Handles the admin-side opening/closing, sticking/unsticking and
499 557 * spamming/unspamming of topics
500 558 *
501 - * @since bbPress (r2727)
502 - *
503 - * @uses bbp_get_topic() To get the topic
504 - * @uses current_user_can() To check if the user is capable of editing
505 - * the topic
506 - * @uses wp_die() To die if the user isn't capable or the post wasn't
507 - * found
508 - * @uses check_admin_referer() To verify the nonce and check referer
509 - * @uses bbp_is_topic_open() To check if the topic is open
510 - * @uses bbp_close_topic() To close the topic
511 - * @uses bbp_open_topic() To open the topic
512 - * @uses bbp_is_topic_sticky() To check if the topic is a sticky or
513 - * super sticky
514 - * @uses bbp_unstick_topic() To unstick the topic
515 - * @uses bbp_stick_topic() To stick the topic
516 - * @uses bbp_is_topic_spam() To check if the topic is marked as spam
517 - * @uses bbp_unspam_topic() To unmark the topic as spam
518 - * @uses bbp_spam_topic() To mark the topic as spam
519 - * @uses do_action() Calls 'bbp_toggle_topic_admin' with success, post
520 - * data, action and message
521 - * @uses add_query_arg() To add custom args to the url
522 - * @uses wp_safe_redirect() Redirect the page to custom url
559 + * @since 2.0.0 bbPress (r2727)
523 560 */
524 561 public function toggle_topic() {
525 562
526 - if ( $this->bail() ) return;
563 + // Bail if not a topic toggle action
564 + if ( ! bbp_is_get_request() || empty( $_GET['action'] ) || empty( $_GET['topic_id'] ) ) {
565 + return;
566 + }
527 567
528 - // Only proceed if GET is a topic toggle action
529 - if ( 'GET' == $_SERVER['REQUEST_METHOD'] && !empty( $_GET['action'] ) && in_array( $_GET['action'], array( 'bbp_toggle_topic_close', 'bbp_toggle_topic_stick', 'bbp_toggle_topic_spam' ) ) && !empty( $_GET['topic_id'] ) ) {
530 - $action = $_GET['action']; // What action is taking place?
531 - $topic_id = (int) $_GET['topic_id']; // What's the topic id?
532 - $success = false; // Flag
533 - $post_data = array( 'ID' => $topic_id ); // Prelim array
534 - $topic = bbp_get_topic( $topic_id );
568 + // Bail if not an allowed action
569 + $action = sanitize_key( $_GET['action'] );
570 + if ( empty( $action ) || ! in_array( $action, $this->get_allowed_action_toggles(), true ) ) {
571 + return;
572 + }
535 573
536 - // Bail if topic is missing
537 - if ( empty( $topic ) )
538 - wp_die( __( 'The topic was not found!', 'bbpress' ) );
574 + // Bail if topic is missing
575 + $topic_id = bbp_get_topic_id( $_GET['topic_id'] );
576 + if ( ! bbp_get_topic( $topic_id ) ) {
577 + wp_die( esc_html__( 'The topic was not found.', 'bbpress' ) );
578 + }
539 579
540 - if ( !current_user_can( 'moderate', $topic->ID ) ) // What is the user doing here?
541 - wp_die( __( 'You do not have the permission to do that!', 'bbpress' ) );
580 + // What is the user doing here?
581 + if ( ! current_user_can( 'moderate', $topic_id ) ) {
582 + wp_die( esc_html__( 'You do not have permission to do that.', 'bbpress' ) );
583 + }
542 584
543 - switch ( $action ) {
544 - case 'bbp_toggle_topic_close' :
545 - check_admin_referer( 'close-topic_' . $topic_id );
585 + // Defaults
586 + $post_data = array( 'ID' => $topic_id );
587 + $message = '';
588 + $success = false;
546 589
547 - $is_open = bbp_is_topic_open( $topic_id );
548 - $message = true == $is_open ? 'closed' : 'opened';
549 - $success = true == $is_open ? bbp_close_topic( $topic_id ) : bbp_open_topic( $topic_id );
590 + switch ( $action ) {
591 + case 'bbp_toggle_topic_approve' :
592 + check_admin_referer( 'approve-topic_' . $topic_id );
550 593
551 - break;
594 + $is_approve = bbp_is_topic_public( $topic_id );
595 + $message = ( true === $is_approve )
596 + ? 'unapproved'
597 + : 'approved';
598 + $success = ( true === $is_approve )
599 + ? bbp_unapprove_topic( $topic_id )
600 + : bbp_approve_topic( $topic_id );
552 601
553 - case 'bbp_toggle_topic_stick' :
554 - check_admin_referer( 'stick-topic_' . $topic_id );
602 + break;
555 603
556 - $is_sticky = bbp_is_topic_sticky( $topic_id );
557 - $is_super = ( empty( $is_sticky ) && !empty( $_GET['super'] ) && 1 == (int) $_GET['super'] ) ? true : false;
558 - $message = true == $is_sticky ? 'unsticked' : 'sticked';
559 - $message = true == $is_super ? 'super_sticked' : $message;
560 - $success = true == $is_sticky ? bbp_unstick_topic( $topic_id ) : bbp_stick_topic( $topic_id, $is_super );
604 + case 'bbp_toggle_topic_close' :
605 + check_admin_referer( 'close-topic_' . $topic_id );
561 606
562 - break;
607 + $is_open = bbp_is_topic_open( $topic_id );
608 + $message = ( true === $is_open )
609 + ? 'closed'
610 + : 'opened';
611 + $success = ( true === $is_open )
612 + ? bbp_close_topic( $topic_id )
613 + : bbp_open_topic( $topic_id );
563 614
564 - case 'bbp_toggle_topic_spam' :
565 - check_admin_referer( 'spam-topic_' . $topic_id );
615 + break;
566 616
567 - $is_spam = bbp_is_topic_spam( $topic_id );
568 - $message = true == $is_spam ? 'unspammed' : 'spammed';
569 - $success = true == $is_spam ? bbp_unspam_topic( $topic_id ) : bbp_spam_topic( $topic_id );
617 + case 'bbp_toggle_topic_stick' :
618 + check_admin_referer( 'stick-topic_' . $topic_id );
570 619
571 - break;
572 - }
620 + $is_sticky = bbp_is_topic_sticky( $topic_id );
621 + $is_super = ( false === $is_sticky ) && ! empty( $_GET['super'] ) && ( "1" === $_GET['super'] )
622 + ? true
623 + : false;
624 + $message = ( true === $is_sticky )
625 + ? 'unstuck'
626 + : 'stuck';
627 + $message = ( true === $is_super )
628 + ? 'super_sticky'
629 + : $message;
630 + $success = ( true === $is_sticky )
631 + ? bbp_unstick_topic( $topic_id )
632 + : bbp_stick_topic( $topic_id, $is_super );
573 633
574 - $message = array( 'bbp_topic_toggle_notice' => $message, 'topic_id' => $topic->ID );
634 + break;
575 635
576 - if ( false == $success || is_wp_error( $success ) )
577 - $message['failed'] = '1';
636 + case 'bbp_toggle_topic_spam' :
637 + check_admin_referer( 'spam-topic_' . $topic_id );
578 638
579 - // Do additional topic toggle actions (admin side)
580 - do_action( 'bbp_toggle_topic_admin', $success, $post_data, $action, $message );
639 + $is_spam = bbp_is_topic_spam( $topic_id );
640 + $message = ( true === $is_spam )
641 + ? 'unspammed'
642 + : 'spammed';
643 + $success = ( true === $is_spam )
644 + ? bbp_unspam_topic( $topic_id )
645 + : bbp_spam_topic( $topic_id );
581 646
582 - // Redirect back to the topic
583 - $redirect = add_query_arg( $message, remove_query_arg( array( 'action', 'topic_id' ) ) );
584 - wp_safe_redirect( $redirect );
647 + break;
648 + }
585 649
586 - // For good measure
587 - exit();
650 + // Setup the message
651 + $retval = array(
652 + 'bbp_topic_toggle_notice' => $message,
653 + 'topic_id' => $topic_id
654 + );
655 +
656 + // Prepare for failure
657 + if ( ( false === $success ) || is_wp_error( $success ) ) {
658 + $retval['failed'] = '1';
588 659 }
660 +
661 + // Filter all message args
662 + $retval = apply_filters( 'bbp_toggle_topic_action_admin', $retval, $topic_id, $action );
663 +
664 + // Do additional topic toggle actions (admin side)
665 + do_action( 'bbp_toggle_topic_admin', $success, $post_data, $action, $retval );
666 +
667 + // Redirect back to the topic
668 + $redirect = add_query_arg( $retval, remove_query_arg( array( 'action', 'topic_id' ) ) );
669 + bbp_redirect( $redirect );
589 670 }
590 671
591 672 /**
592 673 * Toggle topic notices
@@ -593,137 +674,207 @@
593 674 *
594 675 * Display the success/error notices from
595 676 * {@link BBP_Admin::toggle_topic()}
596 677 *
597 - * @since bbPress (r2727)
598 - *
599 - * @uses bbp_get_topic() To get the topic
600 - * @uses bbp_get_topic_title() To get the topic title of the topic
601 - * @uses esc_html() To sanitize the topic title
602 - * @uses apply_filters() Calls 'bbp_toggle_topic_notice_admin' with
603 - * message, topic id, notice and is it a failure
678 + * @since 2.0.0 bbPress (r2727)
604 679 */
605 680 public function toggle_topic_notice() {
606 681
607 - if ( $this->bail() ) return;
682 + // Bail if missing topic toggle action
683 + if ( ! bbp_is_get_request() || empty( $_GET['topic_id'] ) || empty( $_GET['bbp_topic_toggle_notice'] ) ) {
684 + return;
685 + }
608 686
609 - // Only proceed if GET is a topic toggle action
610 - if ( 'GET' == $_SERVER['REQUEST_METHOD'] && !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'] ) ) {
611 - $notice = $_GET['bbp_topic_toggle_notice']; // Which notice?
612 - $topic_id = (int) $_GET['topic_id']; // What's the topic id?
613 - $is_failure = !empty( $_GET['failed'] ) ? true : false; // Was that a failure?
687 + // Bail if not an allowed notice
688 + $notice = sanitize_key( $_GET['bbp_topic_toggle_notice'] );
689 + if ( empty( $notice ) || ! in_array( $notice, $this->get_allowed_notice_toggles(), true ) ) {
690 + return;
691 + }
614 692
615 - // Bais if no topic_id or notice
616 - if ( empty( $notice ) || empty( $topic_id ) )
617 - return;
693 + // Bail if no topic_id or notice
694 + $topic_id = bbp_get_topic_id( $_GET['topic_id'] );
695 + if ( empty( $topic_id ) ) {
696 + return;
697 + }
618 698
619 - // Bail if topic is missing
620 - $topic = bbp_get_topic( $topic_id );
621 - if ( empty( $topic ) )
622 - return;
699 + // Bail if topic is missing
700 + if ( ! bbp_get_topic( $topic_id ) ) {
701 + return;
702 + }
623 703
624 - $topic_title = esc_html( bbp_get_topic_title( $topic->ID ) );
704 + // Use the title in the responses
705 + $topic_title = bbp_get_topic_title( $topic_id );
706 + $is_failure = ! empty( $_GET['failed'] );
707 + $message = '';
625 708
626 - switch ( $notice ) {
627 - case 'opened' :
628 - $message = $is_failure == true ? sprintf( __( 'There was a problem opening the topic "%1$s".', 'bbpress' ), $topic_title ) : sprintf( __( 'Topic "%1$s" successfully opened.', 'bbpress' ), $topic_title );
629 - break;
709 + // Which notice?
710 + switch ( $notice ) {
711 + case 'opened' :
712 + $message = ( $is_failure === true )
713 + ? sprintf( esc_html__( 'There was a problem opening the topic "%1$s".', 'bbpress' ), $topic_title )
714 + : sprintf( esc_html__( 'Topic "%1$s" successfully opened.', 'bbpress' ), $topic_title );
715 + break;
630 716
631 - case 'closed' :
632 - $message = $is_failure == true ? sprintf( __( 'There was a problem closing the topic "%1$s".', 'bbpress' ), $topic_title ) : sprintf( __( 'Topic "%1$s" successfully closed.', 'bbpress' ), $topic_title );
633 - break;
717 + case 'closed' :
718 + $message = ( $is_failure === true )
719 + ? sprintf( esc_html__( 'There was a problem closing the topic "%1$s".', 'bbpress' ), $topic_title )
720 + : sprintf( esc_html__( 'Topic "%1$s" successfully closed.', 'bbpress' ), $topic_title );
721 + break;
634 722
635 - case 'super_sticked' :
636 - $message = $is_failure == true ? sprintf( __( 'There was a problem sticking the topic "%1$s" to front.', 'bbpress' ), $topic_title ) : sprintf( __( 'Topic "%1$s" successfully sticked to front.', 'bbpress' ), $topic_title );
637 - break;
723 + case 'super_sticky' :
724 + $message = ( $is_failure === true )
725 + ? sprintf( esc_html__( 'There was a problem sticking the topic "%1$s" to front.', 'bbpress' ), $topic_title )
726 + : sprintf( esc_html__( 'Topic "%1$s" successfully stuck to front.', 'bbpress' ), $topic_title );
727 + break;
638 728
639 - case 'sticked' :
640 - $message = $is_failure == true ? sprintf( __( 'There was a problem sticking the topic "%1$s".', 'bbpress' ), $topic_title ) : sprintf( __( 'Topic "%1$s" successfully sticked.', 'bbpress' ), $topic_title );
641 - break;
729 + case 'stuck' :
730 + $message = ( $is_failure === true )
731 + ? sprintf( esc_html__( 'There was a problem sticking the topic "%1$s".', 'bbpress' ), $topic_title )
732 + : sprintf( esc_html__( 'Topic "%1$s" successfully stuck.', 'bbpress' ), $topic_title );
733 + break;
642 734
643 - case 'unsticked' :
644 - $message = $is_failure == true ? sprintf( __( 'There was a problem unsticking the topic "%1$s".', 'bbpress' ), $topic_title ) : sprintf( __( 'Topic "%1$s" successfully unsticked.', 'bbpress' ), $topic_title );
645 - break;
735 + case 'unstuck' :
736 + $message = ( $is_failure === true )
737 + ? sprintf( esc_html__( 'There was a problem unsticking the topic "%1$s".', 'bbpress' ), $topic_title )
738 + : sprintf( esc_html__( 'Topic "%1$s" successfully unstuck.', 'bbpress' ), $topic_title );
739 + break;
646 740
647 - case 'spammed' :
648 - $message = $is_failure == true ? sprintf( __( 'There was a problem marking the topic "%1$s" as spam.', 'bbpress' ), $topic_title ) : sprintf( __( 'Topic "%1$s" successfully marked as spam.', 'bbpress' ), $topic_title );
649 - break;
741 + case 'spammed' :
742 + $message = ( $is_failure === true )
743 + ? sprintf( esc_html__( 'There was a problem marking the topic "%1$s" as spam.', 'bbpress' ), $topic_title )
744 + : sprintf( esc_html__( 'Topic "%1$s" successfully marked as spam.', 'bbpress' ), $topic_title );
745 + break;
650 746
651 - case 'unspammed' :
652 - $message = $is_failure == true ? sprintf( __( 'There was a problem unmarking the topic "%1$s" as spam.', 'bbpress' ), $topic_title ) : sprintf( __( 'Topic "%1$s" successfully unmarked as spam.', 'bbpress' ), $topic_title );
653 - break;
654 - }
747 + case 'unspammed' :
748 + $message = ( $is_failure === true )
749 + ? sprintf( esc_html__( 'There was a problem unmarking the topic "%1$s" as spam.', 'bbpress' ), $topic_title )
750 + : sprintf( esc_html__( 'Topic "%1$s" successfully unmarked as spam.', 'bbpress' ), $topic_title );
751 + break;
655 752
656 - // Do additional topic toggle notice filters (admin side)
657 - $message = apply_filters( 'bbp_toggle_topic_notice_admin', $message, $topic->ID, $notice, $is_failure );
753 + case 'approved' :
754 + $message = ( $is_failure === true )
755 + ? sprintf( esc_html__( 'There was a problem approving the topic "%1$s".', 'bbpress' ), $topic_title )
756 + : sprintf( esc_html__( 'Topic "%1$s" successfully approved.', 'bbpress' ), $topic_title );
757 + break;
658 758
659 - ?>
759 + case 'unapproved' :
760 + $message = ( $is_failure === true )
761 + ? sprintf( esc_html__( 'There was a problem unapproving the topic "%1$s".', 'bbpress' ), $topic_title )
762 + : sprintf( esc_html__( 'Topic "%1$s" successfully unapproved.', 'bbpress' ), $topic_title );
763 + break;
764 + }
660 765
661 - <div id="message" class="<?php echo $is_failure == true ? 'error' : 'updated'; ?> fade">
662 - <p style="line-height: 150%"><?php echo $message; ?></p>
663 - </div>
766 + // Do additional topic toggle notice filters (admin side)
767 + $message = apply_filters( 'bbp_toggle_topic_notice_admin', $message, $topic_id, $notice, $is_failure );
768 + $class = ( $is_failure === true )
769 + ? 'error'
770 + : 'updated';
664 771
665 - <?php
666 - }
772 + // Add the notice
773 + bbp_admin()->add_notice( $message, $class, true );
667 774 }
668 775
669 776 /**
777 + * Returns an array of keys used to sort row actions
778 + *
779 + * @since 2.6.0 bbPress (r6771)
780 + *
781 + * @return array
782 + */
783 + private function get_row_action_sort_order() {
784 +
785 + // Filter & return
786 + return (array) apply_filters( 'bbp_admin_topics_row_action_sort_order', array(
787 + 'edit',
788 + 'stick',
789 + 'approved',
790 + 'unapproved',
791 + 'closed',
792 + 'spam',
793 + 'unspam',
794 + 'trash',
795 + 'untrash',
796 + 'delete',
797 + 'view'
798 + ) );
799 + }
800 +
801 + /**
802 + * Returns an array of notice toggles
803 + *
804 + * @since 2.6.0 bbPress (r6396)
805 + *
806 + * @return array
807 + */
808 + private function get_allowed_notice_toggles() {
809 +
810 + // Filter & return
811 + return (array) apply_filters( 'bbp_admin_topics_allowed_notice_toggles', array(
812 + 'opened',
813 + 'closed',
814 + 'super_sticky',
815 + 'stuck',
816 + 'unstuck',
817 + 'spammed',
818 + 'unspammed',
819 + 'approved',
820 + 'unapproved'
821 + ) );
822 + }
823 +
824 + /**
825 + * Returns an array of notice toggles
826 + *
827 + * @since 2.6.0 bbPress (r6396)
828 + *
829 + * @return array
830 + */
831 + private function get_allowed_action_toggles() {
832 +
833 + // Filter & return
834 + return (array) apply_filters( 'bbp_admin_topics_allowed_action_toggles', array(
835 + 'bbp_toggle_topic_close',
836 + 'bbp_toggle_topic_stick',
837 + 'bbp_toggle_topic_spam',
838 + 'bbp_toggle_topic_approve'
839 + ) );
840 + }
841 +
842 + /**
670 843 * Manage the column headers for the topics page
671 844 *
672 - * @since bbPress (r2485)
845 + * @since 2.0.0 bbPress (r2485)
673 846 *
674 847 * @param array $columns The columns
675 - * @uses apply_filters() Calls 'bbp_admin_topics_column_headers' with
676 - * the columns
848 + *
677 849 * @return array $columns bbPress topic columns
678 850 */
679 - public function topics_column_headers( $columns ) {
680 -
681 - if ( $this->bail() ) return $columns;
682 -
851 + public function column_headers( $columns ) {
683 852 $columns = array(
684 853 'cb' => '<input type="checkbox" />',
685 - 'title' => __( 'Topics', 'bbpress' ),
686 - 'bbp_topic_forum' => __( 'Forum', 'bbpress' ),
687 - 'bbp_topic_reply_count' => __( 'Replies', 'bbpress' ),
688 - 'bbp_topic_voice_count' => __( 'Voices', 'bbpress' ),
689 - 'bbp_topic_author' => __( 'Author', 'bbpress' ),
690 - 'bbp_topic_created' => __( 'Created', 'bbpress' ),
691 - 'bbp_topic_freshness' => __( 'Freshness', 'bbpress' )
854 + 'title' => esc_html__( 'Topics', 'bbpress' ),
855 + 'bbp_topic_forum' => esc_html__( 'Forum', 'bbpress' ),
856 + 'bbp_topic_reply_count' => esc_html__( 'Replies', 'bbpress' ),
857 + 'bbp_topic_voice_count' => esc_html__( 'Voices', 'bbpress' ),
858 + 'bbp_topic_author' => esc_html__( 'Author', 'bbpress' ),
859 + 'bbp_topic_created' => esc_html__( 'Created', 'bbpress' ),
860 + 'bbp_topic_freshness' => esc_html__( 'Last Post', 'bbpress' )
692 861 );
693 862
694 - return apply_filters( 'bbp_admin_topics_column_headers', $columns );
863 + // Filter & return
864 + return (array) apply_filters( 'bbp_admin_topics_column_headers', $columns );
695 865 }
696 866
697 867 /**
698 868 * Print extra columns for the topics page
699 869 *
700 - * @since bbPress (r2485)
870 + * @since 2.0.0 bbPress (r2485)
701 871 *
702 872 * @param string $column Column
703 873 * @param int $topic_id Topic id
704 - * @uses bbp_get_topic_forum_id() To get the forum id of the topic
705 - * @uses bbp_forum_title() To output the topic's forum title
706 - * @uses apply_filters() Calls 'topic_forum_row_actions' with an array
707 - * of topic forum actions
708 - * @uses bbp_get_forum_permalink() To get the forum permalink
709 - * @uses admin_url() To get the admin url of post.php
710 - * @uses add_query_arg() To add custom args to the url
711 - * @uses bbp_topic_reply_count() To output the topic reply count
712 - * @uses bbp_topic_voice_count() To output the topic voice count
713 - * @uses bbp_topic_author_display_name() To output the topic author name
714 - * @uses get_the_date() Get the topic creation date
715 - * @uses get_the_time() Get the topic creation time
716 - * @uses esc_attr() To sanitize the topic creation time
717 - * @uses bbp_get_topic_last_active_time() To get the time when the topic was
718 - * last active
719 - * @uses do_action() Calls 'bbp_admin_topics_column_data' with the
720 - * column and topic id
721 874 */
722 - function topics_column_data( $column, $topic_id ) {
875 + public function column_data( $column, $topic_id ) {
723 876
724 - if ( $this->bail() ) return;
725 -
726 877 // Get topic forum ID
727 878 $forum_id = bbp_get_topic_forum_id( $topic_id );
728 879
729 880 // Populate column data
@@ -731,22 +882,23 @@
731 882
732 883 // Forum
733 884 case 'bbp_topic_forum' :
734 885
886 + // Get title
887 + $forum_title = ! empty( $forum_id )
888 + ? bbp_get_forum_title( $forum_id )
889 + : '';
890 +
735 891 // Output forum name
736 - if ( !empty( $forum_id ) ) {
737 -
738 - // Forum Title
739 - $forum_title = bbp_get_forum_title( $forum_id );
740 - if ( empty( $forum_title ) ) {
741 - $forum_title = __( 'No Forum', 'bbpress' );
742 - }
743 -
744 - // Output the title
892 + if ( ! empty( $forum_title ) ) {
745 893 echo $forum_title;
746 894
895 + // Output dash
747 896 } else {
748 - _e( '(No Forum)', 'bbpress' );
897 + ?>
898 + <span aria-hidden="true">&mdash;</span>
899 + <span class="screen-reader-text"><?php esc_html_e( 'No forum', 'bbpress' ); ?></span>
900 + <?php
749 901 }
750 902
751 903 break;
752 904
@@ -766,9 +918,9 @@
766 918 break;
767 919
768 920 // Freshness
769 921 case 'bbp_topic_created':
770 - printf( __( '%1$s <br /> %2$s', 'bbpress' ),
922 + printf( '%1$s <br /> %2$s',
771 923 get_the_date(),
772 924 esc_attr( get_the_time() )
773 925 );
774 926
@@ -776,12 +928,12 @@
776 928
777 929 // Freshness
778 930 case 'bbp_topic_freshness' :
779 931 $last_active = bbp_get_topic_last_active_time( $topic_id, false );
780 - if ( !empty( $last_active ) ) {
781 - echo $last_active;
932 + if ( ! empty( $last_active ) ) {
933 + echo esc_html( $last_active );
782 934 } else {
783 - _e( 'No Replies', 'bbpress' ); // This should never happen
935 + esc_html_e( 'No Replies', 'bbpress' ); // This should never happen
784 936 }
785 937
786 938 break;
787 939
@@ -797,142 +949,196 @@
797 949 *
798 950 * Remove the quick-edit action link under the topic title and add the
799 951 * content and close/stick/spam links
800 952 *
801 - * @since bbPress (r2485)
953 + * @since 2.0.0 bbPress (r2485)
802 954 *
803 - * @param array $actions Actions
804 - * @param array $topic Topic object
805 - * @uses bbp_get_topic_post_type() To get the topic post type
806 - * @uses bbp_topic_content() To output topic content
807 - * @uses bbp_get_topic_permalink() To get the topic link
808 - * @uses bbp_get_topic_title() To get the topic title
809 - * @uses current_user_can() To check if the current user can edit or
810 - * delete the topic
811 - * @uses bbp_is_topic_open() To check if the topic is open
812 - * @uses bbp_is_topic_spam() To check if the topic is marked as spam
813 - * @uses bbp_is_topic_sticky() To check if the topic is a sticky or a
814 - * super sticky
815 - * @uses get_post_type_object() To get the topic post type object
816 - * @uses add_query_arg() To add custom args to the url
817 - * @uses remove_query_arg() To remove custom args from the url
818 - * @uses wp_nonce_url() To nonce the url
819 - * @uses get_delete_post_link() To get the delete post link of the topic
955 + * @param array $actions Actions
956 + * @param object $topic Topic object
957 + *
820 958 * @return array $actions Actions
821 959 */
822 - public function topics_row_actions( $actions, $topic ) {
960 + public function row_actions( $actions = array(), $topic = false ) {
823 961
824 - if ( $this->bail() ) return $actions;
962 + // Disable quick edit (too much to do here)
963 + unset( $actions['inline hide-if-no-js'] );
825 964
826 - unset( $actions['inline hide-if-no-js'] );
965 + // View link
966 + $view_link = bbp_get_topic_permalink( $topic->ID );
827 967
968 + // Maybe add view=all
969 + if ( ! in_array( $topic->post_status, array( bbp_get_closed_status_id(), bbp_get_public_status_id() ), true ) ) {
970 + $view_link = bbp_add_view_all( $view_link, true );
971 + }
972 +
828 973 // Show view link if it's not set, the topic is trashed and the user can view trashed topics
829 - if ( empty( $actions['view'] ) && ( bbp_get_trash_status_id() == $topic->post_status ) && current_user_can( 'view_trash' ) )
830 - $actions['view'] = '<a href="' . bbp_get_topic_permalink( $topic->ID ) . '" title="' . esc_attr( sprintf( __( 'View &#8220;%s&#8221;', 'bbpress' ), bbp_get_topic_title( $topic->ID ) ) ) . '" rel="permalink">' . __( 'View', 'bbpress' ) . '</a>';
974 + if ( empty( $actions['view'] ) && ( bbp_get_trash_status_id() === $topic->post_status ) && current_user_can( 'view_trash' ) ) {
975 + $actions['view'] = '<a href="' . esc_url( $view_link ) . '" title="' . esc_attr( sprintf( __( 'View &#8220;%s&#8221;', 'bbpress' ), bbp_get_topic_title( $topic->ID ) ) ) . '" rel="permalink">' . esc_html__( 'View', 'bbpress' ) . '</a>';
976 + }
831 977
832 978 // Only show the actions if the user is capable of viewing them :)
833 979 if ( current_user_can( 'moderate', $topic->ID ) ) {
834 980
981 + // Pending
982 + // Show the 'approve' and 'view' link on pending posts only and 'unapprove' on published posts only
983 + $approve_uri = wp_nonce_url( add_query_arg( array( 'topic_id' => $topic->ID, 'action' => 'bbp_toggle_topic_approve' ), remove_query_arg( array( 'bbp_topic_toggle_notice', 'topic_id', 'failed', 'super' ) ) ), 'approve-topic_' . $topic->ID );
984 + if ( bbp_is_topic_public( $topic->ID ) ) {
985 + $actions['unapproved'] = '<a href="' . esc_url( $approve_uri ) . '" title="' . esc_attr__( 'Unapprove this topic', 'bbpress' ) . '">' . _x( 'Unapprove', 'Unapprove Topic', 'bbpress' ) . '</a>';
986 + } else {
987 +
988 + // Do not show 'approve' if already public
989 + if ( ! bbp_is_topic_public( $topic->ID ) ) {
990 + $actions['approved'] = '<a href="' . esc_url( $approve_uri ) . '" title="' . esc_attr__( 'Approve this topic', 'bbpress' ) . '">' . _x( 'Approve', 'Approve Topic', 'bbpress' ) . '</a>';
991 + }
992 +
993 + // Modify the view link
994 + $actions['view'] = '<a href="' . esc_url( $view_link ) . '" title="' . esc_attr( sprintf( __( 'View &#8220;%s&#8221;', 'bbpress' ), bbp_get_topic_title( $topic->ID ) ) ) . '" rel="permalink">' . esc_html__( 'View', 'bbpress' ) . '</a>';
995 + }
996 +
835 997 // Close
836 998 // Show the 'close' and 'open' link on published and closed posts only
837 - if ( in_array( $topic->post_status, array( bbp_get_public_status_id(), bbp_get_closed_status_id() ) ) ) {
838 - $close_uri = esc_url( 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 ) );
839 - if ( bbp_is_topic_open( $topic->ID ) )
840 - $actions['closed'] = '<a href="' . $close_uri . '" title="' . esc_attr__( 'Close this topic', 'bbpress' ) . '">' . _x( 'Close', 'Close a Topic', 'bbpress' ) . '</a>';
841 - else
842 - $actions['closed'] = '<a href="' . $close_uri . '" title="' . esc_attr__( 'Open this topic', 'bbpress' ) . '">' . _x( 'Open', 'Open a Topic', 'bbpress' ) . '</a>';
999 + if ( bbp_is_topic_public( $topic->ID ) ) {
1000 + $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 );
1001 + if ( bbp_is_topic_open( $topic->ID ) ) {
1002 + $actions['closed'] = '<a href="' . esc_url( $close_uri ) . '" title="' . esc_attr__( 'Close this topic', 'bbpress' ) . '">' . _x( 'Close', 'Close a Topic', 'bbpress' ) . '</a>';
1003 + } else {
1004 + $actions['closed'] = '<a href="' . esc_url( $close_uri ) . '" title="' . esc_attr__( 'Open this topic', 'bbpress' ) . '">' . _x( 'Open', 'Open a Topic', 'bbpress' ) . '</a>';
1005 + }
843 1006 }
844 1007
845 - // Dont show sticky if topic links is spam or trash
846 - if ( !bbp_is_topic_spam( $topic->ID ) && !bbp_is_topic_trash( $topic->ID ) ) {
847 -
848 - // Sticky
849 - $stick_uri = esc_url( 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 ) );
1008 + // Sticky
1009 + // Dont show sticky if topic is spam, trash or pending
1010 + if ( ! bbp_is_topic_spam( $topic->ID ) && ! bbp_is_topic_trash( $topic->ID ) && ! bbp_is_topic_pending( $topic->ID ) ) {
1011 + $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 );
850 1012 if ( bbp_is_topic_sticky( $topic->ID ) ) {
851 - $actions['stick'] = '<a href="' . $stick_uri . '" title="' . esc_attr__( 'Unstick this topic', 'bbpress' ) . '">' . __( 'Unstick', 'bbpress' ) . '</a>';
1013 + $actions['stick'] = '<a href="' . esc_url( $stick_uri ) . '" title="' . esc_attr__( 'Unstick this topic', 'bbpress' ) . '">' . esc_html__( 'Unstick', 'bbpress' ) . '</a>';
852 1014 } else {
853 - $super_uri = esc_url( 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 ) );
854 - $actions['stick'] = '<a href="' . $stick_uri . '" title="' . esc_attr__( 'Stick this topic to its forum', 'bbpress' ) . '">' . __( 'Stick', 'bbpress' ) . '</a> (<a href="' . $super_uri . '" title="' . esc_attr__( 'Stick this topic to front', 'bbpress' ) . '">' . __( 'to front', 'bbpress' ) . '</a>)';
1015 + $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 );
1016 + $actions['stick'] = '<a href="' . esc_url( $stick_uri ) . '" title="' . esc_attr__( 'Stick this topic to its forum', 'bbpress' ) . '">' . esc_html__( 'Stick', 'bbpress' ) . '</a> <a href="' . esc_url( $super_uri ) . '" title="' . esc_attr__( 'Stick this topic to front', 'bbpress' ) . '">' . esc_html__( '(to front)', 'bbpress' ) . '</a>';
855 1017 }
856 1018 }
857 1019
858 1020 // Spam
859 - $spam_uri = esc_url( 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 ) );
860 - if ( bbp_is_topic_spam( $topic->ID ) )
861 - $actions['spam'] = '<a href="' . $spam_uri . '" title="' . esc_attr__( 'Mark the topic as not spam', 'bbpress' ) . '">' . __( 'Not spam', 'bbpress' ) . '</a>';
862 - else
863 - $actions['spam'] = '<a href="' . $spam_uri . '" title="' . esc_attr__( 'Mark this topic as spam', 'bbpress' ) . '">' . __( 'Spam', 'bbpress' ) . '</a>';
864 -
1021 + $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 );
1022 + if ( ! bbp_is_topic_spam( $topic->ID ) ) {
1023 + $actions['spam'] = '<a href="' . esc_url( $spam_uri ) . '" title="' . esc_attr__( 'Mark this topic as spam', 'bbpress' ) . '">' . esc_html__( 'Spam', 'bbpress' ) . '</a>';
1024 + } else {
1025 + $actions['unspam'] = '<a href="' . esc_url( $spam_uri ) . '" title="' . esc_attr__( 'Mark the topic as not spam', 'bbpress' ) . '">' . esc_html__( 'Not Spam', 'bbpress' ) . '</a>';
1026 + }
865 1027 }
866 1028
867 1029 // Do not show trash links for spam topics, or spam links for trashed topics
868 1030 if ( current_user_can( 'delete_topic', $topic->ID ) ) {
869 - if ( bbp_get_trash_status_id() == $topic->post_status ) {
1031 + $trash_days = bbp_get_trash_days( bbp_get_topic_post_type() );
1032 +
1033 + if ( bbp_get_trash_status_id() === $topic->post_status ) {
870 1034 $post_type_object = get_post_type_object( bbp_get_topic_post_type() );
871 - $actions['untrash'] = "<a title='" . esc_attr__( 'Restore this item from the Trash', 'bbpress' ) . "' href='" . 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 ) . "'>" . __( 'Restore', 'bbpress' ) . "</a>";
872 - } elseif ( EMPTY_TRASH_DAYS ) {
873 - $actions['trash'] = "<a class='submitdelete' title='" . esc_attr__( 'Move this item to the Trash', 'bbpress' ) . "' href='" . 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 ) ) . "'>" . __( 'Trash', 'bbpress' ) . "</a>";
1035 + $actions['untrash'] = "<a title='" . esc_attr__( 'Restore this item from the Trash', 'bbpress' ) . "' href='" . esc_url( wp_nonce_url( admin_url( sprintf( $post_type_object->_edit_link . '&amp;action=untrash', $topic->ID ) ), 'untrash-post_' . $topic->ID ) ) . "'>" . esc_html__( 'Restore', 'bbpress' ) . "</a>";
1036 + } elseif ( ! empty( $trash_days ) ) {
1037 + $actions['trash'] = "<a class='submitdelete' title='" . esc_attr__( 'Move this item to the Trash', 'bbpress' ) . "' href='" . esc_url( get_delete_post_link( $topic->ID ) ) . "'>" . esc_html__( 'Trash', 'bbpress' ) . "</a>";
874 1038 }
875 1039
876 - if ( bbp_get_trash_status_id() == $topic->post_status || !EMPTY_TRASH_DAYS ) {
877 - $actions['delete'] = "<a class='submitdelete' title='" . esc_attr__( 'Delete this item permanently', 'bbpress' ) . "' href='" . 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 ) ) . "'>" . __( 'Delete Permanently', 'bbpress' ) . "</a>";
878 - } elseif ( bbp_get_spam_status_id() == $topic->post_status ) {
879 - unset( $actions['trash'] );
1040 + if ( ( bbp_get_trash_status_id() === $topic->post_status ) || empty( $trash_days ) ) {
1041 + $actions['delete'] = "<a class='submitdelete' title='" . esc_attr__( 'Delete this item permanently', 'bbpress' ) . "' href='" . esc_url( get_delete_post_link( $topic->ID, '', true ) ) . "'>" . esc_html__( 'Delete Permanently', 'bbpress' ) . "</a>";
880 1042 }
881 1043 }
882 1044
883 - return $actions;
1045 + // Sort & return
1046 + return $this->sort_row_actions( $actions );
884 1047 }
885 1048
886 1049 /**
1050 + * Sort row actions by key
1051 + *
1052 + * @since 2.6.0
1053 + *
1054 + * @param array $actions
1055 + *
1056 + * @return array
1057 + */
1058 + private function sort_row_actions( $actions = array() ) {
1059 +
1060 + // Return value
1061 + $retval = array();
1062 +
1063 + // Known row actions, in sort order
1064 + $known_actions = $this->get_row_action_sort_order();
1065 +
1066 + // Sort known actions, and keep any unknown ones
1067 + foreach ( $known_actions as $key ) {
1068 + if ( isset( $actions[ $key ] ) ) {
1069 + $retval[ $key ] = $actions[ $key ];
1070 + unset( $actions[ $key ] );
1071 + }
1072 + }
1073 +
1074 + // Combine & return
1075 + return $retval + $actions;
1076 + }
1077 +
1078 + /**
887 1079 * Add forum dropdown to topic and reply list table filters
888 1080 *
889 - * @since bbPress (r2991)
1081 + * @since 2.0.0 bbPress (r2991)
890 1082 *
891 - * @uses bbp_get_reply_post_type() To get the reply post type
892 - * @uses bbp_get_topic_post_type() To get the topic post type
893 - * @uses bbp_dropdown() To generate a forum dropdown
894 1083 * @return bool False. If post type is not topic or reply
895 1084 */
896 1085 public function filter_dropdown() {
897 1086
898 - if ( $this->bail() ) return;
899 -
900 - // Add Empty Spam button
901 - if ( !empty( $_GET['post_status'] ) && ( bbp_get_spam_status_id() == $_GET['post_status'] ) && current_user_can( 'moderate' ) ) {
902 - wp_nonce_field( 'bulk-destroy', '_destroy_nonce' );
903 - $title = esc_attr__( 'Empty Spam', 'bbpress' );
904 - submit_button( $title, 'button-secondary apply', 'delete_all', false );
905 - }
906 -
907 1087 // Get which forum is selected
908 - $selected = !empty( $_GET['bbp_forum_id'] ) ? $_GET['bbp_forum_id'] : '';
1088 + $selected = ! empty( $_GET['bbp_forum_id'] )
1089 + ? (int) $_GET['bbp_forum_id']
1090 + : 0;
909 1091
910 1092 // Show the forums dropdown
911 1093 bbp_dropdown( array(
912 1094 'selected' => $selected,
913 - 'show_none' => __( 'In all forums', 'bbpress' )
1095 + 'show_none' => esc_html__( 'In all forums', 'bbpress' )
914 1096 ) );
915 1097 }
916 1098
917 1099 /**
1100 + * Add "Empty Spam" button for moderators
1101 + *
1102 + * @since 2.6.0 bbPress (r6791)
1103 + */
1104 + public function filter_empty_spam() {
1105 +
1106 + // Bail if not viewing spam
1107 + if ( empty( $_GET['post_status'] ) || ( bbp_get_spam_status_id() !== $_GET['post_status'] ) && current_user_can( 'moderate' ) ) {
1108 + return;
1109 + }
1110 +
1111 + ?>
1112 +
1113 + <div class="alignleft actions"><?php
1114 +
1115 + // Output the nonce & button
1116 + wp_nonce_field( 'bulk-destroy', '_destroy_nonce' );
1117 + submit_button(
1118 + esc_attr__( 'Empty Spam', 'bbpress' ),
1119 + 'button-secondary apply',
1120 + 'delete_all',
1121 + false
1122 + );
1123 +
1124 + ?></div><?php
1125 + }
1126 +
1127 + /**
918 1128 * Adjust the request query and include the forum id
919 1129 *
920 - * @since bbPress (r2991)
1130 + * @since 2.0.0 bbPress (r2991)
921 1131 *
922 1132 * @param array $query_vars Query variables from {@link WP_Query}
923 - * @uses is_admin() To check if it's the admin section
924 - * @uses bbp_get_topic_post_type() To get the topic post type
925 - * @uses bbp_get_reply_post_type() To get the reply post type
926 1133 * @return array Processed Query Vars
927 1134 */
928 1135 function filter_post_rows( $query_vars ) {
929 1136
930 - if ( $this->bail() ) return $query_vars;
931 -
932 1137 // Add post_parent query_var if one is present
933 - if ( !empty( $_GET['bbp_forum_id'] ) ) {
1138 + if ( ! empty( $_GET['bbp_forum_id'] ) ) {
934 1139 $query_vars['meta_key'] = '_bbp_forum_id';
1140 + $query_vars['meta_type'] = 'NUMERIC';
935 1141 $query_vars['meta_value'] = $_GET['bbp_forum_id'];
936 1142 }
937 1143
938 1144 // Return manipulated query_vars
@@ -941,15 +1147,11 @@
941 1147
942 1148 /**
943 1149 * Custom user feedback messages for topic post type
944 1150 *
945 - * @since bbPress (r3080)
1151 + * @since 2.0.0 bbPress (r3080)
946 1152 *
947 1153 * @global int $post_ID
948 - * @uses bbp_get_topic_permalink()
949 - * @uses wp_post_revision_title()
950 - * @uses esc_url()
951 - * @uses add_query_arg()
952 1154 *
953 1155 * @param array $messages
954 1156 *
955 1157 * @return array
@@ -956,10 +1158,8 @@
956 1158 */
957 1159 public function updated_messages( $messages ) {
958 1160 global $post_ID;
959 1161
960 - if ( $this->bail() ) return $messages;
961 -
962 1162 // URL for the current topic
963 1163 $topic_url = bbp_get_topic_permalink( $post_ID );
964 1164
965 1165 // Current topic's post_date
@@ -965,47 +1165,72 @@
965 1165 // Current topic's post_date
966 1166 $post_date = bbp_get_global_post_field( 'post_date', 'raw' );
967 1167
968 1168 // Messages array
969 - $messages[$this->post_type] = array(
1169 + $messages[ $this->post_type ] = array(
970 1170 0 => '', // Left empty on purpose
971 1171
972 1172 // Updated
973 - 1 => sprintf( __( 'Topic updated. <a href="%s">View topic</a>', 'bbpress' ), $topic_url ),
1173 + 1 => sprintf(
1174 + '%1$s <a href="%2$s">%3$s</a>',
1175 + esc_html__( 'Topic updated.', 'bbpress' ),
1176 + $topic_url,
1177 + esc_html__( 'View topic', 'bbpress' )
1178 + ),
974 1179
975 1180 // Custom field updated
976 - 2 => __( 'Custom field updated.', 'bbpress' ),
1181 + 2 => esc_html__( 'Custom field updated.', 'bbpress' ),
977 1182
978 1183 // Custom field deleted
979 - 3 => __( 'Custom field deleted.', 'bbpress' ),
1184 + 3 => esc_html__( 'Custom field deleted.', 'bbpress' ),
980 1185
981 1186 // Topic updated
982 - 4 => __( 'Topic updated.', 'bbpress' ),
1187 + 4 => esc_html__( 'Topic updated.', 'bbpress' ),
983 1188
984 1189 // Restored from revision
985 1190 // translators: %s: date and time of the revision
986 1191 5 => isset( $_GET['revision'] )
987 - ? sprintf( __( 'Topic restored to revision from %s', 'bbpress' ), wp_post_revision_title( (int) $_GET['revision'], false ) )
1192 + ? sprintf( esc_html__( 'Topic restored to revision from %s', 'bbpress' ), wp_post_revision_title( (int) $_GET['revision'], false ) )
988 1193 : false,
989 1194
990 1195 // Topic created
991 - 6 => sprintf( __( 'Topic created. <a href="%s">View topic</a>', 'bbpress' ), $topic_url ),
1196 + 6 => sprintf(
1197 + '%1$s <a href="%2$s">%3$s</a>',
1198 + esc_html__( 'Topic created.', 'bbpress' ),
1199 + $topic_url,
1200 + esc_html__( 'View topic', 'bbpress' )
1201 + ),
992 1202
993 1203 // Topic saved
994 - 7 => __( 'Topic saved.', 'bbpress' ),
1204 + 7 => esc_html__( 'Topic saved.', 'bbpress' ),
995 1205
996 1206 // Topic submitted
997 - 8 => sprintf( __( 'Topic submitted. <a target="_blank" href="%s">Preview topic</a>', 'bbpress' ), esc_url( add_query_arg( 'preview', 'true', $topic_url ) ) ),
1207 + 8 => sprintf(
1208 + '%1$s <a href="%2$s" target="_blank">%3$s</a>',
1209 + esc_html__( 'Topic submitted.', 'bbpress' ),
1210 + esc_url( add_query_arg( 'preview', 'true', $topic_url ) ),
1211 + esc_html__( 'Preview topic', 'bbpress' )
1212 + ),
998 1213
999 1214 // Topic scheduled
1000 - 9 => sprintf( __( 'Topic scheduled for: <strong>%1$s</strong>. <a target="_blank" href="%2$s">Preview topic</a>', 'bbpress' ),
1215 + 9 => sprintf(
1216 + '%1$s <a target="_blank" href="%2$s">%3$s</a>',
1217 + sprintf(
1218 + esc_html__( 'Topic scheduled for: %s.', 'bbpress' ),
1001 1219 // translators: Publish box date format, see http://php.net/date
1002 - date_i18n( __( 'M j, Y @ G:i', 'bbpress' ),
1003 - strtotime( $post_date ) ),
1004 - $topic_url ),
1220 + '<strong>' . date_i18n( __( 'M j, Y @ G:i', 'bbpress' ), strtotime( $post_date ) ) . '</strong>'
1221 + ),
1222 + $topic_url,
1223 + esc_html__( 'Preview topic', 'bbpress' )
1224 + ),
1005 1225
1006 1226 // Topic draft updated
1007 - 10 => sprintf( __( 'Topic draft updated. <a target="_blank" href="%s">Preview topic</a>', 'bbpress' ), esc_url( add_query_arg( 'preview', 'true', $topic_url ) ) ),
1227 + 10 => sprintf(
1228 + '%1$s <a href="%2$s" target="_blank">%3$s</a>',
1229 + esc_html__( 'Topic draft updated.', 'bbpress' ),
1230 + esc_url( add_query_arg( 'preview', 'true', $topic_url ) ),
1231 + esc_html__( 'Preview topic', 'bbpress' )
1232 + ),
1008 1233 );
1009 1234
1010 1235 return $messages;
1011 1236 }
@@ -1017,11 +1242,18 @@
1017 1242 *
1018 1243 * This is currently here to make hooking and unhooking of the admin UI easy.
1019 1244 * It could use dependency injection in the future, but for now this is easier.
1020 1245 *
1021 - * @since bbPress (r2596)
1246 + * @since 2.0.0 bbPress (r2596)
1022 1247 *
1023 - * @uses BBP_Forums_Admin
1248 + * @param WP_Screen $current_screen Current screen object
1024 1249 */
1025 -function bbp_admin_topics() {
1026 - bbpress()->admin->topics = new BBP_Topics_Admin();
1250 +function bbp_admin_topics( $current_screen ) {
1251 +
1252 + // Bail if not a forum screen
1253 + if ( empty( $current_screen->post_type ) || ( bbp_get_topic_post_type() !== $current_screen->post_type ) ) {
1254 + return;
1255 + }
1256 +
1257 + // Init the topics admin
1258 + bbp_admin()->topics = new BBP_Topics_Admin();
1027 1259 }