PluginProbe
bbPress / 2.0-beta-1
bbPress v2.0-beta-1
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
bbpress / bbp-admin / bbp-functions.php

bbp-functions.php in bbPress 2.0-beta-1, at bbp-admin/bbp-functions.php

875 lines 32.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * bbPress Admin Functions
5 *
6 * @package bbPress
7 * @subpackage Administration
8 */
9
10 // Redirect if accessed directly
11 if ( !defined( 'ABSPATH' ) ) exit;
12
13 /** Admin Menus ***************************************************************/
14
15 /**
16 * Add a separator to the WordPress admin menus
17 *
18 * @since bbPress (r2957)
19 */
20 function bbp_admin_separator () {
21 global $menu;
22
23 if ( !current_user_can( 'edit_replies' ) )
24 return;
25
26 $menu[] = array( '', 'read', 'separator-bbpress', '', 'wp-menu-separator' );
27 }
28
29 /**
30 * Tell WordPress we have a custom menu order
31 *
32 * @since bbPress (r2957)
33 *
34 * @param bool $menu_order Menu order
35 * @return bool Always true
36 */
37 function bbp_admin_custom_menu_order( $menu_order ) {
38 if ( !current_user_can( 'edit_replies' ) )
39 return false;
40
41 return true;
42 }
43
44 /**
45 * Move our custom separator above our custom post types
46 *
47 * @since bbPress (r2957)
48 *
49 * @param array $menu_order Menu Order
50 * @uses bbp_get_forum_post_type() To get the forum post type
51 * @return array Modified menu order
52 */
53 function bbp_admin_menu_order( $menu_order ) {
54
55 // Initialize our custom order array
56 $bbp_menu_order = array();
57
58 // Get the index of our custom separator
59 $bbp_separator = array_search( 'separator-bbpress', $menu_order );
60
61 // Forums
62 if ( current_user_can( 'edit_forums' ) )
63 $top_menu_type = bbp_get_forum_post_type();
64
65 // Topics
66 elseif ( current_user_can( 'edit_topics' ) )
67 $top_menu_type = bbp_get_topic_post_type();
68
69 // Replies
70 elseif ( current_user_can( 'edit_replies' ) )
71 $top_menu_type = bbp_get_reply_post_type();
72
73 // Bail if there are no bbPress menus present
74 else
75 return;
76
77 // Loop through menu order and do some rearranging
78 foreach ( $menu_order as $index => $item ) {
79
80 // Current item is ours, so set our separator here
81 if ( ( ( 'edit.php?post_type=' . $top_menu_type ) == $item ) ) {
82 $bbp_menu_order[] = 'separator-bbpress';
83 unset( $menu_order[$bbp_separator] );
84 }
85
86 // Skip our separator
87 if ( !in_array( $item, array( 'separator-bbpress' ) ) )
88 $bbp_menu_order[] = $item;
89
90 }
91
92 // Return our custom order
93 return $bbp_menu_order;
94 }
95
96 /**
97 * Display the admin notices
98 *
99 * @since bbPress (r2613)
100 *
101 * @param string|WP_Error $message A message to be displayed or {@link WP_Error}
102 * @param string $class Optional. A class to be added to the message div
103 * @uses WP_Error::get_error_messages() To get the error messages of $message
104 * @uses add_action() Adds the admin notice action with the message HTML
105 * @return string The message HTML
106 */
107 function bbp_admin_notices( $message, $class = false ) {
108 if ( is_string( $message ) ) {
109 $message = '<p>' . $message . '</p>';
110 $class = $class ? $class : 'updated';
111 } elseif ( is_wp_error( $message ) ) {
112 $errors = $message->get_error_messages();
113
114 switch ( count( $errors ) ) {
115 case 0:
116 return false;
117 break;
118
119 case 1:
120 $message = '<p>' . $errors[0] . '</p>';
121 break;
122
123 default:
124 $message = '<ul>' . "\n\t" . '<li>' . join( '</li>' . "\n\t" . '<li>', $errors ) . '</li>' . "\n" . '</ul>';
125 break;
126 }
127
128 $class = $class ? $class : 'error';
129 } else {
130 return false;
131 }
132
133 $message = '<div id="message" class="' . esc_attr( $class ) . '">' . $message . '</div>';
134 $message = str_replace( "'", "\'", $message );
135 $lambda = create_function( '', "echo '$message';" );
136
137 add_action( 'admin_notices', $lambda );
138
139 return $lambda;
140 }
141
142 /**
143 * Get the array of the recount list
144 *
145 * @since bbPress (r2613)
146 *
147 * @uses apply_filters() Calls 'bbp_recount_list' with the recount list array
148 * @return array Recount list
149 */
150 function bbp_recount_list() {
151 $recount_list = array(
152 5 => array( 'bbp-forum-topics', __( 'Count topics in each forum', 'bbpress' ), 'bbp_recount_forum_topics' ),
153 10 => array( 'bbp-forum-replies', __( 'Count replies in each forum', 'bbpress' ), 'bbp_recount_forum_replies' ),
154 15 => array( 'bbp-topic-replies', __( 'Count replies in each topic', 'bbpress' ), 'bbp_recount_topic_replies' ),
155 20 => array( 'bbp-topic-voices', __( 'Count voices in each topic', 'bbpress' ), 'bbp_recount_topic_voices' ),
156 25 => array( 'bbp-topic-hidden-replies', __( 'Count spammed & trashed replies in each topic', 'bbpress' ), 'bbp_recount_topic_hidden_replies' ),
157 30 => array( 'bbp-topics-replied', __( 'Count replies for each user', 'bbpress' ), 'bbp_recount_user_topics_replied' ),
158 35 => array( 'bbp-clean-favorites', __( 'Remove trashed topics from user favorites', 'bbpress' ), 'bbp_recount_clean_favorites' ),
159 40 => array( 'bbp-clean-subscriptions', __( 'Remove trashed topics from user subscriptions', 'bbpress' ), 'bbp_recount_clean_subscriptions' ),
160 //45 => array( 'bbp-topic-tag-count', __( 'Count tags for every topic', 'bbpress' ), 'bbp_recount_topic_tags' ),
161 //50 => array( 'bbp-tags-tag-count', __( 'Count topics for every tag', 'bbpress' ), 'bbp_recount_tag_topics' ),
162 //55 => array( 'bbp-tags-delete-empty', __( 'Delete tags with no topics', 'bbpress' ), 'bbp_recount_tag_delete_empty' ),
163 60 => array( 'bbp-sync-all-topics-forums', __( 'Recalculate last activity in each topic and forum', 'bbpress' ), 'bbp_recount_rewalk' )
164 );
165
166 ksort( $recount_list );
167 return apply_filters( 'bbp_recount_list', $recount_list );
168 }
169
170 /**
171 * Recount topic replies
172 *
173 * @since bbPress (r2613)
174 *
175 * @uses bbp_get_reply_post_type() To get the reply post type
176 * @uses wpdb::query() To run our recount sql queries
177 * @uses is_wp_error() To check if the executed query returned {@link WP_Error}
178 * @return array An array of the status code and the message
179 */
180 function bbp_recount_topic_replies() {
181 global $wpdb;
182
183 $statement = __( 'Counting the number of replies in each topic&hellip; %s', 'bbpress' );
184 $result = __( 'Failed!', 'bbpress' );
185
186 $sql_delete = "DELETE FROM `{$wpdb->postmeta}` WHERE `meta_key` = '_bbp_reply_count';";
187 if ( is_wp_error( $wpdb->query( $sql_delete ) ) )
188 return array( 1, sprintf( $statement, $result ) );
189
190 $sql = "INSERT INTO `{$wpdb->postmeta}` (`post_id`, `meta_key`, `meta_value`) (SELECT `post_parent`, '_bbp_reply_count', COUNT(`post_status`) as `meta_value` FROM `{$wpdb->posts}` WHERE `post_type` = '" . bbp_get_reply_post_type() . "' AND `post_status` = 'publish' GROUP BY `post_parent`);";
191 if ( is_wp_error( $wpdb->query( $sql ) ) )
192 return array( 2, sprintf( $statement, $result ) );
193
194 $result = __( 'Complete!', 'bbpress' );
195 return array( 0, sprintf( $statement, $result ) );
196 }
197
198 /**
199 * Recount topic voices
200 *
201 * @since bbPress (r2613)
202 *
203 * @uses bbp_get_reply_post_type() To get the reply post type
204 * @uses wpdb::query() To run our recount sql queries
205 * @uses is_wp_error() To check if the executed query returned {@link WP_Error}
206 * @return array An array of the status code and the message
207 */
208 function bbp_recount_topic_voices() {
209 global $wpdb;
210
211 $statement = __( 'Counting the number of voices in each topic&hellip; %s', 'bbpress' );
212 $result = __( 'Failed!', 'bbpress' );
213
214 $sql_delete = "DELETE FROM `{$wpdb->postmeta}` WHERE `meta_key` = '_bbp_voice_count';";
215 if ( is_wp_error( $wpdb->query( $sql_delete ) ) )
216 return array( 1, sprintf( $statement, $result ) );
217
218 $sql = "INSERT INTO `{$wpdb->postmeta}` (`post_id`, `meta_key`, `meta_value`) (SELECT `post_parent`, '_bbp_voice_count', COUNT(DISTINCT `post_author`) as `meta_value` FROM `{$wpdb->posts}` WHERE `post_type` = '" . bbp_get_reply_post_type() . "' AND `post_status` = 'publish' GROUP BY `post_parent`);";
219 if ( is_wp_error( $wpdb->query( $sql ) ) )
220 return array( 2, sprintf( $statement, $result ) );
221
222 $result = __( 'Complete!', 'bbpress' );
223 return array( 0, sprintf( $statement, $result ) );
224 }
225
226 /**
227 * Recount topic hidden replies (spammed/trashed)
228 *
229 * @since bbPress (r2747)
230 *
231 * @uses wpdb::query() To run our recount sql queries
232 * @uses is_wp_error() To check if the executed query returned {@link WP_Error}
233 * @return array An array of the status code and the message
234 */
235 function bbp_recount_topic_hidden_replies() {
236 global $wpdb, $bbp;
237
238 $statement = __( 'Counting the number of spammed and trashed replies in each topic&hellip; %s', 'bbpress' );
239 $result = __( 'Failed!', 'bbpress' );
240
241 $sql_delete = "DELETE FROM `{$wpdb->postmeta}` WHERE `meta_key` = '_bbp_hidden_reply_count';";
242 if ( is_wp_error( $wpdb->query( $sql_delete ) ) )
243 return array( 1, sprintf( $statement, $result ) );
244
245 $sql = "INSERT INTO `{$wpdb->postmeta}` (`post_id`, `meta_key`, `meta_value`) (SELECT `post_parent`, '_bbp_hidden_reply_count', COUNT(`post_status`) as `meta_value` FROM `{$wpdb->posts}` WHERE `post_type` = '" . bbp_get_reply_post_type() . "' AND `post_status` IN ( '" . join( "','", array( 'trash', $bbp->spam_status_id ) ) . "') GROUP BY `post_parent`);";
246 if ( is_wp_error( $wpdb->query( $sql ) ) )
247 return array( 2, sprintf( $statement, $result ) );
248
249 $result = __( 'Complete!', 'bbpress' );
250 return array( 0, sprintf( $statement, $result ) );
251 }
252
253 /**
254 * Recount forum topics
255 *
256 * @since bbPress (r2613)
257 *
258 * @uses wpdb::query() To run our recount sql queries
259 * @uses is_wp_error() To check if the executed query returned {@link WP_Error}
260 * @uses bbp_get_forum_post_type() To get the forum post type
261 * @uses get_posts() To get the forums
262 * @uses bbp_update_forum_topic_count() To update the forum topic count
263 * @return array An array of the status code and the message
264 */
265 function bbp_recount_forum_topics() {
266 global $wpdb;
267
268 $statement = __( 'Counting the number of topics in each forum&hellip; %s', 'bbpress' );
269 $result = __( 'Failed!', 'bbpress' );
270
271 $sql_delete = "DELETE FROM {$wpdb->postmeta} WHERE meta_key IN ( '_bbp_forum_topic_count', '_bbp_total_topic_count' );";
272 if ( is_wp_error( $wpdb->query( $sql_delete ) ) )
273 return array( 1, sprintf( $statement, $result ) );
274
275 if ( $forums = get_posts( array( 'post_type' => bbp_get_forum_post_type(), 'numberposts' => -1 ) ) ) {
276 foreach( $forums as $forum ) {
277 bbp_update_forum_topic_count( $forum->ID );
278 }
279 } else {
280 return array( 2, sprintf( $statement, $result ) );
281 }
282
283 $result = __( 'Complete!', 'bbpress' );
284 return array( 0, sprintf( $statement, $result ) );
285 }
286
287 /**
288 * Recount forum replies
289 *
290 * @since bbPress (r2613)
291 *
292 * @uses wpdb::query() To run our recount sql queries
293 * @uses is_wp_error() To check if the executed query returned {@link WP_Error}
294 * @uses bbp_get_forum_post_type() To get the forum post type
295 * @uses get_posts() To get the forums
296 * @uses bbp_update_forum_reply_count() To update the forum reply count
297 * @return array An array of the status code and the message
298 */
299 function bbp_recount_forum_replies() {
300 global $wpdb;
301
302 $statement = __( 'Counting the number of replies in each forum&hellip; %s', 'bbpress' );
303 $result = __( 'Failed!', 'bbpress' );
304
305 $sql_delete = "DELETE FROM `{$wpdb->postmeta}` WHERE `meta_key` IN ( '_bbp_reply_count', '_bbp_total_reply_count' );";
306 if ( is_wp_error( $wpdb->query( $sql_delete ) ) )
307 return array( 1, sprintf( $statement, $result ) );
308
309 if ( $forums = get_posts( array( 'post_type' => bbp_get_forum_post_type(), 'numberposts' => -1 ) ) ) {
310 foreach( $forums as $forum ) {
311 bbp_update_forum_reply_count( $forum->ID );
312 }
313 } else {
314 return array( 2, sprintf( $statement, $result ) );
315 }
316
317 $result = __( 'Complete!', 'bbpress' );
318 return array( 0, sprintf( $statement, $result ) );
319 }
320
321 /**
322 * Recount topic replied by the users
323 *
324 * @since bbPress (r2613)
325 *
326 * @uses bbp_get_reply_post_type() To get the reply post type
327 * @uses wpdb::query() To run our recount sql queries
328 * @uses is_wp_error() To check if the executed query returned {@link WP_Error}
329 * @return array An array of the status code and the message
330 */
331 function bbp_recount_user_topics_replied() {
332 global $wpdb;
333
334 $statement = __( 'Counting the number of topics to which each user has replied&hellip; %s', 'bbpress' );
335 $result = __( 'Failed!', 'bbpress' );
336
337 $sql_select = "SELECT `post_author`, COUNT(DISTINCT `ID`) as `_count` FROM `{$wpdb->posts}` WHERE `post_type` = '" . bbp_get_reply_post_type() . "' AND `post_status` = 'publish' GROUP BY `post_author`;";
338 $insert_rows = $wpdb->get_results( $sql_select );
339
340 if ( is_wp_error( $insert_rows ) )
341 return array( 1, sprintf( $statement, $result ) );
342
343 $insert_values = array();
344 foreach ( $insert_rows as $insert_row )
345 $insert_values[] = "('{$insert_row->post_author}', '_bbp_topics_replied', '{$insert_row->_count}')";
346
347 if ( !count( $insert_values ) )
348 return array( 2, sprintf( $statement, $result ) );
349
350 $sql_delete = "DELETE FROM `{$wpdb->usermeta}` WHERE `meta_key` = '_bbp_topics_replied';";
351 if ( is_wp_error( $wpdb->query( $sql_delete ) ) )
352 return array( 3, sprintf( $statement, $result ) );
353
354 $insert_values = array_chunk( $insert_values, 10000 );
355 foreach ( $insert_values as $chunk ) {
356 $chunk = "\n" . join( ",\n", $chunk );
357 $sql_insert = "INSERT INTO `{$wpdb->usermeta}` (`user_id`, `meta_key`, `meta_value`) VALUES $chunk;";
358
359 if ( is_wp_error( $wpdb->query( $sql_insert ) ) )
360 return array( 4, sprintf( $statement, $result ) );
361 }
362
363 $result = __( 'Complete!', 'bbpress' );
364 return array( 0, sprintf( $statement, $result ) );
365 }
366
367 // This function bypasses the taxonomy API
368 /**
369 * Recount topic tags in each topic
370 *
371 * @since bbPress (r2613)
372 *
373 * @uses wpdb::query() To run our recount sql queries
374 * @uses is_wp_error() To check if the executed query returned {@link WP_Error}
375 * @return array An array of the status code and the message
376 */
377 function bbp_recount_topic_tags() {
378 global $wpdb;
379
380 $statement = __( 'Counting the number of topic tags in each topic&hellip; %s', 'bbpress' );
381 $result = __( 'Failed!', 'bbpress' );
382
383 // // Delete empty tags
384 // $delete = bbp_recount_tag_delete_empty();
385 // if ( $delete[0] > 0 ) {
386 // $result = __( 'Could not delete empty tags.' );
387 // return array( 1, sprintf( $statement, $result ) );
388 // }
389 //
390 // // Get all tags
391 // $sql_terms = "SELECT
392 // `$wpdb->term_relationships`.`object_id`,
393 // `$wpdb->term_taxonomy`.`term_id`
394 // FROM `$wpdb->term_relationships`
395 // JOIN `$wpdb->term_taxonomy`
396 // ON `$wpdb->term_taxonomy`.`term_taxonomy_id` = `$wpdb->term_relationships`.`term_taxonomy_id`
397 // WHERE
398 // `$wpdb->term_taxonomy`.`taxonomy` = 'bb_topic_tag'
399 // ORDER BY
400 // `$wpdb->term_relationships`.`object_id`,
401 // `$wpdb->term_taxonomy`.`term_id`;";
402 //
403 // $terms = $wpdb->get_results( $sql_terms );
404 // if ( is_wp_error( $terms ) || !is_array( $terms ) )
405 // return array( 2, sprintf( $statement, $result ) );
406 //
407 // if ( empty( $terms ) ) {
408 // $result = __( 'No topic tags found.' );
409 // return array( 3, sprintf( $statement, $result ) );
410 // }
411 //
412 // // Count the tags in each topic
413 // $topics = array( );
414 // foreach ( $terms as $term ) {
415 // if ( !isset( $topics[$term->object_id] ) ) {
416 // $topics[$term->object_id] = 1;
417 // } else {
418 // $topics[$term->object_id]++;
419 // }
420 // }
421 //
422 // if ( empty( $topics ) )
423 // return array( 4, sprintf( $statement, $result ) );
424 //
425 // // Build the values to insert into the SQL statement
426 // $values = array( );
427 // foreach ( $topics as $topic_id => $tag_count )
428 // $values[] = '(' . $topic_id . ', ' . $tag_count . ')';
429 //
430 // if ( empty( $values ) )
431 // return array( 5, sprintf( $statement, $result ) );
432 //
433 // // Update the topics with the new tag counts
434 // $values = array_chunk( $values, 10000 );
435 // foreach ( $values as $chunk ) {
436 // $sql = "INSERT INTO `$wpdb->topics` (`topic_id`, `tag_count`) VALUES " . implode( ", ", $chunk ) . " ON DUPLICATE KEY UPDATE `tag_count` = VALUES(`tag_count`);";
437 // if ( is_wp_error( $wpdb->query( $sql ) ) ) {
438 // return array( 6, sprintf( $statement, $result ) );
439 // }
440 // }
441 //
442 // $result = __( 'Complete!', 'bbpress' );
443 return array( 0, sprintf( $statement, $result ) );
444 }
445
446 // This function bypasses the taxonomy API
447 /**
448 * Recount the number of topics in each topic tag
449 *
450 * @since bbPress (r2613)
451 *
452 * @uses wpdb::query() To run our recount sql queries
453 * @uses is_wp_error() To check if the executed query returned {@link WP_Error}
454 * @return array An array of the status code and the message
455 */
456 function bbp_recount_tag_topics() {
457 global $wpdb;
458
459 $statement = __( 'Counting the number of topics in each topic tag&hellip; %s', 'bbpress' );
460 $result = __( 'Failed!', 'bbpress' );
461
462 // // Delete empty tags
463 // $delete = bbp_recount_tag_delete_empty();
464 // if ( $delete[0] > 0 ) {
465 // $result = __( 'Could not delete empty tags.' );
466 // return array( 1, sprintf( $statement, $result ) );
467 // }
468 //
469 // // Get all tags
470 // $sql_terms = "SELECT
471 // `$wpdb->term_taxonomy`.`term_taxonomy_id`,
472 // `$wpdb->term_relationships`.`object_id`
473 // FROM `$wpdb->term_relationships`
474 // JOIN `$wpdb->term_taxonomy`
475 // ON `$wpdb->term_taxonomy`.`term_taxonomy_id` = `$wpdb->term_relationships`.`term_taxonomy_id`
476 // WHERE
477 // `$wpdb->term_taxonomy`.`taxonomy` = 'bb_topic_tag'
478 // ORDER BY
479 // `$wpdb->term_taxonomy`.`term_taxonomy_id`,
480 // `$wpdb->term_relationships`.`object_id`;";
481 //
482 // $terms = $wpdb->get_results( $sql_terms );
483 // if ( is_wp_error( $terms ) || !is_array( $terms ) )
484 // return array( 2, sprintf( $statement, $result ) );
485 //
486 // if ( empty( $terms ) ) {
487 // $result = __( 'No topic tags found.', 'bbpress' );
488 // return array( 3, sprintf( $statement, $result ) );
489 // }
490 //
491 // // Count the topics in each tag
492 // $tags = array( );
493 // foreach ( $terms as $term ) {
494 // if ( !isset( $tags[$term->term_taxonomy_id] ) ) {
495 // $tags[$term->term_taxonomy_id] = 1;
496 // } else {
497 // $tags[$term->term_taxonomy_id]++;
498 // }
499 // }
500 //
501 // if ( empty( $tags ) )
502 // return array( 4, sprintf( $statement, $result ) );
503 //
504 // // Build the values to insert into the SQL statement
505 // $values = array( );
506 // foreach ( $tags as $term_taxonomy_id => $count )
507 // $values[] = '(' . $term_taxonomy_id . ', ' . $count . ')';
508 //
509 // if ( empty( $values ) )
510 // return array( 5, sprintf( $statement, $result ) );
511 //
512 // // Update the terms with the new tag counts
513 // $values = array_chunk( $values, 10000 );
514 // foreach ( $values as $chunk ) {
515 // $sql = "INSERT INTO `$wpdb->term_taxonomy` (`term_taxonomy_id`, `count`) VALUES " . implode( ", ", $chunk ) . " ON DUPLICATE KEY UPDATE `count` = VALUES(`count`);";
516 // if ( is_wp_error( $wpdb->query( $sql ) ) ) {
517 // return array( 6, sprintf( $statement, $result ) );
518 // }
519 // }
520 //
521 // if ( $return_boolean )
522 // return true;
523 //
524 // $result = __( 'Complete!', 'bbpress' );
525 return array( 0, sprintf( $statement, $result ) );
526 }
527
528 // This function bypasses the taxonomy API
529 /**
530 * Recount topic tags with no topics
531 *
532 * @since bbPress (r2613)
533 *
534 * @uses wpdb::query() To run our recount sql queries
535 * @uses is_wp_error() To check if the executed query returned {@link WP_Error}
536 * @return array An array of the status code and the message
537 */
538 function bbp_recount_tag_delete_empty() {
539 global $wpdb;
540
541 $statement = __( 'Deleting topic tags with no topics&hellip; %s', 'bbpress' );
542 $result = __( 'Failed!', 'bbpress' );
543
544 // static $run_once;
545 // if ( isset( $run_once ) ) {
546 // if ( $run_once > 0 ) {
547 // $exit = sprintf( __( 'failure (returned code %s)', 'bbpress' ), $run_once );
548 // } else {
549 // $exit = __( 'success', 'bbpress' );
550 // }
551 // $result = sprintf( __( 'Already run with %s.', 'bbpress' ), $exit );
552 // return array( $run_once, sprintf( $statement, $result ) );
553 // }
554 //
555 // // Get all topic ids
556 // $sql_topics = "SELECT `topic_id` FROM $wpdb->topics ORDER BY `topic_id`;";
557 // $topics = $wpdb->get_results( $sql_topics );
558 // if ( is_wp_error( $topics ) ) {
559 // $result = __( 'No topics found.', 'bbpress' );
560 // $run_once = 1;
561 // return array( 1, sprintf( $statement, $result ) );
562 // }
563 //
564 // $topic_ids = array( );
565 //
566 // foreach ( $topics as $topic )
567 // $topic_ids[] = $topic->topic_id;
568 //
569 // // Get all topic tag term relationships without a valid topic id
570 // $in_topic_ids = implode( ', ', $topic_ids );
571 // $sql_bad_term_relationships = "SELECT
572 // `$wpdb->term_taxonomy`.`term_taxonomy_id`,
573 // `$wpdb->term_taxonomy`.`term_id`,
574 // `$wpdb->term_relationships`.`object_id`
575 // FROM `$wpdb->term_relationships`
576 // JOIN `$wpdb->term_taxonomy`
577 // ON `$wpdb->term_taxonomy`.`term_taxonomy_id` = `$wpdb->term_relationships`.`term_taxonomy_id`
578 // WHERE
579 // `$wpdb->term_taxonomy`.`taxonomy` = 'bb_topic_tag' AND
580 // `$wpdb->term_relationships`.`object_id` NOT IN ($in_topic_ids)
581 // ORDER BY
582 // `$wpdb->term_relationships`.`object_id`,
583 // `$wpdb->term_taxonomy`.`term_id`,
584 // `$wpdb->term_taxonomy`.`term_taxonomy_id`;";
585 //
586 // $bad_term_relationships = $wpdb->get_results( $sql_bad_term_relationships );
587 // if ( is_wp_error( $bad_term_relationships ) || !is_array( $bad_term_relationships ) ) {
588 // $run_once = 2;
589 // return array( 2, sprintf( $statement, $result ) );
590 // }
591 //
592 // // Delete those bad term relationships
593 // if ( !empty( $bad_term_relationships ) ) {
594 // $values = array( );
595 // foreach ( $bad_term_relationships as $bad_term_relationship ) {
596 // $values[] = '(`object_id` = ' . $bad_term_relationship->object_id . ' AND `term_taxonomy_id` = ' . $bad_term_relationship->term_taxonomy_id . ')';
597 // }
598 // if ( !empty( $values ) ) {
599 // $values = join( ' OR ', $values );
600 // $sql_bad_term_relationships_delete = "DELETE
601 // FROM `$wpdb->term_relationships`
602 // WHERE $values;";
603 // if ( is_wp_error( $wpdb->query( $sql_bad_term_relationships_delete ) ) ) {
604 // $run_once = 3;
605 // return array( 3, sprintf( $statement, $result ) );
606 // }
607 // }
608 // }
609 //
610 // // Now get all term taxonomy ids with term relationships
611 // $sql_term_relationships = "SELECT `term_taxonomy_id` FROM $wpdb->term_relationships ORDER BY `term_taxonomy_id`;";
612 // $term_taxonomy_ids = $wpdb->get_col( $sql_term_relationships );
613 // if ( is_wp_error( $term_taxonomy_ids ) ) {
614 // $run_once = 4;
615 // return array( 4, sprintf( $statement, $result ) );
616 // }
617 // $term_taxonomy_ids = array_unique( $term_taxonomy_ids );
618 //
619 // // Delete topic tags that don't have any term relationships
620 // if ( !empty( $term_taxonomy_ids ) ) {
621 // $in_term_taxonomy_ids = implode( ', ', $term_taxonomy_ids );
622 // $sql_delete_term_relationships = "DELETE
623 // FROM $wpdb->term_taxonomy
624 // WHERE
625 // `taxonomy` = 'bb_topic_tag' AND
626 // `term_taxonomy_id` NOT IN ($in_term_taxonomy_ids);";
627 // if ( is_wp_error( $wpdb->query( $sql_delete_term_relationships ) ) ) {
628 // $run_once = 5;
629 // return array( 5, sprintf( $statement, $result ) );
630 // }
631 // }
632 //
633 // // Get all valid term ids
634 // $sql_terms = "SELECT `term_id` FROM $wpdb->term_taxonomy ORDER BY `term_id`;";
635 // $term_ids = $wpdb->get_col( $sql_terms );
636 // if ( is_wp_error( $term_ids ) ) {
637 // $run_once = 6;
638 // return array( 6, sprintf( $statement, $result ) );
639 // }
640 // $term_ids = array_unique( $term_ids );
641 //
642 // // Delete terms that don't have any associated term taxonomies
643 // if ( !empty( $term_ids ) ) {
644 // $in_term_ids = implode( ', ', $term_ids );
645 // $sql_delete_terms = "DELETE
646 // FROM $wpdb->terms
647 // WHERE
648 // `term_id` NOT IN ($in_term_ids);";
649 // if ( is_wp_error( $wpdb->query( $sql_delete_terms ) ) ) {
650 // $run_once = 7;
651 // return array( 7, sprintf( $statement, $result ) );
652 // }
653 // }
654 //
655 // $result = __( 'Complete!', 'bbpress' );
656 // $run_once = 0;
657 return array( 0, sprintf( $statement, $result ) );
658 }
659
660 /**
661 * Clean the users' favorites
662 *
663 * @since bbPress (r2613)
664 *
665 * @uses bbp_get_topic_post_type() To get the topic post type
666 * @uses wpdb::query() To run our recount sql queries
667 * @uses is_wp_error() To check if the executed query returned {@link WP_Error}
668 * @return array An array of the status code and the message
669 */
670 function bbp_recount_clean_favorites() {
671 global $wpdb;
672
673 $statement = __( 'Removing trashed topics from user favorites&hellip; %s', 'bbpress' );
674 $result = __( 'Failed!', 'bbpress' );
675
676 $users = $wpdb->get_results( "SELECT `user_id`, `meta_value` AS `favorites` FROM `$wpdb->usermeta` WHERE `meta_key` = '_bbp_favorites';" );
677 if ( is_wp_error( $users ) )
678 return array( 1, sprintf( $statement, $result ) );
679
680 $topics = $wpdb->get_col( "SELECT `ID` FROM `$wpdb->posts` WHERE `post_type` = '" . bbp_get_topic_post_type() . "' AND `post_status` = 'publish';" );
681
682 if ( is_wp_error( $topics ) )
683 return array( 2, sprintf( $statement, $result ) );
684
685 $values = array();
686 foreach ( $users as $user ) {
687 if ( empty( $user->favorites ) || !is_string( $user->favorites ) )
688 continue;
689
690 $favorites = array_intersect( $topics, (array) explode( ',', $user->favorites ) );
691 if ( empty( $favorites ) || !is_array( $favorites ) )
692 continue;
693
694 $favorites = join( ',', $favorites );
695 $values[] = "('$user->user_id', '_bbp_favorites', '$favorites')";
696 }
697
698 if ( !count( $values ) ) {
699 $result = __( 'Nothing to remove!', 'bbpress' );
700 return array( 0, sprintf( $statement, $result ) );
701 }
702
703 $sql_delete = "DELETE FROM `$wpdb->usermeta` WHERE `meta_key` = '_bbp_favorites';";
704 if ( is_wp_error( $wpdb->query( $sql_delete ) ) )
705 return array( 4, sprintf( $statement, $result ) );
706
707 $values = array_chunk( $values, 10000 );
708 foreach ( $values as $chunk ) {
709 $chunk = "\n" . join( ",\n", $chunk );
710 $sql_insert = "INSERT INTO `$wpdb->usermeta` (`user_id`, `meta_key`, `meta_value`) VALUES $chunk;";
711 if ( is_wp_error( $wpdb->query( $sql_insert ) ) )
712 return array( 5, sprintf( $statement, $result ) );
713 }
714
715 $result = __( 'Complete!', 'bbpress' );
716 return array( 0, sprintf( $statement, $result ) );
717 }
718
719 /**
720 * Clean the users' subscriptions
721 *
722 * @since bbPress (r2668)
723 *
724 * @uses bbp_get_topic_post_type() To get the topic post type
725 * @uses wpdb::query() To run our recount sql queries
726 * @uses is_wp_error() To check if the executed query returned {@link WP_Error}
727 * @return array An array of the status code and the message
728 */
729 function bbp_recount_clean_subscriptions() {
730 global $wpdb;
731
732 $statement = __( 'Removing trashed topics from user subscriptions&hellip; %s', 'bbpress' );
733 $result = __( 'Failed!', 'bbpress' );
734
735 $users = $wpdb->get_results( "SELECT `user_id`, `meta_value` AS `subscriptions` FROM `$wpdb->usermeta` WHERE `meta_key` = '_bbp_subscriptions';" );
736 if ( is_wp_error( $users ) )
737 return array( 1, sprintf( $statement, $result ) );
738
739 $topics = $wpdb->get_col( "SELECT `ID` FROM `$wpdb->posts` WHERE `post_type` = '" . bbp_get_topic_post_type() . "' AND `post_status` = 'publish';" );
740 if ( is_wp_error( $topics ) )
741 return array( 2, sprintf( $statement, $result ) );
742
743 $values = array();
744 foreach ( $users as $user ) {
745 if ( empty( $user->subscriptions ) || !is_string( $user->subscriptions ) )
746 continue;
747
748 $subscriptions = array_intersect( $topics, (array) explode( ',', $user->subscriptions ) );
749 if ( empty( $subscriptions ) || !is_array( $subscriptions ) )
750 continue;
751
752 $subscriptions = join( ',', $subscriptions );
753 $values[] = "('$user->user_id', '_bbp_subscriptions', '$subscriptions')";
754 }
755
756 if ( !count( $values ) ) {
757 $result = __( 'Nothing to remove!', 'bbpress' );
758 return array( 0, sprintf( $statement, $result ) );
759 }
760
761 $sql_delete = "DELETE FROM `$wpdb->usermeta` WHERE `meta_key` = '_bbp_subscriptions';";
762 if ( is_wp_error( $wpdb->query( $sql_delete ) ) )
763 return array( 4, sprintf( $statement, $result ) );
764
765 $values = array_chunk( $values, 10000 );
766 foreach ( $values as $chunk ) {
767 $chunk = "\n" . join( ",\n", $chunk );
768 $sql_insert = "INSERT INTO `$wpdb->usermeta` (`user_id`, `meta_key`, `meta_value`) VALUES $chunk;";
769 if ( is_wp_error( $wpdb->query( $sql_insert ) ) )
770 return array( 5, sprintf( $statement, $result ) );
771 }
772
773 $result = __( 'Complete!', 'bbpress' );
774 return array( 0, sprintf( $statement, $result ) );
775 }
776
777 /**
778 * Recaches the last post in every topic and forum
779 *
780 * @since bbPress (r3040)
781 *
782 * @uses wpdb::query() To run our recount sql queries
783 * @uses is_wp_error() To check if the executed query returned {@link WP_Error}
784 * @return array An array of the status code and the message
785 */
786 function bbp_recount_rewalk() {
787 global $wpdb;
788
789 $statement = __( 'Recomputing latest post in every topic and forum&hellip; %s', 'bbpress' );
790 $result = __( 'Failed!', 'bbpress' );
791
792 // First, delete everything.
793 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' );" ) ) )
794 return array( 1, sprintf( $statement, $result ) );
795
796 // Next, give all the topics with replies the ID their last reply.
797 if ( is_wp_error( $wpdb->query( "INSERT INTO `$wpdb->postmeta` (`post_id`, `meta_key`, `meta_value`)
798 ( SELECT `topic`.`ID`, '_bbp_last_reply_id', MAX( `reply`.`ID` )
799 FROM `$wpdb->posts` AS `topic` INNER JOIN `$wpdb->posts` AS `reply` ON `topic`.`ID` = `reply`.`post_parent`
800 WHERE `reply`.`post_status` IN ( 'publish' ) AND `topic`.`post_type` = 'topic' AND `reply`.`post_type` = 'reply'
801 GROUP BY `topic`.`ID` );" ) ) )
802 return array( 2, sprintf( $statement, $result ) );
803
804 // For any remaining topics, give a reply ID of 0.
805 if ( is_wp_error( $wpdb->query( "INSERT INTO `$wpdb->postmeta` (`post_id`, `meta_key`, `meta_value`)
806 ( SELECT `ID`, '_bbp_last_reply_id', 0
807 FROM `$wpdb->posts` AS `topic` LEFT JOIN `$wpdb->postmeta` AS `reply`
808 ON `topic`.`ID` = `reply`.`post_id` AND `reply`.`meta_key` = '_bbp_last_reply_id'
809 WHERE `reply`.`meta_id` IS NULL AND `topic`.`post_type` = 'topic' );" ) ) )
810 return array( 3, sprintf( $statement, $result ) );
811
812 // Now we give all the forums with topics the ID their last topic.
813 if ( is_wp_error( $wpdb->query( "INSERT INTO `$wpdb->postmeta` (`post_id`, `meta_key`, `meta_value`)
814 ( SELECT `forum`.`ID`, '_bbp_last_topic_id', `topic`.`ID`
815 FROM `$wpdb->posts` AS `forum` INNER JOIN `$wpdb->posts` AS `topic` ON `forum`.`ID` = `topic`.`post_parent`
816 WHERE `topic`.`post_status` IN ( 'publish' ) AND `forum`.`post_type` = 'forum' AND `topic`.`post_type` = 'topic'
817 GROUP BY `forum`.`ID` );" ) ) )
818 return array( 4, sprintf( $statement, $result ) );
819
820 // For any remaining forums, give a topic ID of 0.
821 if ( is_wp_error( $wpdb->query( "INSERT INTO `$wpdb->postmeta` (`post_id`, `meta_key`, `meta_value`)
822 ( SELECT `ID`, '_bbp_last_topic_id', 0
823 FROM `$wpdb->posts` AS `forum` LEFT JOIN `$wpdb->postmeta` AS `topic`
824 ON `forum`.`ID` = `topic`.`post_id` AND `topic`.`meta_key` = '_bbp_last_topic_id'
825 WHERE `topic`.`meta_id` IS NULL AND `forum`.`post_type` = 'forum' );" ) ) )
826 return array( 5, sprintf( $statement, $result ) );
827
828 // After that, we give all the topics with replies the ID their last reply (again, this time for a different reason).
829 if ( is_wp_error( $wpdb->query( "INSERT INTO `$wpdb->postmeta` (`post_id`, `meta_key`, `meta_value`)
830 ( SELECT `topic`.`ID`, '_bbp_last_active_id', MAX( `reply`.`ID` )
831 FROM `$wpdb->posts` AS `topic` INNER JOIN `$wpdb->posts` AS `reply` ON `topic`.`ID` = `reply`.`post_parent`
832 WHERE `reply`.`post_status` IN ( 'publish' ) AND `topic`.`post_type` = 'topic' AND `reply`.`post_type` = 'reply'
833 GROUP BY `topic`.`ID` );" ) ) )
834 return array( 6, sprintf( $statement, $result ) );
835
836 // For any remaining topics, give a reply ID of themself.
837 if ( is_wp_error( $wpdb->query( "INSERT INTO `$wpdb->postmeta` (`post_id`, `meta_key`, `meta_value`)
838 ( SELECT `ID`, '_bbp_last_active_id', `ID`
839 FROM `$wpdb->posts` AS `topic` LEFT JOIN `$wpdb->postmeta` AS `reply`
840 ON `topic`.`ID` = `reply`.`post_id` AND `reply`.`meta_key` = '_bbp_last_active_id'
841 WHERE `reply`.`meta_id` IS NULL AND `topic`.`post_type` = 'topic' );" ) ) )
842 return array( 7, sprintf( $statement, $result ) );
843
844 // Give topics with replies their last update time.
845 if ( is_wp_error( $wpdb->query( "INSERT INTO `$wpdb->postmeta` (`post_id`, `meta_key`, `meta_value`)
846 ( SELECT `topic`.`ID`, '_bbp_last_active_time', MAX( `reply`.`post_date` )
847 FROM `$wpdb->posts` AS `topic` INNER JOIN `$wpdb->posts` AS `reply` ON `topic`.`ID` = `reply`.`post_parent`
848 WHERE `reply`.`post_status` IN ( 'publish' ) AND `topic`.`post_type` = 'topic' AND `reply`.`post_type` = 'reply'
849 GROUP BY `topic`.`ID` );" ) ) )
850 return array( 8, sprintf( $statement, $result ) );
851
852 // Give topics without replies their last update time.
853 if ( is_wp_error( $wpdb->query( "INSERT INTO `$wpdb->postmeta` (`post_id`, `meta_key`, `meta_value`)
854 ( SELECT `ID`, '_bbp_last_active_time', `post_date`
855 FROM `$wpdb->posts` AS `topic` LEFT JOIN `$wpdb->postmeta` AS `reply`
856 ON `topic`.`ID` = `reply`.`post_id` AND `reply`.`meta_key` = '_bbp_last_active_time'
857 WHERE `reply`.`meta_id` IS NULL AND `topic`.`post_type` = 'topic' );" ) ) )
858 return array( 9, sprintf( $statement, $result ) );
859
860 // Forums need to know what their last active item is as well. Now it gets a bit more complex to do in the database.
861 $forums = $wpdb->get_col( "SELECT `ID` FROM `$wpdb->posts` WHERE `post_type` = 'forum';" );
862 if ( is_wp_error( $forums ) )
863 return array( 10, sprintf( $statement, $result ) );
864
865 foreach ( $forums as $forum ) {
866 bbp_update_forum_last_active_id( $forum );
867 bbp_update_forum_last_active_time( $forum );
868 }
869
870 $result = __( 'Complete!', 'bbpress' );
871 return array( 0, sprintf( $statement, $result ) );
872 }
873
874 ?>
875