PluginProbe
bbPress / 2.6.6
bbPress v2.6.6
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 2.2.2 All 71 releases
← All changes | includes/admin/tools.php +454 -1023 2.22.6.6 View file →
@@ -7,1119 +7,550 @@
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 -/** Repair ********************************************************************/
14 -
15 13 /**
16 - * Admin repair page
14 + * Output a bbPress specific tools box
17 15 *
18 - * @since bbPress (r2613)
19 - *
20 - * @uses bbp_admin_repair_list() To get the recount list
21 - * @uses check_admin_referer() To verify the nonce and the referer
22 - * @uses wp_cache_flush() To flush the cache
23 - * @uses do_action() Calls 'admin_notices' to display the notices
24 - * @uses screen_icon() To display the screen icon
25 - * @uses wp_nonce_field() To add a hidden nonce field
16 + * @since 2.6.0 bbPress (r6273)
26 17 */
27 -function bbp_admin_repair() {
28 -?>
18 +function bbp_admin_tools_box() {
29 19
30 - <div class="wrap">
20 + // Bail if user cannot access tools page
21 + if ( ! current_user_can( 'bbp_tools_page' ) ) {
22 + return;
23 + }
31 24
32 - <?php screen_icon( 'tools' ); ?>
25 + // Get the tools pages
26 + $links = array();
27 + $tools = bbp_get_tools_admin_pages(); ?>
33 28
34 - <h2 class="nav-tab-wrapper"><?php bbp_tools_admin_tabs( __( 'Repair Forums', 'bbpress' ) ); ?></h2>
29 + <div class="card">
30 + <h3 class="title"><?php esc_html_e( 'Forums', 'bbpress' ) ?></h3>
31 + <p><?php esc_html_e( 'bbPress provides the following tools to help you manage your forums:', 'bbpress' ); ?></p>
35 32
36 - <p><?php _e( 'bbPress keeps track of relationships between forums, topics, replies, and topic tags, and users. Occasionally these relationships become out of sync, most often after an import or migration. Use the tools below to manually recalculate these relationships.', 'bbpress' ); ?></p>
37 - <p class="description"><?php _e( 'Some of these tools create substantial database overhead. Avoid running more than 1 repair job at a time.', 'bbpress' ); ?></p>
33 + <?php
38 34
39 - <form class="settings" method="post" action="">
40 - <table class="form-table">
41 - <tbody>
42 - <tr valign="top">
43 - <th scope="row"><?php _e( 'Relationships to Repair:', 'bbpress' ) ?></th>
44 - <td>
45 - <fieldset>
46 - <legend class="screen-reader-text"><span><?php _e( 'Repair', 'bbpress' ) ?></span></legend>
35 + // Loop through tools and create links
36 + foreach ( $tools as $tool ) {
47 37
48 - <?php foreach ( bbp_admin_repair_list() as $item ) : ?>
38 + // Skip if user cannot see this page
39 + if ( ! current_user_can( $tool['cap'] ) ) {
40 + continue;
41 + }
49 42
50 - <label><input type="checkbox" class="checkbox" name="<?php echo esc_attr( $item[0] ) . '" id="' . esc_attr( str_replace( '_', '-', $item[0] ) ); ?>" value="1" /> <?php echo esc_html( $item[1] ); ?></label><br />
43 + // Add link to array
44 + $links[] = sprintf( '<a href="%s">%s</a>', esc_url( add_query_arg( array( 'page' => $tool['page'] ), admin_url( 'tools.php' ) ) ), $tool['name'] );
45 + }
51 46
52 - <?php endforeach; ?>
47 + // Output links
48 + echo '<p class="bbp-tools-links">' . implode( ' &middot; ', $links ) . '</p>';
53 49
54 - </fieldset>
55 - </td>
56 - </tr>
57 - </tbody>
58 - </table>
50 + ?></div>
59 51
60 - <fieldset class="submit">
61 - <input class="button-primary" type="submit" name="submit" value="<?php esc_attr_e( 'Repair Items', 'bbpress' ); ?>" />
62 - <?php wp_nonce_field( 'bbpress-do-counts' ); ?>
63 - </fieldset>
64 - </form>
65 - </div>
66 -
67 52 <?php
68 53 }
69 54
70 55 /**
71 - * Handle the processing and feedback of the admin tools page
56 + * Register an admin area repair tool
72 57 *
73 - * @since bbPress (r2613)
58 + * @since 2.6.0 bbPress (r5885)
74 59 *
75 - * @uses bbp_admin_repair_list() To get the recount list
76 - * @uses check_admin_referer() To verify the nonce and the referer
77 - * @uses wp_cache_flush() To flush the cache
78 - * @uses do_action() Calls 'admin_notices' to display the notices
60 + * @param array $args
61 + * @return
79 62 */
80 -function bbp_admin_repair_handler() {
63 +function bbp_register_repair_tool( $args = array() ) {
81 64
82 - if ( 'post' == strtolower( $_SERVER['REQUEST_METHOD'] ) ) {
83 - check_admin_referer( 'bbpress-do-counts' );
65 + // Parse arguments
66 + $r = bbp_parse_args( $args, array(
67 + 'id' => '',
68 + 'type' => '',
69 + 'title' => '',
70 + 'description' => '',
71 + 'callback' => '',
72 + 'priority' => 0,
73 + 'overhead' => 'low',
74 + 'version' => '',
75 + 'components' => array(),
84 76
85 - // Stores messages
86 - $messages = array();
77 + // @todo
78 + 'success' => esc_html__( 'The repair was completed successfully', 'bbpress' ),
79 + 'failure' => esc_html__( 'The repair was not successful', 'bbpress' )
80 + ), 'register_repair_tool' );
87 81
88 - wp_cache_flush();
89 -
90 - foreach ( (array) bbp_admin_repair_list() as $item ) {
91 - if ( isset( $item[2] ) && isset( $_POST[$item[0]] ) && 1 == $_POST[$item[0]] && is_callable( $item[2] ) ) {
92 - $messages[] = call_user_func( $item[2] );
93 - }
94 - }
95 -
96 - if ( count( $messages ) ) {
97 - foreach ( $messages as $message ) {
98 - bbp_admin_tools_feedback( $message[1] );
99 - }
100 - }
82 + // Bail if missing required values
83 + if ( empty( $r['id'] ) || empty( $r['priority'] ) || empty( $r['title'] ) || empty( $r['callback'] ) ) {
84 + return;
101 85 }
102 -}
103 86
104 -/**
105 - * Assemble the admin notices
106 - *
107 - * @since bbPress (r2613)
108 - *
109 - * @param string|WP_Error $message A message to be displayed or {@link WP_Error}
110 - * @param string $class Optional. A class to be added to the message div
111 - * @uses WP_Error::get_error_messages() To get the error messages of $message
112 - * @uses add_action() Adds the admin notice action with the message HTML
113 - * @return string The message HTML
114 - */
115 -function bbp_admin_tools_feedback( $message, $class = false ) {
116 - if ( is_string( $message ) ) {
117 - $message = '<p>' . $message . '</p>';
118 - $class = $class ? $class : 'updated';
119 - } elseif ( is_wp_error( $message ) ) {
120 - $errors = $message->get_error_messages();
87 + // Add tool to the registered tools array
88 + bbp_admin()->tools[ $r['id'] ] = array(
89 + 'type' => $r['type'],
90 + 'title' => $r['title'],
91 + 'description' => $r['description'],
92 + 'priority' => $r['priority'],
93 + 'callback' => $r['callback'],
94 + 'overhead' => $r['overhead'],
95 + 'components' => $r['components'],
96 + 'version' => $r['version'],
121 97
122 - switch ( count( $errors ) ) {
123 - case 0:
124 - return false;
125 - break;
126 -
127 - case 1:
128 - $message = '<p>' . $errors[0] . '</p>';
129 - break;
130 -
131 - default:
132 - $message = '<ul>' . "\n\t" . '<li>' . join( '</li>' . "\n\t" . '<li>', $errors ) . '</li>' . "\n" . '</ul>';
133 - break;
134 - }
135 -
136 - $class = $class ? $class : 'error';
137 - } else {
138 - return false;
139 - }
140 -
141 - $message = '<div id="message" class="' . esc_attr( $class ) . '">' . $message . '</div>';
142 - $message = str_replace( "'", "\'", $message );
143 - $lambda = create_function( '', "echo '$message';" );
144 -
145 - add_action( 'admin_notices', $lambda );
146 -
147 - return $lambda;
148 -}
149 -
150 -/**
151 - * Get the array of the repair list
152 - *
153 - * @since bbPress (r2613)
154 - *
155 - * @uses apply_filters() Calls 'bbp_repair_list' with the list array
156 - * @return array Repair list of options
157 - */
158 -function bbp_admin_repair_list() {
159 - $repair_list = array(
160 - 0 => array( 'bbp-sync-topic-meta', __( 'Recalculate the parent topic for each post', 'bbpress' ), 'bbp_admin_repair_topic_meta' ),
161 - 5 => array( 'bbp-sync-forum-meta', __( 'Recalculate the parent forum for each post', 'bbpress' ), 'bbp_admin_repair_forum_meta' ),
162 - 10 => array( 'bbp-sync-forum-visibility', __( 'Recalculate private and hidden forums', 'bbpress' ), 'bbp_admin_repair_forum_visibility' ),
163 - 15 => array( 'bbp-sync-all-topics-forums', __( 'Recalculate last activity in each topic and forum', 'bbpress' ), 'bbp_admin_repair_freshness' ),
164 - 20 => array( 'bbp-group-forums', __( 'Repair BuddyPress Group Forum relationships', 'bbpress' ), 'bbp_admin_repair_group_forum_relationship' ),
165 - 25 => array( 'bbp-forum-topics', __( 'Count topics in each forum', 'bbpress' ), 'bbp_admin_repair_forum_topic_count' ),
166 - 30 => array( 'bbp-forum-replies', __( 'Count replies in each forum', 'bbpress' ), 'bbp_admin_repair_forum_reply_count' ),
167 - 35 => array( 'bbp-topic-replies', __( 'Count replies in each topic', 'bbpress' ), 'bbp_admin_repair_topic_reply_count' ),
168 - 40 => array( 'bbp-topic-voices', __( 'Count voices in each topic', 'bbpress' ), 'bbp_admin_repair_topic_voice_count' ),
169 - 45 => array( 'bbp-topic-hidden-replies', __( 'Count spammed & trashed replies in each topic', 'bbpress' ), 'bbp_admin_repair_topic_hidden_reply_count' ),
170 - 50 => array( 'bbp-user-replies', __( 'Count topics for each user', 'bbpress' ), 'bbp_admin_repair_user_topic_count' ),
171 - 55 => array( 'bbp-user-topics', __( 'Count replies for each user', 'bbpress' ), 'bbp_admin_repair_user_reply_count' ),
172 - 60 => array( 'bbp-user-favorites', __( 'Remove trashed topics from user favorites', 'bbpress' ), 'bbp_admin_repair_user_favorites' ),
173 - 65 => array( 'bbp-user-subscriptions', __( 'Remove trashed topics from user subscriptions', 'bbpress' ), 'bbp_admin_repair_user_subscriptions' ),
174 - 70 => array( 'bbp-user-role-map', __( 'Remap existing users to default forum roles', 'bbpress' ), 'bbp_admin_repair_user_roles' )
98 + // @todo
99 + 'success' => $r['success'],
100 + 'failure' => $r['failure'],
175 101 );
176 - ksort( $repair_list );
177 -
178 - return (array) apply_filters( 'bbp_repair_list', $repair_list );
179 102 }
180 103
181 104 /**
182 - * Recount topic replies
105 + * Register the default repair tools
183 106 *
184 - * @since bbPress (r2613)
185 - *
186 - * @uses bbp_get_reply_post_type() To get the reply post type
187 - * @uses wpdb::query() To run our recount sql queries
188 - * @uses is_wp_error() To check if the executed query returned {@link WP_Error}
189 - * @return array An array of the status code and the message
107 + * @since 2.6.0 bbPress (r5885)
190 108 */
191 -function bbp_admin_repair_topic_reply_count() {
192 - global $wpdb;
109 +function bbp_register_default_repair_tools() {
193 110
194 - $statement = __( 'Counting the number of replies in each topic&hellip; %s', 'bbpress' );
195 - $result = __( 'Failed!', 'bbpress' );
111 + // Topic meta
112 + bbp_register_repair_tool( array(
113 + 'id' => 'bbp-sync-topic-meta',
114 + 'type' => 'repair',
115 + 'title' => esc_html__( 'Recalculate parent topic for each reply', 'bbpress' ),
116 + 'description' => esc_html__( 'Run this if replies appear in the wrong topics.', 'bbpress' ),
117 + 'callback' => 'bbp_admin_repair_topic_meta',
118 + 'priority' => 5,
119 + 'overhead' => 'low',
120 + 'components' => array( bbp_get_reply_post_type() )
121 + ) );
196 122
197 - $sql_delete = "DELETE FROM `{$wpdb->postmeta}` WHERE `meta_key` = '_bbp_reply_count';";
198 - if ( is_wp_error( $wpdb->query( $sql_delete ) ) )
199 - return array( 1, sprintf( $statement, $result ) );
123 + // Forum meta
124 + bbp_register_repair_tool( array(
125 + 'id' => 'bbp-sync-forum-meta',
126 + 'type' => 'repair',
127 + 'title' => esc_html__( 'Recalculate parent forum for each topic and reply', 'bbpress' ),
128 + 'description' => esc_html__( 'Run this if topics or replies appear in the wrong forums.', 'bbpress' ),
129 + 'callback' => 'bbp_admin_repair_forum_meta',
130 + 'priority' => 10,
131 + 'overhead' => 'low',
132 + 'components' => array( bbp_get_topic_post_type(), bbp_get_reply_post_type() )
133 + ) );
200 134
201 - // Post types and status
202 - $tpt = bbp_get_topic_post_type();
203 - $rpt = bbp_get_reply_post_type();
204 - $pps = bbp_get_public_status_id();
205 - $cps = bbp_get_closed_status_id();
135 + // Forum visibility
136 + bbp_register_repair_tool( array(
137 + 'id' => 'bbp-sync-forum-visibility',
138 + 'type' => 'repair',
139 + 'title' => esc_html__( 'Recalculate private and hidden forums', 'bbpress' ),
140 + 'description' => esc_html__( 'Run this if non-public forums are publicly visible.', 'bbpress' ),
141 + 'callback' => 'bbp_admin_repair_forum_visibility',
142 + 'priority' => 15,
143 + 'overhead' => 'low',
144 + 'components' => array( bbp_get_forum_post_type() )
145 + ) );
206 146
207 - $sql = "INSERT INTO `{$wpdb->postmeta}` (`post_id`, `meta_key`, `meta_value`) (
208 - SELECT `topics`.`ID` AS `post_id`, '_bbp_reply_count' AS `meta_key`, COUNT(`replies`.`ID`) As `meta_value`
209 - FROM `{$wpdb->posts}` AS `topics`
210 - LEFT JOIN `{$wpdb->posts}` as `replies`
211 - ON `replies`.`post_parent` = `topics`.`ID`
212 - AND `replies`.`post_status` = '{$pps}'
213 - AND `replies`.`post_type` = '{$rpt}'
214 - WHERE `topics`.`post_type` = '{$tpt}'
215 - AND `topics`.`post_status` IN ( '{$pps}', '{$cps}' )
216 - GROUP BY `topics`.`ID`);";
147 + // Sync all topics in all forums
148 + bbp_register_repair_tool( array(
149 + 'id' => 'bbp-sync-all-topics-forums',
150 + 'type' => 'repair',
151 + 'title' => esc_html__( 'Recalculate last activity in each topic and forum', 'bbpress' ),
152 + 'description' => esc_html__( 'Run this if freshness appears incorrectly.', 'bbpress' ),
153 + 'callback' => 'bbp_admin_repair_freshness',
154 + 'priority' => 20,
155 + 'overhead' => 'high',
156 + 'components' => array( bbp_get_forum_post_type(), bbp_get_topic_post_type(), bbp_get_reply_post_type() )
157 + ) );
217 158
218 - if ( is_wp_error( $wpdb->query( $sql ) ) )
219 - return array( 2, sprintf( $statement, $result ) );
159 + // Sync all sticky topics in all forums
160 + bbp_register_repair_tool( array(
161 + 'id' => 'bbp-sync-all-topics-sticky',
162 + 'type' => 'repair',
163 + 'title' => esc_html__( 'Recalculate sticky relationship of each topic', 'bbpress' ),
164 + 'description' => esc_html__( 'Run this if sticky topics appear incorrectly.', 'bbpress' ),
165 + 'callback' => 'bbp_admin_repair_sticky',
166 + 'priority' => 25,
167 + 'overhead' => 'low',
168 + 'components' => array( bbp_get_topic_post_type() )
169 + ) );
220 170
221 - return array( 0, sprintf( $statement, __( 'Complete!', 'bbpress' ) ) );
222 -}
171 + // Sync all hierarchical reply positions
172 + bbp_register_repair_tool( array(
173 + 'id' => 'bbp-sync-all-reply-positions',
174 + 'type' => 'repair',
175 + 'title' => esc_html__( 'Recalculate position of each reply in each topic', 'bbpress' ),
176 + 'description' => esc_html__( 'Run this if replies appear in the wrong order.', 'bbpress' ),
177 + 'callback' => 'bbp_admin_repair_reply_menu_order',
178 + 'priority' => 30,
179 + 'overhead' => 'high',
180 + 'components' => array( bbp_get_reply_post_type() )
181 + ) );
223 182
224 -/**
225 - * Recount topic voices
226 - *
227 - * @since bbPress (r2613)
228 - *
229 - * @uses bbp_get_reply_post_type() To get the reply post type
230 - * @uses wpdb::query() To run our recount sql queries
231 - * @uses is_wp_error() To check if the executed query returned {@link WP_Error}
232 - * @return array An array of the status code and the message
233 - */
234 -function bbp_admin_repair_topic_voice_count() {
235 - global $wpdb;
183 + // Sync all topic engagements for all users
184 + bbp_register_repair_tool( array(
185 + 'id' => 'bbp-topic-engagements',
186 + 'type' => 'repair',
187 + 'title' => esc_html__( 'Recalculate engagements in each topic for each user', 'bbpress' ),
188 + 'description' => esc_html__( 'Run this if voices appear incorrectly.', 'bbpress' ),
189 + 'callback' => 'bbp_admin_repair_topic_voice_count',
190 + 'priority' => 35,
191 + 'overhead' => 'high',
192 + 'components' => array( bbp_get_topic_post_type(), bbp_get_user_rewrite_id() )
193 + ) );
236 194
237 - $statement = __( 'Counting the number of voices in each topic&hellip; %s', 'bbpress' );
238 - $result = __( 'Failed!', 'bbpress' );
195 + // Update closed topic counts
196 + bbp_register_repair_tool( array(
197 + 'id' => 'bbp-sync-closed-topics',
198 + 'type' => 'repair',
199 + 'title' => esc_html__( 'Repair closed topic statuses', 'bbpress' ),
200 + 'description' => esc_html__( 'Run this if closed topics appear incorrectly.', 'bbpress' ),
201 + 'callback' => 'bbp_admin_repair_closed_topics',
202 + 'priority' => 40,
203 + 'overhead' => 'medium',
204 + 'components' => array( bbp_get_topic_post_type() )
205 + ) );
239 206
240 - $sql_delete = "DELETE FROM `{$wpdb->postmeta}` WHERE `meta_key` = '_bbp_voice_count';";
241 - if ( is_wp_error( $wpdb->query( $sql_delete ) ) )
242 - return array( 1, sprintf( $statement, $result ) );
207 + // Count topics
208 + bbp_register_repair_tool( array(
209 + 'id' => 'bbp-forum-topics',
210 + 'type' => 'repair',
211 + 'title' => esc_html__( 'Recount topics in each forum', 'bbpress' ),
212 + 'description' => esc_html__( 'Run this if the number of topics in any forums are incorrect.', 'bbpress' ),
213 + 'callback' => 'bbp_admin_repair_forum_topic_count',
214 + 'priority' => 45,
215 + 'overhead' => 'medium',
216 + 'components' => array( bbp_get_forum_post_type(), bbp_get_topic_post_type() )
217 + ) );
243 218
244 - // Post types and status
245 - $tpt = bbp_get_topic_post_type();
246 - $rpt = bbp_get_reply_post_type();
247 - $pps = bbp_get_public_status_id();
248 - $cps = bbp_get_closed_status_id();
219 + // Count topic tags
220 + bbp_register_repair_tool( array(
221 + 'id' => 'bbp-topic-tags',
222 + 'type' => 'repair',
223 + 'title' => esc_html__( 'Recount topics in each topic-tag', 'bbpress' ),
224 + 'description' => esc_html__( 'Run this if the number of topics in any topic-tags are incorrect.', 'bbpress' ),
225 + 'callback' => 'bbp_admin_repair_topic_tag_count',
226 + 'priority' => 50,
227 + 'overhead' => 'medium',
228 + 'components' => array( bbp_get_topic_post_type(), bbp_get_topic_tag_tax_id() )
229 + ) );
249 230
250 - $sql = "INSERT INTO `{$wpdb->postmeta}` (`post_id`, `meta_key`, `meta_value`) (
251 - SELECT `postmeta`.`meta_value`, '_bbp_voice_count', COUNT(DISTINCT `post_author`) as `meta_value`
252 - FROM `{$wpdb->posts}` AS `posts`
253 - LEFT JOIN `{$wpdb->postmeta}` AS `postmeta`
254 - ON `posts`.`ID` = `postmeta`.`post_id`
255 - AND `postmeta`.`meta_key` = '_bbp_topic_id'
256 - WHERE `posts`.`post_type` IN ( '{$tpt}', '{$rpt}' )
257 - AND `posts`.`post_status` IN ( '{$pps}', '{$cps}' )
258 - AND `posts`.`post_author` != '0'
259 - GROUP BY `postmeta`.`meta_value`);";
231 + // Count forum replies
232 + bbp_register_repair_tool( array(
233 + 'id' => 'bbp-forum-replies',
234 + 'type' => 'repair',
235 + 'title' => esc_html__( 'Recount replies in each forum', 'bbpress' ),
236 + 'description' => esc_html__( 'Run this if the number of replies in any forums are incorrect.', 'bbpress' ),
237 + 'callback' => 'bbp_admin_repair_forum_reply_count',
238 + 'priority' => 55,
239 + 'overhead' => 'high',
240 + 'components' => array( bbp_get_forum_post_type(), bbp_get_reply_post_type() )
241 + ) );
260 242
261 - if ( is_wp_error( $wpdb->query( $sql ) ) )
262 - return array( 2, sprintf( $statement, $result ) );
243 + // Count non-published replies to each forum
244 + bbp_register_repair_tool( array(
245 + 'id' => 'bbp-forum-hidden-replies',
246 + 'type' => 'repair',
247 + 'title' => esc_html__( 'Recount pending, spammed, and trashed replies in each forum', 'bbpress' ),
248 + 'description' => esc_html__( 'Run this if non-public replies display incorrectly in forums.', 'bbpress' ),
249 + 'callback' => 'bbp_admin_repair_forum_hidden_reply_count',
250 + 'priority' => 60,
251 + 'overhead' => 'high',
252 + 'components' => array( bbp_get_forum_post_type(), bbp_get_reply_post_type() )
253 + ) );
263 254
264 - return array( 0, sprintf( $statement, __( 'Complete!', 'bbpress' ) ) );
265 -}
255 + // Count topic replies
256 + bbp_register_repair_tool( array(
257 + 'id' => 'bbp-topic-replies',
258 + 'type' => 'repair',
259 + 'title' => esc_html__( 'Recount replies in each topic', 'bbpress' ),
260 + 'description' => esc_html__( 'Run this if the number of replies in any topics are incorrect.', 'bbpress' ),
261 + 'callback' => 'bbp_admin_repair_topic_reply_count',
262 + 'priority' => 65,
263 + 'overhead' => 'high',
264 + 'components' => array( bbp_get_topic_post_type(), bbp_get_reply_post_type() )
265 + ) );
266 266
267 -/**
268 - * Recount topic hidden replies (spammed/trashed)
269 - *
270 - * @since bbPress (r2747)
271 - *
272 - * @uses wpdb::query() To run our recount sql queries
273 - * @uses is_wp_error() To check if the executed query returned {@link WP_Error}
274 - * @return array An array of the status code and the message
275 - */
276 -function bbp_admin_repair_topic_hidden_reply_count() {
277 - global $wpdb;
267 + // Count non-published replies to each topic
268 + bbp_register_repair_tool( array(
269 + 'id' => 'bbp-topic-hidden-replies',
270 + 'type' => 'repair',
271 + 'title' => esc_html__( 'Recount pending, spammed, and trashed replies in each topic', 'bbpress' ),
272 + 'description' => esc_html__( 'Run this if non-public replies display incorrectly in topics.', 'bbpress' ),
273 + 'callback' => 'bbp_admin_repair_topic_hidden_reply_count',
274 + 'priority' => 70,
275 + 'overhead' => 'high',
276 + 'components' => array( bbp_get_topic_post_type(), bbp_get_reply_post_type() )
277 + ) );
278 278
279 - $statement = __( 'Counting the number of spammed and trashed replies in each topic&hellip; %s', 'bbpress' );
280 - $result = __( 'Failed!', 'bbpress' );
279 + // Recount topics for each user
280 + bbp_register_repair_tool( array(
281 + 'id' => 'bbp-user-topics',
282 + 'type' => 'repair',
283 + 'title' => esc_html__( 'Recount topics for each user', 'bbpress' ),
284 + 'description' => esc_html__( 'Run this to get fresh topic counts for all users.', 'bbpress' ),
285 + 'callback' => 'bbp_admin_repair_user_topic_count',
286 + 'priority' => 75,
287 + 'overhead' => 'medium',
288 + 'components' => array( bbp_get_topic_post_type(), bbp_get_user_rewrite_id() )
289 + ) );
281 290
282 - $sql_delete = "DELETE FROM `{$wpdb->postmeta}` WHERE `meta_key` = '_bbp_reply_count_hidden';";
283 - if ( is_wp_error( $wpdb->query( $sql_delete ) ) )
284 - return array( 1, sprintf( $statement, $result ) );
291 + // Recount topics for each user
292 + bbp_register_repair_tool( array(
293 + 'id' => 'bbp-user-replies',
294 + 'type' => 'repair',
295 + 'title' => esc_html__( 'Recount replies for each user', 'bbpress' ),
296 + 'description' => esc_html__( 'Run this to get fresh reply counts for all users.', 'bbpress' ),
297 + 'callback' => 'bbp_admin_repair_user_reply_count',
298 + 'priority' => 80,
299 + 'overhead' => 'medium',
300 + 'components' => array( bbp_get_reply_post_type(), bbp_get_user_rewrite_id() )
301 + ) );
285 302
286 - $sql = "INSERT INTO `{$wpdb->postmeta}` (`post_id`, `meta_key`, `meta_value`) (SELECT `post_parent`, '_bbp_reply_count_hidden', COUNT(`post_status`) as `meta_value` FROM `{$wpdb->posts}` WHERE `post_type` = '" . bbp_get_reply_post_type() . "' AND `post_status` IN ( '" . join( "','", array( bbp_get_trash_status_id(), bbp_get_spam_status_id() ) ) . "') GROUP BY `post_parent`);";
287 - if ( is_wp_error( $wpdb->query( $sql ) ) )
288 - return array( 2, sprintf( $statement, $result ) );
303 + // Remove unpublished topics from user favorites
304 + bbp_register_repair_tool( array(
305 + 'id' => 'bbp-user-favorites',
306 + 'type' => 'repair',
307 + 'title' => esc_html__( 'Remove unpublished topics from user favorites', 'bbpress' ),
308 + 'description' => esc_html__( 'Run this to remove trashed or deleted topics from all user favorites.', 'bbpress' ),
309 + 'callback' => 'bbp_admin_repair_user_favorites',
310 + 'priority' => 85,
311 + 'overhead' => 'medium',
312 + 'components' => array( bbp_get_topic_post_type(), bbp_get_user_rewrite_id() )
313 + ) );
289 314
290 - return array( 0, sprintf( $statement, __( 'Complete!', 'bbpress' ) ) );
291 -}
315 + // Remove unpublished topics from user subscriptions
316 + bbp_register_repair_tool( array(
317 + 'id' => 'bbp-user-topic-subscriptions',
318 + 'type' => 'repair',
319 + 'title' => esc_html__( 'Remove unpublished topics from user subscriptions', 'bbpress' ),
320 + 'description' => esc_html__( 'Run this to remove trashed or deleted topics from all user subscriptions.', 'bbpress' ),
321 + 'callback' => 'bbp_admin_repair_user_topic_subscriptions',
322 + 'priority' => 90,
323 + 'overhead' => 'medium',
324 + 'components' => array( bbp_get_topic_post_type(), bbp_get_user_rewrite_id() )
325 + ) );
292 326
293 -/**
294 - * Repair group forum ID mappings after a bbPress 1.1 to bbPress 2.2 conversion
295 - *
296 - * @since bbPress (r4395)
297 - *
298 - * @global WPDB $wpdb
299 - * @return If a wp_error() occurs and no converted forums are found
300 - */
301 -function bbp_admin_repair_group_forum_relationship() {
302 - global $wpdb;
327 + // Remove unpublished forums from user subscriptions
328 + bbp_register_repair_tool( array(
329 + 'id' => 'bbp-user-forum-subscriptions',
330 + 'type' => 'repair',
331 + 'title' => esc_html__( 'Remove unpublished forums from user subscriptions', 'bbpress' ),
332 + 'description' => esc_html__( 'Run this to remove trashed or deleted forums from all user subscriptions.', 'bbpress' ),
333 + 'callback' => 'bbp_admin_repair_user_forum_subscriptions',
334 + 'priority' => 95,
335 + 'overhead' => 'medium',
336 + 'components' => array( bbp_get_forum_post_type(), bbp_get_user_rewrite_id() )
337 + ) );
303 338
304 - $statement = __( 'Repairing BuddyPress group-forum relationships&hellip; %s', 'bbpress' );
305 - $g_count = 0;
306 - $f_count = 0;
339 + // Remove unpublished forums from user subscriptions
340 + bbp_register_repair_tool( array(
341 + 'id' => 'bbp-user-role-map',
342 + 'type' => 'repair',
343 + 'title' => esc_html__( 'Remap all users to default forum roles', 'bbpress' ),
344 + 'description' => esc_html__( 'Run this if users have issues accessing the forums.', 'bbpress' ),
345 + 'callback' => 'bbp_admin_repair_user_roles',
346 + 'priority' => 100,
347 + 'overhead' => 'low',
348 + 'components' => array( bbp_get_user_rewrite_id() )
349 + ) );
307 350
308 - // Copy the BuddyPress filter here, incase BuddyPress is not active
309 - $prefix = apply_filters( 'bp_core_get_table_prefix', $wpdb->base_prefix );
310 - $tablename = $prefix . 'bp_groups_groupmeta';
351 + // Migrate topic engagements to post-meta
352 + bbp_register_repair_tool( array(
353 + 'id' => 'bbp-user-topic-engagements-move',
354 + 'type' => 'upgrade',
355 + 'title' => esc_html__( 'Upgrade user topic engagements', 'bbpress' ),
356 + 'description' => esc_html__( 'Copies engagements from user meta to topic meta.', 'bbpress' ),
357 + 'callback' => 'bbp_admin_upgrade_user_engagements',
358 + 'priority' => 105,
359 + 'version' => '2.6.0',
360 + 'overhead' => 'high',
361 + 'components' => array( bbp_get_user_rewrite_id(), bbp_get_user_engagements_rewrite_id() )
362 + ) );
311 363
312 - // Get the converted forum IDs
313 - $forum_ids = $wpdb->query( "SELECT `forum`.`ID`, `forummeta`.`meta_value`
314 - FROM `{$wpdb->posts}` AS `forum`
315 - LEFT JOIN `{$wpdb->postmeta}` AS `forummeta`
316 - ON `forum`.`ID` = `forummeta`.`post_id`
317 - AND `forummeta`.`meta_key` = '_bbp_old_forum_id'
318 - WHERE `forum`.`post_type` = 'forum'
319 - GROUP BY `forum`.`ID`;" );
364 + // Migrate favorites from user-meta to post-meta
365 + bbp_register_repair_tool( array(
366 + 'id' => 'bbp-user-favorites-move',
367 + 'type' => 'upgrade',
368 + 'title' => esc_html__( 'Upgrade user topic favorites', 'bbpress' ),
369 + 'description' => esc_html__( 'Copies favorites from user meta to topic meta.', 'bbpress' ),
370 + 'callback' => 'bbp_admin_upgrade_user_favorites',
371 + 'priority' => 110,
372 + 'version' => '2.6.0',
373 + 'overhead' => 'high',
374 + 'components' => array( bbp_get_user_rewrite_id(), bbp_get_user_favorites_rewrite_id() )
375 + ) );
320 376
321 - // Bail if forum IDs returned an error
322 - if ( is_wp_error( $forum_ids ) || empty( $wpdb->last_result ) )
323 - return array( 2, sprintf( $statement, __( 'Failed!', 'bbpress' ) ) );
377 + // Migrate topic subscriptions from user-meta to post-meta
378 + bbp_register_repair_tool( array(
379 + 'id' => 'bbp-user-topic-subscriptions-move',
380 + 'type' => 'upgrade',
381 + 'title' => esc_html__( 'Upgrade user topic subscriptions', 'bbpress' ),
382 + 'description' => esc_html__( 'Copies topic subscriptions from user meta to topic meta.', 'bbpress' ),
383 + 'callback' => 'bbp_admin_upgrade_user_topic_subscriptions',
384 + 'priority' => 115,
385 + 'version' => '2.6.0',
386 + 'overhead' => 'high',
387 + 'components' => array( bbp_get_user_rewrite_id(), bbp_get_user_subscriptions_rewrite_id() )
388 + ) );
324 389
325 - // Stash the last results
326 - $results = $wpdb->last_result;
390 + // Migrate forum subscriptions from user-meta to post-meta
391 + bbp_register_repair_tool( array(
392 + 'id' => 'bbp-user-forum-subscriptions-move',
393 + 'type' => 'upgrade',
394 + 'title' => esc_html__( 'Upgrade user forum subscriptions', 'bbpress' ),
395 + 'description' => esc_html__( 'Copies forum subscriptions from user meta to forum meta.', 'bbpress' ),
396 + 'callback' => 'bbp_admin_upgrade_user_forum_subscriptions',
397 + 'priority' => 120,
398 + 'version' => '2.6.0',
399 + 'overhead' => 'high',
400 + 'components' => array( bbp_get_user_rewrite_id(), bbp_get_user_subscriptions_rewrite_id() )
401 + ) );
327 402
328 - // Update each group forum
329 - foreach ( $results as $group_forums ) {
403 + // Remove favorites from user-meta
404 + bbp_register_repair_tool( array(
405 + 'id' => 'bbp-user-favorites-delete',
406 + 'type' => 'upgrade',
407 + 'title' => esc_html__( 'Remove favorites from user-meta', 'bbpress' ),
408 + 'description' => esc_html__( 'Run this to delete old data (after confirming successful favorites upgrade)', 'bbpress' ),
409 + 'callback' => 'bbp_admin_upgrade_remove_favorites_from_usermeta',
410 + 'priority' => 125,
411 + 'version' => '2.6.1',
412 + 'overhead' => 'medium',
413 + 'components' => array( bbp_get_user_rewrite_id(), bbp_get_user_favorites_rewrite_id() )
414 + ) );
330 415
331 - // Only update if is a converted forum
332 - if ( ! isset( $group_forums->meta_value ) )
333 - continue;
416 + // Remove topic subscriptions from user-meta
417 + bbp_register_repair_tool( array(
418 + 'id' => 'bbp-user-topic-subscriptions-delete',
419 + 'type' => 'upgrade',
420 + 'title' => esc_html__( 'Remove topic subscriptions from user-meta', 'bbpress' ),
421 + 'description' => esc_html__( 'Run this to delete old data (after confirming successful topic subscriptions upgrade)', 'bbpress' ),
422 + 'callback' => 'bbp_admin_upgrade_remove_topic_subscriptions_from_usermeta',
423 + 'priority' => 130,
424 + 'version' => '2.6.1',
425 + 'overhead' => 'medium',
426 + 'components' => array( bbp_get_user_rewrite_id(), bbp_get_user_subscriptions_rewrite_id() )
427 + ) );
334 428
335 - // Attempt to update group meta
336 - $updated = $wpdb->query( "UPDATE `{$tablename}` SET `meta_value` = '{$group_forums->ID}' WHERE `meta_key` = 'forum_id' AND `meta_value` = '{$group_forums->meta_value}';" );
429 + // Remove forum subscriptions from user-meta
430 + bbp_register_repair_tool( array(
431 + 'id' => 'bbp-user-forum-subscriptions-delete',
432 + 'type' => 'upgrade',
433 + 'title' => esc_html__( 'Remove forum subscriptions from user-meta', 'bbpress' ),
434 + 'description' => esc_html__( 'Run this to delete old data (after confirming successful forum subscriptions upgrade)', 'bbpress' ),
435 + 'callback' => 'bbp_admin_upgrade_remove_forum_subscriptions_from_usermeta',
436 + 'priority' => 135,
437 + 'version' => '2.6.1',
438 + 'overhead' => 'medium',
439 + 'components' => array( bbp_get_user_rewrite_id(), bbp_get_user_subscriptions_rewrite_id() )
440 + ) );
337 441
338 - // Bump the count
339 - if ( !empty( $updated ) && ! is_wp_error( $updated ) ) {
340 - ++$g_count;
341 - }
342 -
343 - // Update group's forum metadata
344 - $group_id = (int) $wpdb->get_var( "SELECT `group_id` FROM `{$tablename}` WHERE `meta_key` = 'forum_id' AND `meta_value` = '{$group_forums->ID}';" );
345 - if ( !empty( $group_id ) ) {
346 - update_post_meta( $group_forums->ID, '_bbp_group_ids', array( $group_id ) );
347 - ++$f_count;
348 - }
349 - }
350 -
351 - // Make some logical guesses at the old group root forum
352 - if ( function_exists( 'bp_forums_parent_forum_id' ) ) {
353 - $old_default_forum_id = bp_forums_parent_forum_id();
354 - } elseif ( defined( 'BP_FORUMS_PARENT_FORUM_ID' ) ) {
355 - $old_default_forum_id = (int) BP_FORUMS_PARENT_FORUM_ID;
356 - } else {
357 - $old_default_forum_id = 1;
358 - }
359 -
360 - // Try to get the group root forum
361 - $posts = get_posts( array(
362 - 'post_type' => bbp_get_forum_post_type(),
363 - 'meta_key' => '_bbp_old_forum_id',
364 - 'meta_value' => $old_default_forum_id,
365 - 'numberposts' => 1
442 + // Sync all BuddyPress group forum relationships
443 + bbp_register_repair_tool( array(
444 + 'id' => 'bbp-group-forums',
445 + 'type' => 'upgrade',
446 + 'title' => esc_html__( 'Upgrade BuddyPress Group Forum relationships', 'bbpress' ),
447 + 'description' => esc_html__( 'Run this if you just upgraded BuddyPress Forums from Legacy.', 'bbpress' ),
448 + 'callback' => 'bbp_admin_upgrade_group_forum_relationship',
449 + 'priority' => 140,
450 + 'version' => esc_html__( 'Any', 'bbpress' ),
451 + 'overhead' => 'low',
452 + 'components' => array( bbp_get_forum_post_type() )
366 453 ) );
367 -
368 - // Found the group root forum
369 - if ( ! empty( $posts ) ) {
370 -
371 - // Rename 'Default Forum' since it's now visible in sitewide forums
372 - if ( 'Default Forum' == $posts[0]->post_title ) {
373 - wp_update_post( array(
374 - 'ID' => $posts[0]->ID,
375 - 'post_title' => __( 'Group Forums', 'bbpress' ),
376 - ) );
377 - }
378 -
379 - // Update the group forums root metadata
380 - update_option( '_bbp_group_forums_root_id', $posts[0]->ID );
381 - }
382 -
383 - // Complete results
384 - $result = sprintf( __( 'Complete! %s groups updated; %s forums updated.', 'bbpress' ), bbp_number_format( $g_count ), bbp_number_format( $f_count ) );
385 - return array( 0, sprintf( $statement, $result ) );
386 454 }
387 455
388 456 /**
389 - * Recount forum topics
457 + * Output the tabs in the admin area
390 458 *
391 - * @since bbPress (r2613)
459 + * @since 2.1.0 bbPress (r3872)
392 460 *
393 - * @uses wpdb::query() To run our recount sql queries
394 - * @uses is_wp_error() To check if the executed query returned {@link WP_Error}
395 - * @uses bbp_get_forum_post_type() To get the forum post type
396 - * @uses get_posts() To get the forums
397 - * @uses bbp_update_forum_topic_count() To update the forum topic count
398 - * @return array An array of the status code and the message
461 + * @param string $active_tab Name of the tab that is active
399 462 */
400 -function bbp_admin_repair_forum_topic_count() {
401 - global $wpdb;
402 -
403 - $statement = __( 'Counting the number of topics in each forum&hellip; %s', 'bbpress' );
404 - $result = __( 'Failed!', 'bbpress' );
405 -
406 - $sql_delete = "DELETE FROM {$wpdb->postmeta} WHERE meta_key IN ( '_bbp_topic_count', '_bbp_total_topic_count' );";
407 - if ( is_wp_error( $wpdb->query( $sql_delete ) ) )
408 - return array( 1, sprintf( $statement, $result ) );
409 -
410 - $forums = get_posts( array( 'post_type' => bbp_get_forum_post_type(), 'numberposts' => -1 ) );
411 - if ( !empty( $forums ) ) {
412 - foreach( $forums as $forum ) {
413 - bbp_update_forum_topic_count( $forum->ID );
414 - }
415 - } else {
416 - return array( 2, sprintf( $statement, $result ) );
417 - }
418 -
419 - return array( 0, sprintf( $statement, __( 'Complete!', 'bbpress' ) ) );
463 +function bbp_tools_admin_tabs( $active_tab = '' ) {
464 + echo bbp_get_tools_admin_tabs( $active_tab );
420 465 }
421 466
422 -/**
423 - * Recount forum replies
424 - *
425 - * @since bbPress (r2613)
426 - *
427 - * @uses wpdb::query() To run our recount sql queries
428 - * @uses is_wp_error() To check if the executed query returned {@link WP_Error}
429 - * @uses bbp_get_forum_post_type() To get the forum post type
430 - * @uses get_posts() To get the forums
431 - * @uses bbp_update_forum_reply_count() To update the forum reply count
432 - * @return array An array of the status code and the message
433 - */
434 -function bbp_admin_repair_forum_reply_count() {
435 - global $wpdb;
467 + /**
468 + * Output the tabs in the admin area
469 + *
470 + * @since 2.1.0 bbPress (r3872)
471 + *
472 + * @param string $active_tab Name of the tab that is active
473 + */
474 + function bbp_get_tools_admin_tabs( $active_tab = '' ) {
436 475
437 - $statement = __( 'Counting the number of replies in each forum&hellip; %s', 'bbpress' );
438 - $result = __( 'Failed!', 'bbpress' );
476 + // Declare local variables
477 + $tabs_html = '';
478 + $idle_class = 'nav-tab';
479 + $active_class = 'nav-tab nav-tab-active';
439 480
440 - $sql_delete = "DELETE FROM `{$wpdb->postmeta}` WHERE `meta_key` IN ( '_bbp_reply_count', '_bbp_total_reply_count' );";
441 - if ( is_wp_error( $wpdb->query( $sql_delete ) ) )
442 - return array( 1, sprintf( $statement, $result ) );
481 + // Setup core admin tabs
482 + $tabs = bbp_get_tools_admin_pages();
443 483
444 - $forums = get_posts( array( 'post_type' => bbp_get_forum_post_type(), 'numberposts' => -1 ) );
445 - if ( !empty( $forums ) ) {
446 - foreach( $forums as $forum ) {
447 - bbp_update_forum_reply_count( $forum->ID );
448 - }
449 - } else {
450 - return array( 2, sprintf( $statement, $result ) );
451 - }
484 + // Loop through tabs and build navigation
485 + foreach ( $tabs as $tab ) {
452 486
453 - return array( 0, sprintf( $statement, __( 'Complete!', 'bbpress' ) ) );
454 -}
487 + // Skip if user cannot visit page
488 + if ( ! current_user_can( $tab['cap'] ) ) {
489 + continue;
490 + }
455 491
456 -/**
457 - * Recount topics by the users
458 - *
459 - * @since bbPress (r3889)
460 - *
461 - * @uses bbp_get_reply_post_type() To get the reply post type
462 - * @uses wpdb::query() To run our recount sql queries
463 - * @uses is_wp_error() To check if the executed query returned {@link WP_Error}
464 - * @return array An array of the status code and the message
465 - */
466 -function bbp_admin_repair_user_topic_count() {
467 - global $wpdb;
492 + // Setup tab HTML
493 + $is_current = (bool) ( $tab['page'] === $active_tab );
494 + $tab_class = $is_current ? $active_class : $idle_class;
495 + $tab_url = add_query_arg( array( 'page' => $tab['page'] ), admin_url( 'tools.php' ) );
468 496
469 - $statement = __( 'Counting the number of topics each user has created&hellip; %s', 'bbpress' );
470 - $result = __( 'Failed!', 'bbpress' );
471 - $sql_select = "SELECT `post_author`, COUNT(DISTINCT `ID`) as `_count` FROM `{$wpdb->posts}` WHERE `post_type` = '" . bbp_get_topic_post_type() . "' AND `post_status` = '" . bbp_get_public_status_id() . "' GROUP BY `post_author`;";
472 - $insert_rows = $wpdb->get_results( $sql_select );
473 -
474 - if ( is_wp_error( $insert_rows ) )
475 - return array( 1, sprintf( $statement, $result ) );
476 -
477 - $key = $wpdb->prefix . '_bbp_topic_count';
478 - $insert_values = array();
479 - foreach ( $insert_rows as $insert_row )
480 - $insert_values[] = "('{$insert_row->post_author}', '{$key}', '{$insert_row->_count}')";
481 -
482 - if ( !count( $insert_values ) )
483 - return array( 2, sprintf( $statement, $result ) );
484 -
485 - $sql_delete = "DELETE FROM `{$wpdb->usermeta}` WHERE `meta_key` = '{$key}';";
486 - if ( is_wp_error( $wpdb->query( $sql_delete ) ) )
487 - return array( 3, sprintf( $statement, $result ) );
488 -
489 - foreach ( array_chunk( $insert_values, 10000 ) as $chunk ) {
490 - $chunk = "\n" . join( ",\n", $chunk );
491 - $sql_insert = "INSERT INTO `{$wpdb->usermeta}` (`user_id`, `meta_key`, `meta_value`) VALUES $chunk;";
492 -
493 - if ( is_wp_error( $wpdb->query( $sql_insert ) ) ) {
494 - return array( 4, sprintf( $statement, $result ) );
497 + // Tab name is not escaped - may contain HTML
498 + $tabs_html .= '<a href="' . esc_url( $tab_url ) . '" class="' . esc_attr( $tab_class ) . '">' . $tab['name'] . '</a>';
495 499 }
496 - }
497 500
498 - return array( 0, sprintf( $statement, __( 'Complete!', 'bbpress' ) ) );
499 -}
500 -
501 -/**
502 - * Recount topic replied by the users
503 - *
504 - * @since bbPress (r2613)
505 - *
506 - * @uses bbp_get_reply_post_type() To get the reply post type
507 - * @uses wpdb::query() To run our recount sql queries
508 - * @uses is_wp_error() To check if the executed query returned {@link WP_Error}
509 - * @return array An array of the status code and the message
510 - */
511 -function bbp_admin_repair_user_reply_count() {
512 - global $wpdb;
513 -
514 - $statement = __( 'Counting the number of topics to which each user has replied&hellip; %s', 'bbpress' );
515 - $result = __( 'Failed!', 'bbpress' );
516 - $sql_select = "SELECT `post_author`, COUNT(DISTINCT `ID`) as `_count` FROM `{$wpdb->posts}` WHERE `post_type` = '" . bbp_get_reply_post_type() . "' AND `post_status` = '" . bbp_get_public_status_id() . "' GROUP BY `post_author`;";
517 - $insert_rows = $wpdb->get_results( $sql_select );
518 -
519 - if ( is_wp_error( $insert_rows ) )
520 - return array( 1, sprintf( $statement, $result ) );
521 -
522 - $key = $wpdb->prefix . '_bbp_reply_count';
523 - $insert_values = array();
524 - foreach ( $insert_rows as $insert_row )
525 - $insert_values[] = "('{$insert_row->post_author}', '{$key}', '{$insert_row->_count}')";
526 -
527 - if ( !count( $insert_values ) )
528 - return array( 2, sprintf( $statement, $result ) );
529 -
530 - $sql_delete = "DELETE FROM `{$wpdb->usermeta}` WHERE `meta_key` = '{$key}';";
531 - if ( is_wp_error( $wpdb->query( $sql_delete ) ) )
532 - return array( 3, sprintf( $statement, $result ) );
533 -
534 - foreach ( array_chunk( $insert_values, 10000 ) as $chunk ) {
535 - $chunk = "\n" . join( ",\n", $chunk );
536 - $sql_insert = "INSERT INTO `{$wpdb->usermeta}` (`user_id`, `meta_key`, `meta_value`) VALUES $chunk;";
537 -
538 - if ( is_wp_error( $wpdb->query( $sql_insert ) ) ) {
539 - return array( 4, sprintf( $statement, $result ) );
540 - }
501 + // Output the tabs
502 + return $tabs_html;
541 503 }
542 504
543 - return array( 0, sprintf( $statement, __( 'Complete!', 'bbpress' ) ) );
544 -}
545 -
546 505 /**
547 - * Clean the users' favorites
506 + * Return possible tools pages
548 507 *
549 - * @since bbPress (r2613)
508 + * @since 2.6.0 bbPress (r6273)
550 509 *
551 - * @uses bbp_get_topic_post_type() To get the topic post type
552 - * @uses wpdb::query() To run our recount sql queries
553 - * @uses is_wp_error() To check if the executed query returned {@link WP_Error}
554 - * @return array An array of the status code and the message
510 + * @return array
555 511 */
556 -function bbp_admin_repair_user_favorites() {
557 - global $wpdb;
512 +function bbp_get_tools_admin_pages() {
558 513
559 - $statement = __( 'Removing trashed topics from user favorites&hellip; %s', 'bbpress' );
560 - $result = __( 'Failed!', 'bbpress' );
561 - $key = $wpdb->prefix . '_bbp_favorites';
562 - $users = $wpdb->get_results( "SELECT `user_id`, `meta_value` AS `favorites` FROM `{$wpdb->usermeta}` WHERE `meta_key` = '{$key}';" );
514 + // Get tools URL one time & use in each tab
515 + $tools_url = admin_url( 'tools.php' );
563 516
564 - if ( is_wp_error( $users ) )
565 - return array( 1, sprintf( $statement, $result ) );
517 + // Filter & return
518 + return (array) apply_filters( 'bbp_tools_admin_tabs', array(
519 + array(
520 + 'page' => 'bbp-repair',
521 + 'func' => 'bbp_admin_repair_page',
522 + 'cap' => 'bbp_tools_repair_page',
523 + 'name' => bbp_maybe_append_pending_upgrade_count( esc_html__( 'Repair Forums', 'bbpress' ), 'repair' ),
566 524
567 - $topics = $wpdb->get_col( "SELECT `ID` FROM `{$wpdb->posts}` WHERE `post_type` = '" . bbp_get_topic_post_type() . "' AND `post_status` = '" . bbp_get_public_status_id() . "';" );
525 + // Deprecated 2.6.0
526 + 'href' => add_query_arg( array( 'page' => 'bbp-repair' ), $tools_url )
527 + ),
528 + array(
529 + 'page' => 'bbp-upgrade',
530 + 'func' => 'bbp_admin_upgrade_page',
531 + 'cap' => 'bbp_tools_upgrade_page',
532 + 'name' => bbp_maybe_append_pending_upgrade_count( esc_html__( 'Upgrade Forums', 'bbpress' ), 'upgrade' ),
568 533
569 - if ( is_wp_error( $topics ) )
570 - return array( 2, sprintf( $statement, $result ) );
534 + // Deprecated 2.6.0
535 + 'href' => add_query_arg( array( 'page' => 'bbp-upgrade' ), $tools_url )
536 + ),
537 + array(
538 + 'page' => 'bbp-converter',
539 + 'func' => 'bbp_converter_settings_page',
540 + 'cap' => 'bbp_tools_import_page',
541 + 'name' => esc_html__( 'Import Forums', 'bbpress' ),
571 542
572 - $values = array();
573 - foreach ( $users as $user ) {
574 - if ( empty( $user->favorites ) || !is_string( $user->favorites ) )
575 - continue;
543 + // Deprecated 2.6.0
544 + 'href' => add_query_arg( array( 'page' => 'bbp-converter' ), $tools_url )
545 + ),
546 + array(
547 + 'page' => 'bbp-reset',
548 + 'func' => 'bbp_admin_reset_page',
549 + 'cap' => 'bbp_tools_reset_page',
550 + 'name' => esc_html__( 'Reset Forums', 'bbpress' ),
576 551
577 - $favorites = array_intersect( $topics, (array) explode( ',', $user->favorites ) );
578 - if ( empty( $favorites ) || !is_array( $favorites ) )
579 - continue;
580 -
581 - $favorites_joined = join( ',', $favorites );
582 - $values[] = "('{$user->user_id}', '{$key}, '{$favorites_joined}')";
583 -
584 - // Cleanup
585 - unset( $favorites, $favorites_joined );
586 - }
587 -
588 - if ( !count( $values ) ) {
589 - $result = __( 'Nothing to remove!', 'bbpress' );
590 - return array( 0, sprintf( $statement, $result ) );
591 - }
592 -
593 - $sql_delete = "DELETE FROM `{$wpdb->usermeta}` WHERE `meta_key` = '{$key}';";
594 - if ( is_wp_error( $wpdb->query( $sql_delete ) ) )
595 - return array( 4, sprintf( $statement, $result ) );
596 -
597 - foreach ( array_chunk( $values, 10000 ) as $chunk ) {
598 - $chunk = "\n" . join( ",\n", $chunk );
599 - $sql_insert = "INSERT INTO `$wpdb->usermeta` (`user_id`, `meta_key`, `meta_value`) VALUES $chunk;";
600 - if ( is_wp_error( $wpdb->query( $sql_insert ) ) ) {
601 - return array( 5, sprintf( $statement, $result ) );
602 - }
603 - }
604 -
605 - return array( 0, sprintf( $statement, __( 'Complete!', 'bbpress' ) ) );
606 -}
607 -
608 -/**
609 - * Clean the users' subscriptions
610 - *
611 - * @since bbPress (r2668)
612 - *
613 - * @uses bbp_get_topic_post_type() To get the topic post type
614 - * @uses wpdb::query() To run our recount sql queries
615 - * @uses is_wp_error() To check if the executed query returned {@link WP_Error}
616 - * @return array An array of the status code and the message
617 - */
618 -function bbp_admin_repair_user_subscriptions() {
619 - global $wpdb;
620 -
621 - $statement = __( 'Removing trashed topics from user subscriptions&hellip; %s', 'bbpress' );
622 - $result = __( 'Failed!', 'bbpress' );
623 - $key = $wpdb->prefix . '_bbp_subscriptions';
624 - $users = $wpdb->get_results( "SELECT `user_id`, `meta_value` AS `subscriptions` FROM `{$wpdb->usermeta}` WHERE `meta_key` = '{$key}';" );
625 -
626 - if ( is_wp_error( $users ) )
627 - return array( 1, sprintf( $statement, $result ) );
628 -
629 - $topics = $wpdb->get_col( "SELECT `ID` FROM `{$wpdb->posts}` WHERE `post_type` = '" . bbp_get_topic_post_type() . "' AND `post_status` = '" . bbp_get_public_status_id() . "';" );
630 - if ( is_wp_error( $topics ) )
631 - return array( 2, sprintf( $statement, $result ) );
632 -
633 - $values = array();
634 - foreach ( $users as $user ) {
635 - if ( empty( $user->subscriptions ) || !is_string( $user->subscriptions ) )
636 - continue;
637 -
638 - $subscriptions = array_intersect( $topics, (array) explode( ',', $user->subscriptions ) );
639 - if ( empty( $subscriptions ) || !is_array( $subscriptions ) )
640 - continue;
641 -
642 - $subscriptions_joined = join( ',', $subscriptions );
643 - $values[] = "('{$user->user_id}', '{$key}', '{$subscriptions_joined}')";
644 -
645 - // Cleanup
646 - unset( $subscriptions, $subscriptions_joined );
647 - }
648 -
649 - if ( !count( $values ) ) {
650 - $result = __( 'Nothing to remove!', 'bbpress' );
651 - return array( 0, sprintf( $statement, $result ) );
652 - }
653 -
654 - $sql_delete = "DELETE FROM `{$wpdb->usermeta}` WHERE `meta_key` = '{$key}';";
655 - if ( is_wp_error( $wpdb->query( $sql_delete ) ) )
656 - return array( 4, sprintf( $statement, $result ) );
657 -
658 - foreach ( array_chunk( $values, 10000 ) as $chunk ) {
659 - $chunk = "\n" . join( ",\n", $chunk );
660 - $sql_insert = "INSERT INTO `{$wpdb->usermeta}` (`user_id`, `meta_key`, `meta_value`) VALUES $chunk;";
661 - if ( is_wp_error( $wpdb->query( $sql_insert ) ) ) {
662 - return array( 5, sprintf( $statement, $result ) );
663 - }
664 - }
665 -
666 - return array( 0, sprintf( $statement, __( 'Complete!', 'bbpress' ) ) );
667 -}
668 -
669 -/**
670 - * This repair tool will map each user of the current site to their respective
671 - * forums role. By default, Admins will be Key Masters, and every other role
672 - * will be the default role defined in Settings > Forums (Participant).
673 - *
674 - * @since bbPress (r4340)
675 - *
676 - * @uses bbp_get_user_role_map() To get the map of user roles
677 - * @uses get_editable_roles() To get the current WordPress roles
678 - * @uses get_users() To get the users of each role (limited to ID field)
679 - * @uses bbp_set_user_role() To set each user's forums role
680 - */
681 -function bbp_admin_repair_user_roles() {
682 -
683 - $statement = __( 'Remapping forum role for each user on this site&hellip; %s', 'bbpress' );
684 - $changed = 0;
685 - $role_map = bbp_get_user_role_map();
686 -
687 - // Bail if no role map exists
688 - if ( empty( $role_map ) )
689 - return array( 1, sprintf( $statement, __( 'Failed!', 'bbpress' ) ) );
690 -
691 - // Iterate through each role...
692 - foreach ( array_keys( get_editable_roles() ) as $role ) {
693 -
694 - // Reset the offset
695 - $offset = 0;
696 -
697 - // Get users of this site, limited to 1000
698 - while ( $users = get_users( array(
699 - 'role' => $role,
700 - 'fields' => 'ID',
701 - 'number' => 1000,
702 - 'offset' => $offset
703 - ) ) ) {
704 -
705 - // Iterate through each user of $role and try to set it
706 - foreach ( (array) $users as $user_id ) {
707 - if ( bbp_set_user_role( $user_id, $role_map[$role] ) ) {
708 - ++$changed; // Keep a count to display at the end
709 - }
710 - }
711 -
712 - // Bump the offset for the next query iteration
713 - $offset = $offset + 1000;
714 - }
715 - }
716 -
717 - $result = sprintf( __( 'Complete! %s users updated.', 'bbpress' ), bbp_number_format( $changed ) );
718 - return array( 0, sprintf( $statement, $result ) );
719 -}
720 -
721 -/**
722 - * Recaches the last post in every topic and forum
723 - *
724 - * @since bbPress (r3040)
725 - *
726 - * @uses wpdb::query() To run our recount sql queries
727 - * @uses is_wp_error() To check if the executed query returned {@link WP_Error}
728 - * @return array An array of the status code and the message
729 - */
730 -function bbp_admin_repair_freshness() {
731 - global $wpdb;
732 -
733 - $statement = __( 'Recomputing latest post in every topic and forum&hellip; %s', 'bbpress' );
734 - $result = __( 'Failed!', 'bbpress' );
735 -
736 - // First, delete everything.
737 - if ( is_wp_error( $wpdb->query( "DELETE FROM `$wpdb->postmeta` WHERE `meta_key` IN ( '_bbp_last_reply_id', '_bbp_last_topic_id', '_bbp_last_active_id', '_bbp_last_active_time' );" ) ) )
738 - return array( 1, sprintf( $statement, $result ) );
739 -
740 - // Next, give all the topics with replies the ID their last reply.
741 - if ( is_wp_error( $wpdb->query( "INSERT INTO `$wpdb->postmeta` (`post_id`, `meta_key`, `meta_value`)
742 - ( SELECT `topic`.`ID`, '_bbp_last_reply_id', MAX( `reply`.`ID` )
743 - FROM `$wpdb->posts` AS `topic` INNER JOIN `$wpdb->posts` AS `reply` ON `topic`.`ID` = `reply`.`post_parent`
744 - WHERE `reply`.`post_status` IN ( '" . bbp_get_public_status_id() . "' ) AND `topic`.`post_type` = 'topic' AND `reply`.`post_type` = 'reply'
745 - GROUP BY `topic`.`ID` );" ) ) )
746 - return array( 2, sprintf( $statement, $result ) );
747 -
748 - // For any remaining topics, give a reply ID of 0.
749 - if ( is_wp_error( $wpdb->query( "INSERT INTO `$wpdb->postmeta` (`post_id`, `meta_key`, `meta_value`)
750 - ( SELECT `ID`, '_bbp_last_reply_id', 0
751 - FROM `$wpdb->posts` AS `topic` LEFT JOIN `$wpdb->postmeta` AS `reply`
752 - ON `topic`.`ID` = `reply`.`post_id` AND `reply`.`meta_key` = '_bbp_last_reply_id'
753 - WHERE `reply`.`meta_id` IS NULL AND `topic`.`post_type` = 'topic' );" ) ) )
754 - return array( 3, sprintf( $statement, $result ) );
755 -
756 - // Now we give all the forums with topics the ID their last topic.
757 - if ( is_wp_error( $wpdb->query( "INSERT INTO `$wpdb->postmeta` (`post_id`, `meta_key`, `meta_value`)
758 - ( SELECT `forum`.`ID`, '_bbp_last_topic_id', `topic`.`ID`
759 - FROM `$wpdb->posts` AS `forum` INNER JOIN `$wpdb->posts` AS `topic` ON `forum`.`ID` = `topic`.`post_parent`
760 - WHERE `topic`.`post_status` IN ( '" . bbp_get_public_status_id() . "' ) AND `forum`.`post_type` = 'forum' AND `topic`.`post_type` = 'topic'
761 - GROUP BY `forum`.`ID` );" ) ) )
762 - return array( 4, sprintf( $statement, $result ) );
763 -
764 - // For any remaining forums, give a topic ID of 0.
765 - if ( is_wp_error( $wpdb->query( "INSERT INTO `$wpdb->postmeta` (`post_id`, `meta_key`, `meta_value`)
766 - ( SELECT `ID`, '_bbp_last_topic_id', 0
767 - FROM `$wpdb->posts` AS `forum` LEFT JOIN `$wpdb->postmeta` AS `topic`
768 - ON `forum`.`ID` = `topic`.`post_id` AND `topic`.`meta_key` = '_bbp_last_topic_id'
769 - WHERE `topic`.`meta_id` IS NULL AND `forum`.`post_type` = 'forum' );" ) ) )
770 - return array( 5, sprintf( $statement, $result ) );
771 -
772 - // After that, we give all the topics with replies the ID their last reply (again, this time for a different reason).
773 - if ( is_wp_error( $wpdb->query( "INSERT INTO `$wpdb->postmeta` (`post_id`, `meta_key`, `meta_value`)
774 - ( SELECT `topic`.`ID`, '_bbp_last_active_id', MAX( `reply`.`ID` )
775 - FROM `$wpdb->posts` AS `topic` INNER JOIN `$wpdb->posts` AS `reply` ON `topic`.`ID` = `reply`.`post_parent`
776 - WHERE `reply`.`post_status` IN ( '" . bbp_get_public_status_id() . "' ) AND `topic`.`post_type` = 'topic' AND `reply`.`post_type` = 'reply'
777 - GROUP BY `topic`.`ID` );" ) ) )
778 - return array( 6, sprintf( $statement, $result ) );
779 -
780 - // For any remaining topics, give a reply ID of themself.
781 - if ( is_wp_error( $wpdb->query( "INSERT INTO `$wpdb->postmeta` (`post_id`, `meta_key`, `meta_value`)
782 - ( SELECT `ID`, '_bbp_last_active_id', `ID`
783 - FROM `$wpdb->posts` AS `topic` LEFT JOIN `$wpdb->postmeta` AS `reply`
784 - ON `topic`.`ID` = `reply`.`post_id` AND `reply`.`meta_key` = '_bbp_last_active_id'
785 - WHERE `reply`.`meta_id` IS NULL AND `topic`.`post_type` = 'topic' );" ) ) )
786 - return array( 7, sprintf( $statement, $result ) );
787 -
788 - // Give topics with replies their last update time.
789 - if ( is_wp_error( $wpdb->query( "INSERT INTO `$wpdb->postmeta` (`post_id`, `meta_key`, `meta_value`)
790 - ( SELECT `topic`.`ID`, '_bbp_last_active_time', MAX( `reply`.`post_date` )
791 - FROM `$wpdb->posts` AS `topic` INNER JOIN `$wpdb->posts` AS `reply` ON `topic`.`ID` = `reply`.`post_parent`
792 - WHERE `reply`.`post_status` IN ( '" . bbp_get_public_status_id() . "' ) AND `topic`.`post_type` = 'topic' AND `reply`.`post_type` = 'reply'
793 - GROUP BY `topic`.`ID` );" ) ) )
794 - return array( 8, sprintf( $statement, $result ) );
795 -
796 - // Give topics without replies their last update time.
797 - if ( is_wp_error( $wpdb->query( "INSERT INTO `$wpdb->postmeta` (`post_id`, `meta_key`, `meta_value`)
798 - ( SELECT `ID`, '_bbp_last_active_time', `post_date`
799 - FROM `$wpdb->posts` AS `topic` LEFT JOIN `$wpdb->postmeta` AS `reply`
800 - ON `topic`.`ID` = `reply`.`post_id` AND `reply`.`meta_key` = '_bbp_last_active_time'
801 - WHERE `reply`.`meta_id` IS NULL AND `topic`.`post_type` = 'topic' );" ) ) )
802 - return array( 9, sprintf( $statement, $result ) );
803 -
804 - // Forums need to know what their last active item is as well. Now it gets a bit more complex to do in the database.
805 - $forums = $wpdb->get_col( "SELECT `ID` FROM `$wpdb->posts` WHERE `post_type` = 'forum' and `post_status` != 'auto-draft';" );
806 - if ( is_wp_error( $forums ) )
807 - return array( 10, sprintf( $statement, $result ) );
808 -
809 - // Loop through forums
810 - foreach ( $forums as $forum_id ) {
811 - if ( !bbp_is_forum_category( $forum_id ) ) {
812 - bbp_update_forum( array( 'forum_id' => $forum_id ) );
813 - }
814 - }
815 -
816 - // Loop through categories when forums are done
817 - foreach ( $forums as $forum_id ) {
818 - if ( bbp_is_forum_category( $forum_id ) ) {
819 - bbp_update_forum( array( 'forum_id' => $forum_id ) );
820 - }
821 - }
822 -
823 - // Complete results
824 - return array( 0, sprintf( $statement, __( 'Complete!', 'bbpress' ) ) );
825 -}
826 -
827 -/**
828 - * Recaches the private and hidden forums
829 - *
830 - * @since bbPress (r4104)
831 - *
832 - * @uses delete_option() to delete private and hidden forum pointers
833 - * @uses WP_Query() To query post IDs
834 - * @uses is_wp_error() To return if error occurred
835 - * @uses update_option() To update the private and hidden post ID pointers
836 - * @return array An array of the status code and the message
837 - */
838 -function bbp_admin_repair_forum_visibility() {
839 -
840 - $statement = __( 'Recalculating forum visibility &hellip; %s', 'bbpress' );
841 - $result = __( 'Failed!', 'bbpress' );
842 -
843 - // First, delete everything.
844 - delete_option( '_bbp_private_forums' );
845 - delete_option( '_bbp_hidden_forums' );
846 -
847 - // Next, get all the private and hidden forums
848 - $private_forums = new WP_Query( array(
849 - 'suppress_filters' => true,
850 - 'nopaging' => true,
851 - 'post_type' => bbp_get_forum_post_type(),
852 - 'post_status' => bbp_get_private_status_id(),
853 - 'fields' => 'ids'
552 + // Deprecated 2.6.0
553 + 'href' => add_query_arg( array( 'page' => 'bbp-reset' ), $tools_url )
554 + )
854 555 ) );
855 - $hidden_forums = new WP_Query( array(
856 - 'suppress_filters' => true,
857 - 'nopaging' => true,
858 - 'post_type' => bbp_get_forum_post_type(),
859 - 'post_status' => bbp_get_hidden_status_id(),
860 - 'fields' => 'ids'
861 - ) );
862 -
863 - // Bail if queries returned errors
864 - if ( is_wp_error( $private_forums ) || is_wp_error( $hidden_forums ) )
865 - return array( 2, sprintf( $statement, $result ) );
866 -
867 - update_option( '_bbp_private_forums', $private_forums->posts ); // Private forums
868 - update_option( '_bbp_hidden_forums', $hidden_forums->posts ); // Hidden forums
869 -
870 - // Reset the $post global
871 - wp_reset_postdata();
872 -
873 - // Complete results
874 - return array( 0, sprintf( $statement, __( 'Complete!', 'bbpress' ) ) );
875 -}
876 -
877 -/**
878 - * Recaches the forum for each post
879 - *
880 - * @since bbPress (r3876)
881 - *
882 - * @uses wpdb::query() To run our recount sql queries
883 - * @uses is_wp_error() To check if the executed query returned {@link WP_Error}
884 - * @return array An array of the status code and the message
885 - */
886 -function bbp_admin_repair_forum_meta() {
887 - global $wpdb;
888 -
889 - $statement = __( 'Recalculating the forum for each post &hellip; %s', 'bbpress' );
890 - $result = __( 'Failed!', 'bbpress' );
891 -
892 - // First, delete everything.
893 - if ( is_wp_error( $wpdb->query( "DELETE FROM `$wpdb->postmeta` WHERE `meta_key` = '_bbp_forum_id';" ) ) )
894 - return array( 1, sprintf( $statement, $result ) );
895 -
896 - // Next, give all the topics with replies the ID their last reply.
897 - if ( is_wp_error( $wpdb->query( "INSERT INTO `$wpdb->postmeta` (`post_id`, `meta_key`, `meta_value`)
898 - ( SELECT `forum`.`ID`, '_bbp_forum_id', `forum`.`post_parent`
899 - FROM `$wpdb->posts`
900 - AS `forum`
901 - WHERE `forum`.`post_type` = 'forum'
902 - GROUP BY `forum`.`ID` );" ) ) )
903 - return array( 2, sprintf( $statement, $result ) );
904 -
905 - // Next, give all the topics with replies the ID their last reply.
906 - if ( is_wp_error( $wpdb->query( "INSERT INTO `$wpdb->postmeta` (`post_id`, `meta_key`, `meta_value`)
907 - ( SELECT `topic`.`ID`, '_bbp_forum_id', `topic`.`post_parent`
908 - FROM `$wpdb->posts`
909 - AS `topic`
910 - WHERE `topic`.`post_type` = 'topic'
911 - GROUP BY `topic`.`ID` );" ) ) )
912 - return array( 3, sprintf( $statement, $result ) );
913 -
914 - // Next, give all the topics with replies the ID their last reply.
915 - if ( is_wp_error( $wpdb->query( "INSERT INTO `$wpdb->postmeta` (`post_id`, `meta_key`, `meta_value`)
916 - ( SELECT `reply`.`ID`, '_bbp_forum_id', `topic`.`post_parent`
917 - FROM `$wpdb->posts`
918 - AS `reply`
919 - INNER JOIN `$wpdb->posts`
920 - AS `topic`
921 - ON `reply`.`post_parent` = `topic`.`ID`
922 - WHERE `topic`.`post_type` = 'topic'
923 - AND `reply`.`post_type` = 'reply'
924 - GROUP BY `reply`.`ID` );" ) ) )
925 - return array( 4, sprintf( $statement, $result ) );
926 -
927 - // Complete results
928 - return array( 0, sprintf( $statement, __( 'Complete!', 'bbpress' ) ) );
929 -}
930 -
931 -/**
932 - * Recaches the topic for each post
933 - *
934 - * @since bbPress (r3876)
935 - *
936 - * @uses wpdb::query() To run our recount sql queries
937 - * @uses is_wp_error() To check if the executed query returned {@link WP_Error}
938 - * @return array An array of the status code and the message
939 - */
940 -function bbp_admin_repair_topic_meta() {
941 - global $wpdb;
942 -
943 - $statement = __( 'Recalculating the topic for each post &hellip; %s', 'bbpress' );
944 - $result = __( 'Failed!', 'bbpress' );
945 -
946 - // First, delete everything.
947 - if ( is_wp_error( $wpdb->query( "DELETE FROM `$wpdb->postmeta` WHERE `meta_key` = '_bbp_topic_id';" ) ) )
948 - return array( 1, sprintf( $statement, $result ) );
949 -
950 - // Next, give all the topics with replies the ID their last reply.
951 - if ( is_wp_error( $wpdb->query( "INSERT INTO `$wpdb->postmeta` (`post_id`, `meta_key`, `meta_value`)
952 - ( SELECT `topic`.`ID`, '_bbp_topic_id', `topic`.`ID`
953 - FROM `$wpdb->posts`
954 - AS `topic`
955 - WHERE `topic`.`post_type` = 'topic'
956 - GROUP BY `topic`.`ID` );" ) ) )
957 - return array( 3, sprintf( $statement, $result ) );
958 -
959 - // Next, give all the topics with replies the ID their last reply.
960 - if ( is_wp_error( $wpdb->query( "INSERT INTO `$wpdb->postmeta` (`post_id`, `meta_key`, `meta_value`)
961 - ( SELECT `reply`.`ID`, '_bbp_topic_id', `topic`.`ID`
962 - FROM `$wpdb->posts`
963 - AS `reply`
964 - INNER JOIN `$wpdb->posts`
965 - AS `topic`
966 - ON `reply`.`post_parent` = `topic`.`ID`
967 - WHERE `topic`.`post_type` = 'topic'
968 - AND `reply`.`post_type` = 'reply'
969 - GROUP BY `reply`.`ID` );" ) ) )
970 - return array( 4, sprintf( $statement, $result ) );
971 -
972 - // Complete results
973 - return array( 0, sprintf( $statement, __( 'Complete!', 'bbpress' ) ) );
974 -}
975 -
976 -/** Reset ********************************************************************/
977 -
978 -/**
979 - * Admin reset page
980 - *
981 - * @since bbPress (r2613)
982 - *
983 - * @uses check_admin_referer() To verify the nonce and the referer
984 - * @uses do_action() Calls 'admin_notices' to display the notices
985 - * @uses screen_icon() To display the screen icon
986 - * @uses wp_nonce_field() To add a hidden nonce field
987 - */
988 -function bbp_admin_reset() {
989 -?>
990 -
991 - <div class="wrap">
992 -
993 - <?php screen_icon( 'tools' ); ?>
994 -
995 - <h2 class="nav-tab-wrapper"><?php bbp_tools_admin_tabs( __( 'Reset Forums', 'bbpress' ) ); ?></h2>
996 - <p><?php _e( 'This will revert your forums back to a brand new installation. This process cannot be undone. <strong>Backup your database before proceeding</strong>.', 'bbpress' ); ?></p>
997 -
998 - <form class="settings" method="post" action="">
999 - <table class="form-table">
1000 - <tbody>
1001 - <tr valign="top">
1002 - <th scope="row"><?php _e( 'The following data will be removed:', 'bbpress' ) ?></th>
1003 - <td>
1004 - <?php _e( 'All Forums', 'bbpress' ); ?><br />
1005 - <?php _e( 'All Topics', 'bbpress' ); ?><br />
1006 - <?php _e( 'All Replies', 'bbpress' ); ?><br />
1007 - <?php _e( 'All Topic Tags', 'bbpress' ); ?><br />
1008 - <?php _e( 'Related Meta Data', 'bbpress' ); ?><br />
1009 - <?php _e( 'Forum Settings', 'bbpress' ); ?><br />
1010 - <?php _e( 'Forum Activity', 'bbpress' ); ?><br />
1011 - <?php _e( 'Forum User Roles', 'bbpress' ); ?><br />
1012 - <?php _e( 'Importer Helper Data', 'bbpress' ); ?><br />
1013 - </td>
1014 - </tr>
1015 - <tr valign="top">
1016 - <th scope="row"><?php _e( 'Are you sure you want to do this?', 'bbpress' ) ?></th>
1017 - <td>
1018 - <fieldset>
1019 - <legend class="screen-reader-text"><span><?php _e( "Say it ain't so!", 'bbpress' ) ?></span></legend>
1020 - <label><input type="checkbox" class="checkbox" name="bbpress-are-you-sure" id="bbpress-are-you-sure" value="1" /> <?php _e( 'This process cannot be undone.', 'bbpress' ); ?></label>
1021 - </fieldset>
1022 - </td>
1023 - </tr>
1024 - </tbody>
1025 - </table>
1026 -
1027 - <fieldset class="submit">
1028 - <input class="button-primary" type="submit" name="submit" value="<?php esc_attr_e( 'Reset bbPress', 'bbpress' ); ?>" />
1029 - <?php wp_nonce_field( 'bbpress-reset' ); ?>
1030 - </fieldset>
1031 - </form>
1032 - </div>
1033 -
1034 -<?php
1035 -}
1036 -
1037 -/**
1038 - * Handle the processing and feedback of the admin tools page
1039 - *
1040 - * @since bbPress (r2613)
1041 - *
1042 - * @uses check_admin_referer() To verify the nonce and the referer
1043 - * @uses wp_cache_flush() To flush the cache
1044 - */
1045 -function bbp_admin_reset_handler() {
1046 - if ( 'post' == strtolower( $_SERVER['REQUEST_METHOD'] ) && !empty( $_POST['bbpress-are-you-sure'] ) ) {
1047 - check_admin_referer( 'bbpress-reset' );
1048 -
1049 - global $wpdb;
1050 -
1051 - // Stores messages
1052 - $messages = array();
1053 - $failed = __( 'Failed', 'bbpress' );
1054 - $success = __( 'Success!', 'bbpress' );
1055 -
1056 - // Flush the cache; things are about to get ugly.
1057 - wp_cache_flush();
1058 -
1059 - /** Posts *************************************************************/
1060 -
1061 - $statement = __( 'Deleting Posts&hellip; %s', 'bbpress' );
1062 - $sql_posts = $wpdb->get_results( "SELECT `ID` FROM `{$wpdb->posts}` WHERE `post_type` IN ('forum', 'topic', 'reply')", OBJECT_K );
1063 - $sql_delete = "DELETE FROM `{$wpdb->posts}` WHERE `post_type` IN ('forum', 'topic', 'reply')";
1064 - $result = is_wp_error( $wpdb->query( $sql_delete ) ) ? $failed : $success;
1065 - $messages[] = sprintf( $statement, $result );
1066 -
1067 -
1068 - /** Post Meta *********************************************************/
1069 -
1070 - if ( !empty( $sql_posts ) ) {
1071 - foreach( $sql_posts as $key => $value ) {
1072 - $sql_meta[] = $key;
1073 - }
1074 - $statement = __( 'Deleting Post Meta&hellip; %s', 'bbpress' );
1075 - $sql_meta = implode( "', '", $sql_meta );
1076 - $sql_delete = "DELETE FROM `{$wpdb->postmeta}` WHERE `post_id` IN ('{$sql_meta}');";
1077 - $result = is_wp_error( $wpdb->query( $sql_delete ) ) ? $failed : $success;
1078 - $messages[] = sprintf( $statement, $result );
1079 - }
1080 -
1081 - /** Topic Tags ********************************************************/
1082 -
1083 - // @todo
1084 -
1085 - /** User Meta *********************************************************/
1086 -
1087 - $statement = __( 'Deleting User Meta&hellip; %s', 'bbpress' );
1088 - $sql_delete = "DELETE FROM `{$wpdb->usermeta}` WHERE `meta_key` LIKE '%%_bbp_%%';";
1089 - $result = is_wp_error( $wpdb->query( $sql_delete ) ) ? $failed : $success;
1090 - $messages[] = sprintf( $statement, $result );
1091 -
1092 - /** Converter *********************************************************/
1093 -
1094 - $statement = __( 'Deleting Conversion Table&hellip; %s', 'bbpress' );
1095 - $table_name = $wpdb->prefix . 'bbp_converter_translator';
1096 - if ( $wpdb->get_var( "SHOW TABLES LIKE '{$table_name}'" ) == $table_name ) {
1097 - $wpdb->query( "DROP TABLE {$table_name}" );
1098 - $result = $success;
1099 - } else {
1100 - $result = $failed;
1101 - }
1102 - $messages[] = sprintf( $statement, $result );
1103 -
1104 - /** Options ***********************************************************/
1105 -
1106 - $statement = __( 'Deleting Settings&hellip; %s', 'bbpress' );
1107 - $sql_delete = bbp_delete_options();
1108 - $messages[] = sprintf( $statement, $success );
1109 -
1110 - /** Roles *************************************************************/
1111 -
1112 - $statement = __( 'Deleting Roles and Capabilities&hellip; %s', 'bbpress' );
1113 - $sql_delete = bbp_remove_roles();
1114 - $sql_delete = bbp_remove_caps();
1115 - $messages[] = sprintf( $statement, $success );
1116 -
1117 - /** Output ************************************************************/
1118 -
1119 - if ( count( $messages ) ) {
1120 - foreach ( $messages as $message ) {
1121 - bbp_admin_tools_feedback( $message );
1122 - }
1123 - }
1124 - }
1125 556 }