PluginProbe
bbPress / 2.6.19
bbPress v2.6.19
2.6.19 2.6.18 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 All 74 releases
← All changes | includes/admin/topics.php +131 -34 2.6.18 → 2.6.19 View file →
@@ -15,9 +15,9 @@
15 15 * Loads bbPress topics admin area
16 16 *
17 17 * @package bbPress
18 18 * @subpackage Administration
19 - * @since 2.0.0 bbPress (r2464)
19 + * @since 2.0.0 bbPress (r3095)
20 20 */
21 21 class BBP_Topics_Admin {
22 22
23 23 /** Variables *************************************************************/
@@ -26,14 +26,16 @@
26 26 * @var The post type of this admin component
27 27 */
28 28 private $post_type = '';
29 29
30 + private $accepted_forum_moves = array();
31 +
30 32 /** Functions *************************************************************/
31 33
32 34 /**
33 35 * The main bbPress topics admin loader
34 36 *
35 - * @since 2.0.0 bbPress (r2515)
37 + * @since 2.0.0 bbPress (r3095)
36 38 */
37 39 public function __construct() {
38 40 $this->setup_globals();
39 41 $this->setup_actions();
@@ -41,9 +43,9 @@
41 43
42 44 /**
43 45 * Setup the admin hooks, actions and filters
44 46 *
45 - * @since 2.0.0 bbPress (r2646)
47 + * @since 2.0.0 bbPress (r3376)
46 48 * @since 2.6.0 bbPress (r6101) Added bulk actions
47 49 *
48 50 * @access private
49 51 */
@@ -74,8 +76,9 @@
74 76 add_action( 'add_meta_boxes', array( $this, 'favorites_metabox' ) );
75 77 add_action( 'add_meta_boxes', array( $this, 'subscriptions_metabox' ) );
76 78 add_action( 'add_meta_boxes', array( $this, 'comments_metabox' ) );
77 79 add_action( 'save_post', array( $this, 'save_meta_boxes' ) );
80 + add_filter( 'wp_insert_post_data', array( $this, 'filter_post_data' ), 20, 2 );
78 81
79 82 // Check if there are any bbp_toggle_topic_* requests on admin_init, also have a message displayed
80 83 add_action( 'load-edit.php', array( $this, 'toggle_topic' ) );
81 84 add_action( 'load-edit.php', array( $this, 'toggle_topic_notice' ) );
@@ -95,9 +98,9 @@
95 98
96 99 /**
97 100 * Admin globals
98 101 *
99 - * @since 2.0.0 bbPress (r2646)
102 + * @since 2.0.0 bbPress (r3376)
100 103 *
101 104 * @access private
102 105 */
103 106 private function setup_globals() {
@@ -108,9 +111,9 @@
108 111
109 112 /**
110 113 * Contextual help for bbPress topic edit page
111 114 *
112 - * @since 2.0.0 bbPress (r3119)
115 + * @since 2.1.0 bbPress (r3686)
113 116 */
114 117 public function edit_help() {
115 118
116 119 // Overview
@@ -180,9 +183,9 @@
180 183
181 184 /**
182 185 * Contextual help for bbPress topic edit page
183 186 *
184 - * @since 2.0.0 bbPress (r3119)
187 + * @since 2.1.0 bbPress (r3686)
185 188 */
186 189 public function new_help() {
187 190
188 191 $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>';
@@ -356,9 +359,9 @@
356 359
357 360 /**
358 361 * Add the topic attributes meta-box
359 362 *
360 - * @since 2.0.0 bbPress (r2744)
363 + * @since 2.1.0 bbPress (r3749)
361 364 */
362 365 public function attributes_metabox() {
363 366 add_meta_box(
364 367 'bbp_topic_attributes',
@@ -372,9 +375,9 @@
372 375
373 376 /**
374 377 * Add the author info meta-box
375 378 *
376 - * @since 2.0.0 bbPress (r2828)
379 + * @since 2.0.0 bbPress (r3120)
377 380 */
378 381 public function author_metabox() {
379 382
380 383 // Bail if post_type is not a topic
@@ -423,9 +426,9 @@
423 426 * Add the engagements meta-box
424 427 *
425 428 * Allows viewing of users who have engaged in a topic.
426 429 *
427 - * @since 2.6.0 bbPress (r6333)
430 + * @since 2.6.0 bbPress (r6334)
428 431 */
429 432 public function engagements_metabox() {
430 433
431 434 // Bail when creating a new topic
@@ -523,15 +526,24 @@
523 526
524 527 /**
525 528 * Pass the topic attributes for processing
526 529 *
527 - * @since 2.0.0 bbPress (r2746)
530 + * @since 2.6.0 bbPress (r6056)
528 531 *
529 532 * @param int $topic_id Topic id
530 533 * @return int Parent id
531 534 */
532 535 public function save_meta_boxes( $topic_id ) {
536 + $accepted_move = isset( $this->accepted_forum_moves[ $topic_id ] )
537 + ? $this->accepted_forum_moves[ $topic_id ]
538 + : array();
539 + unset( $this->accepted_forum_moves[ $topic_id ] );
533 540
541 + // Revisions can also fire save_post with the metabox nonce.
542 + if ( ! bbp_is_topic( $topic_id ) ) {
543 + return $topic_id;
544 + }
545 +
534 546 // Bail if doing an autosave
535 547 if ( bbp_doing_autosave() ) {
536 548 return $topic_id;
537 549 }
@@ -551,14 +563,16 @@
551 563 return $topic_id;
552 564 }
553 565
554 566 // Bail if current user cannot edit this topic
555 - if ( ! current_user_can( 'edit_topic', $topic_id ) ) {
567 + if ( ! current_user_can( 'edit_topic', $topic_id ) && empty( $accepted_move ) ) {
556 568 return $topic_id;
557 569 }
558 570
559 - // Get the forum ID
560 - $forum_id = ! empty( $_POST['parent_id'] ) ? (int) $_POST['parent_id'] : 0;
571 + // Use the parent accepted by WordPress and the destination filter.
572 + $forum_id = ! empty( $accepted_move )
573 + ? $accepted_move['new']
574 + : bbp_get_topic_forum_id( $topic_id );
561 575
562 576 // Get topic author data
563 577 $anonymous_data = bbp_filter_anonymous_post_data();
564 578 $author_id = bbp_get_topic_author_id( $topic_id );
@@ -565,8 +579,11 @@
565 579 $is_edit = ( isset( $_POST['hidden_post_status'] ) && ( 'draft' !== $_POST['hidden_post_status'] ) );
566 580
567 581 // Formally update the topic
568 582 bbp_update_topic( $topic_id, $forum_id, $anonymous_data, $author_id, $is_edit );
583 + if ( ! empty( $accepted_move['old'] ) ) {
584 + bbp_move_topic_handler( $topic_id, $accepted_move['old'], $accepted_move['new'] );
585 + }
569 586
570 587 // Allow other fun things to happen
571 588 do_action( 'bbp_topic_attributes_metabox_save', $topic_id, $forum_id );
572 589 do_action( 'bbp_author_metabox_save', $topic_id, $anonymous_data );
@@ -574,14 +591,81 @@
574 591 return $topic_id;
575 592 }
576 593
577 594 /**
595 + * Keep admin topic moves within forums the current user may use.
596 + *
597 + * @since 2.6.19 bbPress (r7688)
598 + *
599 + * @param array $data Sanitized post data.
600 + * @param array $postarr Unprocessed post data.
601 + * @return array Filtered post data.
602 + */
603 + public function filter_post_data( $data, $postarr ) {
604 +
605 + // Only filter administration saves of existing topics.
606 + if ( ! is_admin() || empty( $postarr['ID'] ) || ( bbp_get_topic_post_type() !== $data['post_type'] ) ) {
607 + return $data;
608 + }
609 +
610 + $topic = bbp_get_topic( $postarr['ID'] );
611 + if ( empty( $topic ) || (int) $topic->post_parent === (int) $data['post_parent'] ) {
612 + return $data;
613 + }
614 +
615 + $old_forum_id = (int) $topic->post_parent;
616 + $new_forum_id = (int) $data['post_parent'];
617 + $is_new = ( 'auto-draft' === $topic->post_status );
618 + $is_editor = ! empty( $_POST['action'] ) && ( 'editpost' === $_POST['action'] );
619 +
620 + // Other admin save paths cannot complete a bbPress topic move.
621 + if ( ! $is_editor && ! $is_new ) {
622 + $data['post_parent'] = $topic->post_parent;
623 + return $data;
624 + }
625 +
626 + // Match the front-end topic move checks before WordPress changes post_parent.
627 + if (
628 + ! $is_editor
629 + || empty( $_POST['bbp_topic_metabox'] )
630 + || ! is_string( $_POST['bbp_topic_metabox'] )
631 + || ! wp_verify_nonce( $_POST['bbp_topic_metabox'], 'bbp_topic_metabox_save' )
632 + || ! current_user_can( 'edit_topic', $topic->ID )
633 + || ( $is_new && ! current_user_can( 'publish_topics' ) )
634 + || ( ! empty( $old_forum_id ) && ! current_user_can( 'edit_forum', $old_forum_id ) )
635 + || ! bbp_get_forum( $new_forum_id )
636 + || bbp_is_forum_category( $new_forum_id )
637 + || ! current_user_can( 'read_forum', $new_forum_id )
638 + || ( bbp_is_forum_closed( $new_forum_id ) && ! current_user_can( 'edit_forum', $new_forum_id ) )
639 + ) {
640 + if ( $is_new ) {
641 + wp_die(
642 + esc_html__( 'The selected forum is not available for this topic.', 'bbpress' ),
643 + '',
644 + array(
645 + 'response' => 403,
646 + 'back_link' => true,
647 + )
648 + );
649 + }
650 + $data['post_parent'] = $topic->post_parent;
651 + } else {
652 + $this->accepted_forum_moves[ $topic->ID ] = array(
653 + 'old' => $old_forum_id,
654 + 'new' => $new_forum_id,
655 + );
656 + }
657 +
658 + return $data;
659 + }
660 +
661 + /**
578 662 * Toggle topic
579 663 *
580 664 * Handles the admin-side opening/closing, sticking/unsticking and
581 665 * spamming/unspamming of topics
582 666 *
583 - * @since 2.0.0 bbPress (r2727)
667 + * @since 2.0.0 bbPress (r3095)
584 668 */
585 669 public function toggle_topic() {
586 670
587 671 // Bail if not a topic toggle action
@@ -605,8 +689,13 @@
605 689 if ( ! current_user_can( 'moderate', $topic_id ) ) {
606 690 wp_die( esc_html__( 'You do not have permission to do that.', 'bbpress' ) );
607 691 }
608 692
693 + // Super stickies affect every forum and require global moderation
694 + if ( ( 'bbp_toggle_topic_stick' === $action ) && ! current_user_can( 'moderate' ) && ( bbp_is_topic_super_sticky( $topic_id ) || ( ! bbp_is_topic_sticky( $topic_id ) && ! empty( $_GET['super'] ) && ( '1' === $_GET['super'] ) ) ) ) {
695 + wp_die( esc_html__( 'You do not have permission to do that.', 'bbpress' ) );
696 + }
697 +
609 698 // Defaults
610 699 $post_data = array( 'ID' => $topic_id );
611 700 $message = '';
612 701 $success = false;
@@ -698,9 +787,9 @@
698 787 *
699 788 * Display the success/error notices from
700 789 * {@link BBP_Admin::toggle_topic()}
701 790 *
702 - * @since 2.0.0 bbPress (r2727)
791 + * @since 2.0.0 bbPress (r3095)
703 792 */
704 793 public function toggle_topic_notice() {
705 794
706 795 // Bail if missing topic toggle action
@@ -817,9 +906,9 @@
817 906
818 907 /**
819 908 * Returns an array of keys used to sort row actions
820 909 *
821 - * @since 2.6.0 bbPress (r6771)
910 + * @since 2.6.0 bbPress (r6772)
822 911 *
823 912 * @return array
824 913 */
825 914 private function get_row_action_sort_order() {
@@ -845,9 +934,9 @@
845 934
846 935 /**
847 936 * Returns an array of notice toggles
848 937 *
849 - * @since 2.6.0 bbPress (r6396)
938 + * @since 2.6.0 bbPress (r6397)
850 939 *
851 940 * @return array
852 941 */
853 942 private function get_allowed_notice_toggles() {
@@ -871,9 +960,9 @@
871 960
872 961 /**
873 962 * Returns an array of notice toggles
874 963 *
875 - * @since 2.6.0 bbPress (r6396)
964 + * @since 2.6.0 bbPress (r6397)
876 965 *
877 966 * @return array
878 967 */
879 968 private function get_allowed_action_toggles() {
@@ -892,9 +981,9 @@
892 981
893 982 /**
894 983 * Manage the column headers for the topics page
895 984 *
896 - * @since 2.0.0 bbPress (r2485)
985 + * @since 2.4.0 bbPress (r4991)
897 986 *
898 987 * @param array $columns The columns
899 988 *
900 989 * @return array $columns bbPress topic columns
@@ -917,9 +1006,9 @@
917 1006
918 1007 /**
919 1008 * Print extra columns for the topics page
920 1009 *
921 - * @since 2.0.0 bbPress (r2485)
1010 + * @since 2.4.0 bbPress (r4991)
922 1011 *
923 1012 * @param string $column Column
924 1013 * @param int $topic_id Topic id
925 1014 */
@@ -1000,9 +1089,9 @@
1000 1089 *
1001 1090 * Remove the quick-edit action link under the topic title and add the
1002 1091 * content and close/stick/spam links
1003 1092 *
1004 - * @since 2.0.0 bbPress (r2485)
1093 + * @since 2.4.0 bbPress (r4991)
1005 1094 *
1006 1095 * @param array $actions Actions
1007 1096 * @param object $topic Topic object
1008 1097 *
@@ -1067,9 +1156,9 @@
1067 1156 }
1068 1157
1069 1158 // Sticky
1070 1159 // Dont show sticky if topic is spam, trash or pending
1071 - if ( ! bbp_is_topic_spam( $topic->ID ) && ! bbp_is_topic_trash( $topic->ID ) && ! bbp_is_topic_pending( $topic->ID ) ) {
1160 + if ( ! bbp_is_topic_spam( $topic->ID ) && ! bbp_is_topic_trash( $topic->ID ) && ! bbp_is_topic_pending( $topic->ID ) && ( ! bbp_is_topic_super_sticky( $topic->ID ) || current_user_can( 'moderate' ) ) ) {
1072 1161 $args = array(
1073 1162 'topic_id' => $topic->ID,
1074 1163 'action' => 'bbp_toggle_topic_stick'
1075 1164 );
@@ -1076,15 +1165,18 @@
1076 1165 $stick_uri = wp_nonce_url( add_query_arg( $args, remove_query_arg( array( 'bbp_topic_toggle_notice', 'topic_id', 'failed', 'super' ) ) ), 'stick-topic_' . $topic->ID );
1077 1166 if ( bbp_is_topic_sticky( $topic->ID ) ) {
1078 1167 $actions['stick'] = '<a href="' . esc_url( $stick_uri ) . '" title="' . esc_attr__( 'Unstick this topic', 'bbpress' ) . '">' . esc_html__( 'Unstick', 'bbpress' ) . '</a>';
1079 1168 } else {
1080 - $args = array(
1081 - 'topic_id' => $topic->ID,
1082 - 'action' => 'bbp_toggle_topic_stick',
1083 - 'super' => '1'
1084 - );
1085 - $super_uri = wp_nonce_url( add_query_arg( $args, remove_query_arg( array( 'bbp_topic_toggle_notice', 'topic_id', 'failed', 'super' ) ) ), 'stick-topic_' . $topic->ID );
1086 - $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>';
1169 + $actions['stick'] = '<a href="' . esc_url( $stick_uri ) . '" title="' . esc_attr__( 'Stick this topic to its forum', 'bbpress' ) . '">' . esc_html__( 'Stick', 'bbpress' ) . '</a>';
1170 + if ( current_user_can( 'moderate' ) ) {
1171 + $args = array(
1172 + 'topic_id' => $topic->ID,
1173 + 'action' => 'bbp_toggle_topic_stick',
1174 + 'super' => '1'
1175 + );
1176 + $super_uri = wp_nonce_url( add_query_arg( $args, remove_query_arg( array( 'bbp_topic_toggle_notice', 'topic_id', 'failed', 'super' ) ) ), 'stick-topic_' . $topic->ID );
1177 + $actions['stick'] .= ' <a href="' . esc_url( $super_uri ) . '" title="' . esc_attr__( 'Stick this topic to front', 'bbpress' ) . '">' . esc_html__( '(to front)', 'bbpress' ) . '</a>';
1178 + }
1087 1179 }
1088 1180 }
1089 1181
1090 1182 // Spam
@@ -1122,9 +1214,9 @@
1122 1214
1123 1215 /**
1124 1216 * Sort row actions by key
1125 1217 *
1126 - * @since 2.6.0
1218 + * @since 2.6.0 bbPress (r6772)
1127 1219 *
1128 1220 * @param array $actions
1129 1221 *
1130 1222 * @return array
@@ -1151,9 +1243,9 @@
1151 1243
1152 1244 /**
1153 1245 * Add forum dropdown to topic and reply list table filters
1154 1246 *
1155 - * @since 2.0.0 bbPress (r2991)
1247 + * @since 2.0.0 bbPress (r3095)
1156 1248 *
1157 1249 * @return bool False. If post type is not topic or reply
1158 1250 */
1159 1251 public function filter_dropdown() {
@@ -1202,9 +1294,9 @@
1202 1294
1203 1295 /**
1204 1296 * Adjust the request query and include the forum id
1205 1297 *
1206 - * @since 2.0.0 bbPress (r2991)
1298 + * @since 2.0.0 bbPress (r3095)
1207 1299 *
1208 1300 * @param array $query_vars Query variables from {@link WP_Query}
1209 1301 * @return array Processed Query Vars
1210 1302 */
@@ -1223,9 +1315,9 @@
1223 1315
1224 1316 /**
1225 1317 * Custom user feedback messages for topic post type
1226 1318 *
1227 - * @since 2.0.0 bbPress (r3080)
1319 + * @since 2.0.0 bbPress (r3097)
1228 1320 *
1229 1321 * @global int $post_ID
1230 1322 *
1231 1323 * @param array $messages
@@ -1319,13 +1411,18 @@
1319 1411 *
1320 1412 * This is currently here to make hooking and unhooking of the admin UI easy.
1321 1413 * It could use dependency injection in the future, but for now this is easier.
1322 1414 *
1323 - * @since 2.0.0 bbPress (r2596)
1415 + * @since 2.0.0 bbPress (r3343)
1324 1416 *
1325 1417 * @param WP_Screen $current_screen Current screen object
1326 1418 */
1327 1419 function bbp_admin_topics( $current_screen ) {
1420 +
1421 + // Bail if not in site admin
1422 + if ( ! is_blog_admin() ) {
1423 + return;
1424 + }
1328 1425
1329 1426 // Bail if not a forum screen
1330 1427 if ( empty( $current_screen->post_type ) || ( bbp_get_topic_post_type() !== $current_screen->post_type ) ) {
1331 1428 return;