PluginProbe
bbPress / 2.0-rc-2
bbPress v2.0-rc-2
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-rc-2, at bbp-admin/bbp-functions.php

932 lines 34.1 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 // Exit 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 bbpress' );
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 * Assemble 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, $bbp;
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 // Post types and status
191 $tpt = bbp_get_topic_post_type();
192 $rpt = bbp_get_reply_post_type();
193 $pps = 'publish';
194 $cps = $bbp->closed_status_id;
195
196 $sql = "INSERT INTO `{$wpdb->postmeta}` (`post_id`, `meta_key`, `meta_value`) (
197 SELECT `topics`.`ID` AS `post_id`, '_bbp_reply_count' AS `meta_key`, COUNT(`replies`.`ID`) As `meta_value`
198 FROM `{$wpdb->posts}` AS `topics`
199 LEFT JOIN `{$wpdb->posts}` as `replies`
200 ON `replies`.`post_parent` = `topics`.`ID`
201 AND `replies`.`post_status` = '{$pps}'
202 AND `replies`.`post_type` = '{$rpt}'
203 WHERE `topics`.`post_type` = '{$tpt}'
204 AND `topics`.`post_status` IN ( '{$pps}', '{$cps}' )
205 GROUP BY `topics`.`ID`);";
206
207 if ( is_wp_error( $wpdb->query( $sql ) ) )
208 return array( 2, sprintf( $statement, $result ) );
209
210 $result = __( 'Complete!', 'bbpress' );
211 return array( 0, sprintf( $statement, $result ) );
212 }
213
214 /**
215 * Recount topic voices
216 *
217 * @since bbPress (r2613)
218 *
219 * @uses bbp_get_reply_post_type() To get the reply post type
220 * @uses wpdb::query() To run our recount sql queries
221 * @uses is_wp_error() To check if the executed query returned {@link WP_Error}
222 * @return array An array of the status code and the message
223 */
224 function bbp_recount_topic_voices() {
225 global $wpdb, $bbp;
226
227 $statement = __( 'Counting the number of voices in each topic&hellip; %s', 'bbpress' );
228 $result = __( 'Failed!', 'bbpress' );
229
230 $sql_delete = "DELETE FROM `{$wpdb->postmeta}` WHERE `meta_key` = '_bbp_voice_count';";
231 if ( is_wp_error( $wpdb->query( $sql_delete ) ) )
232 return array( 1, sprintf( $statement, $result ) );
233
234 // Post types and status
235 $tpt = bbp_get_topic_post_type();
236 $rpt = bbp_get_reply_post_type();
237 $pps = 'publish';
238 $cps = $bbp->closed_status_id;
239
240 $sql = "INSERT INTO `{$wpdb->postmeta}` (`post_id`, `meta_key`, `meta_value`) (
241 SELECT `postmeta`.`meta_value`, '_bbp_voice_count', COUNT(DISTINCT `post_author`) as `meta_value`
242 FROM `{$wpdb->posts}` AS `posts`
243 LEFT JOIN `{$wpdb->postmeta}` AS `postmeta`
244 ON `posts`.`ID` = `postmeta`.`post_id`
245 AND `postmeta`.`meta_key` = '_bbp_topic_id'
246 WHERE `posts`.`post_type` IN ( '{$tpt}', '{$rpt}' )
247 AND `posts`.`post_status` IN ( '{$pps}', '{$cps}' )
248 AND `posts`.`post_author` != '0'
249 GROUP BY `postmeta`.`meta_value`);";
250
251 if ( is_wp_error( $wpdb->query( $sql ) ) )
252 return array( 2, sprintf( $statement, $result ) );
253
254 $result = __( 'Complete!', 'bbpress' );
255 return array( 0, sprintf( $statement, $result ) );
256 }
257
258 /**
259 * Recount topic hidden replies (spammed/trashed)
260 *
261 * @since bbPress (r2747)
262 *
263 * @uses wpdb::query() To run our recount sql queries
264 * @uses is_wp_error() To check if the executed query returned {@link WP_Error}
265 * @return array An array of the status code and the message
266 */
267 function bbp_recount_topic_hidden_replies() {
268 global $wpdb, $bbp;
269
270 $statement = __( 'Counting the number of spammed and trashed replies in each topic&hellip; %s', 'bbpress' );
271 $result = __( 'Failed!', 'bbpress' );
272
273 $sql_delete = "DELETE FROM `{$wpdb->postmeta}` WHERE `meta_key` = '_bbp_reply_count_hidden';";
274 if ( is_wp_error( $wpdb->query( $sql_delete ) ) )
275 return array( 1, sprintf( $statement, $result ) );
276
277 $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( 'trash', $bbp->spam_status_id ) ) . "') GROUP BY `post_parent`);";
278 if ( is_wp_error( $wpdb->query( $sql ) ) )
279 return array( 2, sprintf( $statement, $result ) );
280
281 $result = __( 'Complete!', 'bbpress' );
282 return array( 0, sprintf( $statement, $result ) );
283 }
284
285 /**
286 * Recount forum topics
287 *
288 * @since bbPress (r2613)
289 *
290 * @uses wpdb::query() To run our recount sql queries
291 * @uses is_wp_error() To check if the executed query returned {@link WP_Error}
292 * @uses bbp_get_forum_post_type() To get the forum post type
293 * @uses get_posts() To get the forums
294 * @uses bbp_update_forum_topic_count() To update the forum topic count
295 * @return array An array of the status code and the message
296 */
297 function bbp_recount_forum_topics() {
298 global $wpdb;
299
300 $statement = __( 'Counting the number of topics in each forum&hellip; %s', 'bbpress' );
301 $result = __( 'Failed!', 'bbpress' );
302
303 $sql_delete = "DELETE FROM {$wpdb->postmeta} WHERE meta_key IN ( '_bbp_topic_count', '_bbp_total_topic_count' );";
304 if ( is_wp_error( $wpdb->query( $sql_delete ) ) )
305 return array( 1, sprintf( $statement, $result ) );
306
307 if ( $forums = get_posts( array( 'post_type' => bbp_get_forum_post_type(), 'numberposts' => -1 ) ) ) {
308 foreach( $forums as $forum ) {
309 bbp_update_forum_topic_count( $forum->ID );
310 }
311 } else {
312 return array( 2, sprintf( $statement, $result ) );
313 }
314
315 $result = __( 'Complete!', 'bbpress' );
316 return array( 0, sprintf( $statement, $result ) );
317 }
318
319 /**
320 * Recount forum replies
321 *
322 * @since bbPress (r2613)
323 *
324 * @uses wpdb::query() To run our recount sql queries
325 * @uses is_wp_error() To check if the executed query returned {@link WP_Error}
326 * @uses bbp_get_forum_post_type() To get the forum post type
327 * @uses get_posts() To get the forums
328 * @uses bbp_update_forum_reply_count() To update the forum reply count
329 * @return array An array of the status code and the message
330 */
331 function bbp_recount_forum_replies() {
332 global $wpdb;
333
334 $statement = __( 'Counting the number of replies in each forum&hellip; %s', 'bbpress' );
335 $result = __( 'Failed!', 'bbpress' );
336
337 $sql_delete = "DELETE FROM `{$wpdb->postmeta}` WHERE `meta_key` IN ( '_bbp_reply_count', '_bbp_total_reply_count' );";
338 if ( is_wp_error( $wpdb->query( $sql_delete ) ) )
339 return array( 1, sprintf( $statement, $result ) );
340
341 if ( $forums = get_posts( array( 'post_type' => bbp_get_forum_post_type(), 'numberposts' => -1 ) ) ) {
342 foreach( $forums as $forum ) {
343 bbp_update_forum_reply_count( $forum->ID );
344 }
345 } else {
346 return array( 2, sprintf( $statement, $result ) );
347 }
348
349 $result = __( 'Complete!', 'bbpress' );
350 return array( 0, sprintf( $statement, $result ) );
351 }
352
353 /**
354 * Recount topic replied by the users
355 *
356 * @since bbPress (r2613)
357 *
358 * @uses bbp_get_reply_post_type() To get the reply post type
359 * @uses wpdb::query() To run our recount sql queries
360 * @uses is_wp_error() To check if the executed query returned {@link WP_Error}
361 * @return array An array of the status code and the message
362 */
363 function bbp_recount_user_topics_replied() {
364 global $wpdb;
365
366 $statement = __( 'Counting the number of topics to which each user has replied&hellip; %s', 'bbpress' );
367 $result = __( 'Failed!', 'bbpress' );
368
369 $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`;";
370 $insert_rows = $wpdb->get_results( $sql_select );
371
372 if ( is_wp_error( $insert_rows ) )
373 return array( 1, sprintf( $statement, $result ) );
374
375 $insert_values = array();
376 foreach ( $insert_rows as $insert_row )
377 $insert_values[] = "('{$insert_row->post_author}', '_bbp_topics_replied', '{$insert_row->_count}')";
378
379 if ( !count( $insert_values ) )
380 return array( 2, sprintf( $statement, $result ) );
381
382 $sql_delete = "DELETE FROM `{$wpdb->usermeta}` WHERE `meta_key` = '_bbp_topics_replied';";
383 if ( is_wp_error( $wpdb->query( $sql_delete ) ) )
384 return array( 3, sprintf( $statement, $result ) );
385
386 $insert_values = array_chunk( $insert_values, 10000 );
387 foreach ( $insert_values as $chunk ) {
388 $chunk = "\n" . join( ",\n", $chunk );
389 $sql_insert = "INSERT INTO `{$wpdb->usermeta}` (`user_id`, `meta_key`, `meta_value`) VALUES $chunk;";
390
391 if ( is_wp_error( $wpdb->query( $sql_insert ) ) )
392 return array( 4, sprintf( $statement, $result ) );
393 }
394
395 $result = __( 'Complete!', 'bbpress' );
396 return array( 0, sprintf( $statement, $result ) );
397 }
398
399 // This function bypasses the taxonomy API
400 /**
401 * Recount topic tags in each topic
402 *
403 * @since bbPress (r2613)
404 *
405 * @uses wpdb::query() To run our recount sql queries
406 * @uses is_wp_error() To check if the executed query returned {@link WP_Error}
407 * @return array An array of the status code and the message
408 */
409 function bbp_recount_topic_tags() {
410 global $wpdb;
411
412 $statement = __( 'Counting the number of topic tags in each topic&hellip; %s', 'bbpress' );
413 $result = __( 'Failed!', 'bbpress' );
414
415 // // Delete empty tags
416 // $delete = bbp_recount_tag_delete_empty();
417 // if ( $delete[0] > 0 ) {
418 // $result = __( 'Could not delete empty tags.' );
419 // return array( 1, sprintf( $statement, $result ) );
420 // }
421 //
422 // // Get all tags
423 // $sql_terms = "SELECT
424 // `$wpdb->term_relationships`.`object_id`,
425 // `$wpdb->term_taxonomy`.`term_id`
426 // FROM `$wpdb->term_relationships`
427 // JOIN `$wpdb->term_taxonomy`
428 // ON `$wpdb->term_taxonomy`.`term_taxonomy_id` = `$wpdb->term_relationships`.`term_taxonomy_id`
429 // WHERE
430 // `$wpdb->term_taxonomy`.`taxonomy` = 'bb_topic_tag'
431 // ORDER BY
432 // `$wpdb->term_relationships`.`object_id`,
433 // `$wpdb->term_taxonomy`.`term_id`;";
434 //
435 // $terms = $wpdb->get_results( $sql_terms );
436 // if ( is_wp_error( $terms ) || !is_array( $terms ) )
437 // return array( 2, sprintf( $statement, $result ) );
438 //
439 // if ( empty( $terms ) ) {
440 // $result = __( 'No topic tags found.' );
441 // return array( 3, sprintf( $statement, $result ) );
442 // }
443 //
444 // // Count the tags in each topic
445 // $topics = array( );
446 // foreach ( $terms as $term ) {
447 // if ( !isset( $topics[$term->object_id] ) ) {
448 // $topics[$term->object_id] = 1;
449 // } else {
450 // $topics[$term->object_id]++;
451 // }
452 // }
453 //
454 // if ( empty( $topics ) )
455 // return array( 4, sprintf( $statement, $result ) );
456 //
457 // // Build the values to insert into the SQL statement
458 // $values = array( );
459 // foreach ( $topics as $topic_id => $tag_count )
460 // $values[] = '(' . $topic_id . ', ' . $tag_count . ')';
461 //
462 // if ( empty( $values ) )
463 // return array( 5, sprintf( $statement, $result ) );
464 //
465 // // Update the topics with the new tag counts
466 // $values = array_chunk( $values, 10000 );
467 // foreach ( $values as $chunk ) {
468 // $sql = "INSERT INTO `$wpdb->topics` (`topic_id`, `tag_count`) VALUES " . implode( ", ", $chunk ) . " ON DUPLICATE KEY UPDATE `tag_count` = VALUES(`tag_count`);";
469 // if ( is_wp_error( $wpdb->query( $sql ) ) ) {
470 // return array( 6, sprintf( $statement, $result ) );
471 // }
472 // }
473 //
474 // $result = __( 'Complete!', 'bbpress' );
475 return array( 0, sprintf( $statement, $result ) );
476 }
477
478 // This function bypasses the taxonomy API
479 /**
480 * Recount the number of topics in each topic tag
481 *
482 * @since bbPress (r2613)
483 *
484 * @uses wpdb::query() To run our recount sql queries
485 * @uses is_wp_error() To check if the executed query returned {@link WP_Error}
486 * @return array An array of the status code and the message
487 */
488 function bbp_recount_tag_topics() {
489 global $wpdb;
490
491 $statement = __( 'Counting the number of topics in each topic tag&hellip; %s', 'bbpress' );
492 $result = __( 'Failed!', 'bbpress' );
493
494 // // Delete empty tags
495 // $delete = bbp_recount_tag_delete_empty();
496 // if ( $delete[0] > 0 ) {
497 // $result = __( 'Could not delete empty tags.' );
498 // return array( 1, sprintf( $statement, $result ) );
499 // }
500 //
501 // // Get all tags
502 // $sql_terms = "SELECT
503 // `$wpdb->term_taxonomy`.`term_taxonomy_id`,
504 // `$wpdb->term_relationships`.`object_id`
505 // FROM `$wpdb->term_relationships`
506 // JOIN `$wpdb->term_taxonomy`
507 // ON `$wpdb->term_taxonomy`.`term_taxonomy_id` = `$wpdb->term_relationships`.`term_taxonomy_id`
508 // WHERE
509 // `$wpdb->term_taxonomy`.`taxonomy` = 'bb_topic_tag'
510 // ORDER BY
511 // `$wpdb->term_taxonomy`.`term_taxonomy_id`,
512 // `$wpdb->term_relationships`.`object_id`;";
513 //
514 // $terms = $wpdb->get_results( $sql_terms );
515 // if ( is_wp_error( $terms ) || !is_array( $terms ) )
516 // return array( 2, sprintf( $statement, $result ) );
517 //
518 // if ( empty( $terms ) ) {
519 // $result = __( 'No topic tags found.', 'bbpress' );
520 // return array( 3, sprintf( $statement, $result ) );
521 // }
522 //
523 // // Count the topics in each tag
524 // $tags = array( );
525 // foreach ( $terms as $term ) {
526 // if ( !isset( $tags[$term->term_taxonomy_id] ) ) {
527 // $tags[$term->term_taxonomy_id] = 1;
528 // } else {
529 // $tags[$term->term_taxonomy_id]++;
530 // }
531 // }
532 //
533 // if ( empty( $tags ) )
534 // return array( 4, sprintf( $statement, $result ) );
535 //
536 // // Build the values to insert into the SQL statement
537 // $values = array( );
538 // foreach ( $tags as $term_taxonomy_id => $count )
539 // $values[] = '(' . $term_taxonomy_id . ', ' . $count . ')';
540 //
541 // if ( empty( $values ) )
542 // return array( 5, sprintf( $statement, $result ) );
543 //
544 // // Update the terms with the new tag counts
545 // $values = array_chunk( $values, 10000 );
546 // foreach ( $values as $chunk ) {
547 // $sql = "INSERT INTO `$wpdb->term_taxonomy` (`term_taxonomy_id`, `count`) VALUES " . implode( ", ", $chunk ) . " ON DUPLICATE KEY UPDATE `count` = VALUES(`count`);";
548 // if ( is_wp_error( $wpdb->query( $sql ) ) ) {
549 // return array( 6, sprintf( $statement, $result ) );
550 // }
551 // }
552 //
553 // if ( $return_boolean )
554 // return true;
555 //
556 // $result = __( 'Complete!', 'bbpress' );
557 return array( 0, sprintf( $statement, $result ) );
558 }
559
560 // This function bypasses the taxonomy API
561 /**
562 * Recount topic tags with no topics
563 *
564 * @since bbPress (r2613)
565 *
566 * @uses wpdb::query() To run our recount sql queries
567 * @uses is_wp_error() To check if the executed query returned {@link WP_Error}
568 * @return array An array of the status code and the message
569 */
570 function bbp_recount_tag_delete_empty() {
571 global $wpdb;
572
573 $statement = __( 'Deleting topic tags with no topics&hellip; %s', 'bbpress' );
574 $result = __( 'Failed!', 'bbpress' );
575
576 // static $run_once;
577 // if ( isset( $run_once ) ) {
578 // if ( $run_once > 0 ) {
579 // $exit = sprintf( __( 'failure (returned code %s)', 'bbpress' ), $run_once );
580 // } else {
581 // $exit = __( 'success', 'bbpress' );
582 // }
583 // $result = sprintf( __( 'Already run with %s.', 'bbpress' ), $exit );
584 // return array( $run_once, sprintf( $statement, $result ) );
585 // }
586 //
587 // // Get all topic ids
588 // $sql_topics = "SELECT `topic_id` FROM $wpdb->topics ORDER BY `topic_id`;";
589 // $topics = $wpdb->get_results( $sql_topics );
590 // if ( is_wp_error( $topics ) ) {
591 // $result = __( 'No topics found.', 'bbpress' );
592 // $run_once = 1;
593 // return array( 1, sprintf( $statement, $result ) );
594 // }
595 //
596 // $topic_ids = array( );
597 //
598 // foreach ( $topics as $topic )
599 // $topic_ids[] = $topic->topic_id;
600 //
601 // // Get all topic tag term relationships without a valid topic id
602 // $in_topic_ids = implode( ', ', $topic_ids );
603 // $sql_bad_term_relationships = "SELECT
604 // `$wpdb->term_taxonomy`.`term_taxonomy_id`,
605 // `$wpdb->term_taxonomy`.`term_id`,
606 // `$wpdb->term_relationships`.`object_id`
607 // FROM `$wpdb->term_relationships`
608 // JOIN `$wpdb->term_taxonomy`
609 // ON `$wpdb->term_taxonomy`.`term_taxonomy_id` = `$wpdb->term_relationships`.`term_taxonomy_id`
610 // WHERE
611 // `$wpdb->term_taxonomy`.`taxonomy` = 'bb_topic_tag' AND
612 // `$wpdb->term_relationships`.`object_id` NOT IN ($in_topic_ids)
613 // ORDER BY
614 // `$wpdb->term_relationships`.`object_id`,
615 // `$wpdb->term_taxonomy`.`term_id`,
616 // `$wpdb->term_taxonomy`.`term_taxonomy_id`;";
617 //
618 // $bad_term_relationships = $wpdb->get_results( $sql_bad_term_relationships );
619 // if ( is_wp_error( $bad_term_relationships ) || !is_array( $bad_term_relationships ) ) {
620 // $run_once = 2;
621 // return array( 2, sprintf( $statement, $result ) );
622 // }
623 //
624 // // Delete those bad term relationships
625 // if ( !empty( $bad_term_relationships ) ) {
626 // $values = array( );
627 // foreach ( $bad_term_relationships as $bad_term_relationship ) {
628 // $values[] = '(`object_id` = ' . $bad_term_relationship->object_id . ' AND `term_taxonomy_id` = ' . $bad_term_relationship->term_taxonomy_id . ')';
629 // }
630 // if ( !empty( $values ) ) {
631 // $values = join( ' OR ', $values );
632 // $sql_bad_term_relationships_delete = "DELETE
633 // FROM `$wpdb->term_relationships`
634 // WHERE $values;";
635 // if ( is_wp_error( $wpdb->query( $sql_bad_term_relationships_delete ) ) ) {
636 // $run_once = 3;
637 // return array( 3, sprintf( $statement, $result ) );
638 // }
639 // }
640 // }
641 //
642 // // Now get all term taxonomy ids with term relationships
643 // $sql_term_relationships = "SELECT `term_taxonomy_id` FROM $wpdb->term_relationships ORDER BY `term_taxonomy_id`;";
644 // $term_taxonomy_ids = $wpdb->get_col( $sql_term_relationships );
645 // if ( is_wp_error( $term_taxonomy_ids ) ) {
646 // $run_once = 4;
647 // return array( 4, sprintf( $statement, $result ) );
648 // }
649 // $term_taxonomy_ids = array_unique( $term_taxonomy_ids );
650 //
651 // // Delete topic tags that don't have any term relationships
652 // if ( !empty( $term_taxonomy_ids ) ) {
653 // $in_term_taxonomy_ids = implode( ', ', $term_taxonomy_ids );
654 // $sql_delete_term_relationships = "DELETE
655 // FROM $wpdb->term_taxonomy
656 // WHERE
657 // `taxonomy` = 'bb_topic_tag' AND
658 // `term_taxonomy_id` NOT IN ($in_term_taxonomy_ids);";
659 // if ( is_wp_error( $wpdb->query( $sql_delete_term_relationships ) ) ) {
660 // $run_once = 5;
661 // return array( 5, sprintf( $statement, $result ) );
662 // }
663 // }
664 //
665 // // Get all valid term ids
666 // $sql_terms = "SELECT `term_id` FROM $wpdb->term_taxonomy ORDER BY `term_id`;";
667 // $term_ids = $wpdb->get_col( $sql_terms );
668 // if ( is_wp_error( $term_ids ) ) {
669 // $run_once = 6;
670 // return array( 6, sprintf( $statement, $result ) );
671 // }
672 // $term_ids = array_unique( $term_ids );
673 //
674 // // Delete terms that don't have any associated term taxonomies
675 // if ( !empty( $term_ids ) ) {
676 // $in_term_ids = implode( ', ', $term_ids );
677 // $sql_delete_terms = "DELETE
678 // FROM $wpdb->terms
679 // WHERE
680 // `term_id` NOT IN ($in_term_ids);";
681 // if ( is_wp_error( $wpdb->query( $sql_delete_terms ) ) ) {
682 // $run_once = 7;
683 // return array( 7, sprintf( $statement, $result ) );
684 // }
685 // }
686 //
687 // $result = __( 'Complete!', 'bbpress' );
688 // $run_once = 0;
689 return array( 0, sprintf( $statement, $result ) );
690 }
691
692 /**
693 * Clean the users' favorites
694 *
695 * @since bbPress (r2613)
696 *
697 * @uses bbp_get_topic_post_type() To get the topic post type
698 * @uses wpdb::query() To run our recount sql queries
699 * @uses is_wp_error() To check if the executed query returned {@link WP_Error}
700 * @return array An array of the status code and the message
701 */
702 function bbp_recount_clean_favorites() {
703 global $wpdb;
704
705 $statement = __( 'Removing trashed topics from user favorites&hellip; %s', 'bbpress' );
706 $result = __( 'Failed!', 'bbpress' );
707
708 $users = $wpdb->get_results( "SELECT `user_id`, `meta_value` AS `favorites` FROM `$wpdb->usermeta` WHERE `meta_key` = '_bbp_favorites';" );
709 if ( is_wp_error( $users ) )
710 return array( 1, sprintf( $statement, $result ) );
711
712 $topics = $wpdb->get_col( "SELECT `ID` FROM `$wpdb->posts` WHERE `post_type` = '" . bbp_get_topic_post_type() . "' AND `post_status` = 'publish';" );
713
714 if ( is_wp_error( $topics ) )
715 return array( 2, sprintf( $statement, $result ) );
716
717 $values = array();
718 foreach ( $users as $user ) {
719 if ( empty( $user->favorites ) || !is_string( $user->favorites ) )
720 continue;
721
722 $favorites = array_intersect( $topics, (array) explode( ',', $user->favorites ) );
723 if ( empty( $favorites ) || !is_array( $favorites ) )
724 continue;
725
726 $favorites = join( ',', $favorites );
727 $values[] = "('$user->user_id', '_bbp_favorites', '$favorites')";
728 }
729
730 if ( !count( $values ) ) {
731 $result = __( 'Nothing to remove!', 'bbpress' );
732 return array( 0, sprintf( $statement, $result ) );
733 }
734
735 $sql_delete = "DELETE FROM `$wpdb->usermeta` WHERE `meta_key` = '_bbp_favorites';";
736 if ( is_wp_error( $wpdb->query( $sql_delete ) ) )
737 return array( 4, sprintf( $statement, $result ) );
738
739 $values = array_chunk( $values, 10000 );
740 foreach ( $values as $chunk ) {
741 $chunk = "\n" . join( ",\n", $chunk );
742 $sql_insert = "INSERT INTO `$wpdb->usermeta` (`user_id`, `meta_key`, `meta_value`) VALUES $chunk;";
743 if ( is_wp_error( $wpdb->query( $sql_insert ) ) )
744 return array( 5, sprintf( $statement, $result ) );
745 }
746
747 $result = __( 'Complete!', 'bbpress' );
748 return array( 0, sprintf( $statement, $result ) );
749 }
750
751 /**
752 * Clean the users' subscriptions
753 *
754 * @since bbPress (r2668)
755 *
756 * @uses bbp_get_topic_post_type() To get the topic post type
757 * @uses wpdb::query() To run our recount sql queries
758 * @uses is_wp_error() To check if the executed query returned {@link WP_Error}
759 * @return array An array of the status code and the message
760 */
761 function bbp_recount_clean_subscriptions() {
762 global $wpdb;
763
764 $statement = __( 'Removing trashed topics from user subscriptions&hellip; %s', 'bbpress' );
765 $result = __( 'Failed!', 'bbpress' );
766
767 $users = $wpdb->get_results( "SELECT `user_id`, `meta_value` AS `subscriptions` FROM `$wpdb->usermeta` WHERE `meta_key` = '_bbp_subscriptions';" );
768 if ( is_wp_error( $users ) )
769 return array( 1, sprintf( $statement, $result ) );
770
771 $topics = $wpdb->get_col( "SELECT `ID` FROM `$wpdb->posts` WHERE `post_type` = '" . bbp_get_topic_post_type() . "' AND `post_status` = 'publish';" );
772 if ( is_wp_error( $topics ) )
773 return array( 2, sprintf( $statement, $result ) );
774
775 $values = array();
776 foreach ( $users as $user ) {
777 if ( empty( $user->subscriptions ) || !is_string( $user->subscriptions ) )
778 continue;
779
780 $subscriptions = array_intersect( $topics, (array) explode( ',', $user->subscriptions ) );
781 if ( empty( $subscriptions ) || !is_array( $subscriptions ) )
782 continue;
783
784 $subscriptions = join( ',', $subscriptions );
785 $values[] = "('$user->user_id', '_bbp_subscriptions', '$subscriptions')";
786 }
787
788 if ( !count( $values ) ) {
789 $result = __( 'Nothing to remove!', 'bbpress' );
790 return array( 0, sprintf( $statement, $result ) );
791 }
792
793 $sql_delete = "DELETE FROM `$wpdb->usermeta` WHERE `meta_key` = '_bbp_subscriptions';";
794 if ( is_wp_error( $wpdb->query( $sql_delete ) ) )
795 return array( 4, sprintf( $statement, $result ) );
796
797 $values = array_chunk( $values, 10000 );
798 foreach ( $values as $chunk ) {
799 $chunk = "\n" . join( ",\n", $chunk );
800 $sql_insert = "INSERT INTO `$wpdb->usermeta` (`user_id`, `meta_key`, `meta_value`) VALUES $chunk;";
801 if ( is_wp_error( $wpdb->query( $sql_insert ) ) )
802 return array( 5, sprintf( $statement, $result ) );
803 }
804
805 $result = __( 'Complete!', 'bbpress' );
806 return array( 0, sprintf( $statement, $result ) );
807 }
808
809 /**
810 * Recaches the last post in every topic and forum
811 *
812 * @since bbPress (r3040)
813 *
814 * @uses wpdb::query() To run our recount sql queries
815 * @uses is_wp_error() To check if the executed query returned {@link WP_Error}
816 * @return array An array of the status code and the message
817 */
818 function bbp_recount_rewalk() {
819 global $wpdb;
820
821 $statement = __( 'Recomputing latest post in every topic and forum&hellip; %s', 'bbpress' );
822 $result = __( 'Failed!', 'bbpress' );
823
824 // First, delete everything.
825 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' );" ) ) )
826 return array( 1, sprintf( $statement, $result ) );
827
828 // Next, give all the topics with replies the ID their last reply.
829 if ( is_wp_error( $wpdb->query( "INSERT INTO `$wpdb->postmeta` (`post_id`, `meta_key`, `meta_value`)
830 ( SELECT `topic`.`ID`, '_bbp_last_reply_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( 2, sprintf( $statement, $result ) );
835
836 // For any remaining topics, give a reply ID of 0.
837 if ( is_wp_error( $wpdb->query( "INSERT INTO `$wpdb->postmeta` (`post_id`, `meta_key`, `meta_value`)
838 ( SELECT `ID`, '_bbp_last_reply_id', 0
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_reply_id'
841 WHERE `reply`.`meta_id` IS NULL AND `topic`.`post_type` = 'topic' );" ) ) )
842 return array( 3, sprintf( $statement, $result ) );
843
844 // Now we give all the forums with topics the ID their last topic.
845 if ( is_wp_error( $wpdb->query( "INSERT INTO `$wpdb->postmeta` (`post_id`, `meta_key`, `meta_value`)
846 ( SELECT `forum`.`ID`, '_bbp_last_topic_id', `topic`.`ID`
847 FROM `$wpdb->posts` AS `forum` INNER JOIN `$wpdb->posts` AS `topic` ON `forum`.`ID` = `topic`.`post_parent`
848 WHERE `topic`.`post_status` IN ( 'publish' ) AND `forum`.`post_type` = 'forum' AND `topic`.`post_type` = 'topic'
849 GROUP BY `forum`.`ID` );" ) ) )
850 return array( 4, sprintf( $statement, $result ) );
851
852 // For any remaining forums, give a topic ID of 0.
853 if ( is_wp_error( $wpdb->query( "INSERT INTO `$wpdb->postmeta` (`post_id`, `meta_key`, `meta_value`)
854 ( SELECT `ID`, '_bbp_last_topic_id', 0
855 FROM `$wpdb->posts` AS `forum` LEFT JOIN `$wpdb->postmeta` AS `topic`
856 ON `forum`.`ID` = `topic`.`post_id` AND `topic`.`meta_key` = '_bbp_last_topic_id'
857 WHERE `topic`.`meta_id` IS NULL AND `forum`.`post_type` = 'forum' );" ) ) )
858 return array( 5, sprintf( $statement, $result ) );
859
860 // After that, we give all the topics with replies the ID their last reply (again, this time for a different reason).
861 if ( is_wp_error( $wpdb->query( "INSERT INTO `$wpdb->postmeta` (`post_id`, `meta_key`, `meta_value`)
862 ( SELECT `topic`.`ID`, '_bbp_last_active_id', MAX( `reply`.`ID` )
863 FROM `$wpdb->posts` AS `topic` INNER JOIN `$wpdb->posts` AS `reply` ON `topic`.`ID` = `reply`.`post_parent`
864 WHERE `reply`.`post_status` IN ( 'publish' ) AND `topic`.`post_type` = 'topic' AND `reply`.`post_type` = 'reply'
865 GROUP BY `topic`.`ID` );" ) ) )
866 return array( 6, sprintf( $statement, $result ) );
867
868 // For any remaining topics, give a reply ID of themself.
869 if ( is_wp_error( $wpdb->query( "INSERT INTO `$wpdb->postmeta` (`post_id`, `meta_key`, `meta_value`)
870 ( SELECT `ID`, '_bbp_last_active_id', `ID`
871 FROM `$wpdb->posts` AS `topic` LEFT JOIN `$wpdb->postmeta` AS `reply`
872 ON `topic`.`ID` = `reply`.`post_id` AND `reply`.`meta_key` = '_bbp_last_active_id'
873 WHERE `reply`.`meta_id` IS NULL AND `topic`.`post_type` = 'topic' );" ) ) )
874 return array( 7, sprintf( $statement, $result ) );
875
876 // Give topics with replies their last update time.
877 if ( is_wp_error( $wpdb->query( "INSERT INTO `$wpdb->postmeta` (`post_id`, `meta_key`, `meta_value`)
878 ( SELECT `topic`.`ID`, '_bbp_last_active_time', MAX( `reply`.`post_date` )
879 FROM `$wpdb->posts` AS `topic` INNER JOIN `$wpdb->posts` AS `reply` ON `topic`.`ID` = `reply`.`post_parent`
880 WHERE `reply`.`post_status` IN ( 'publish' ) AND `topic`.`post_type` = 'topic' AND `reply`.`post_type` = 'reply'
881 GROUP BY `topic`.`ID` );" ) ) )
882 return array( 8, sprintf( $statement, $result ) );
883
884 // Give topics without replies their last update time.
885 if ( is_wp_error( $wpdb->query( "INSERT INTO `$wpdb->postmeta` (`post_id`, `meta_key`, `meta_value`)
886 ( SELECT `ID`, '_bbp_last_active_time', `post_date`
887 FROM `$wpdb->posts` AS `topic` LEFT JOIN `$wpdb->postmeta` AS `reply`
888 ON `topic`.`ID` = `reply`.`post_id` AND `reply`.`meta_key` = '_bbp_last_active_time'
889 WHERE `reply`.`meta_id` IS NULL AND `topic`.`post_type` = 'topic' );" ) ) )
890 return array( 9, sprintf( $statement, $result ) );
891
892 // Forums need to know what their last active item is as well. Now it gets a bit more complex to do in the database.
893 $forums = $wpdb->get_col( "SELECT `ID` FROM `$wpdb->posts` WHERE `post_type` = 'forum' and `post_status` != 'auto-draft';" );
894 if ( is_wp_error( $forums ) )
895 return array( 10, sprintf( $statement, $result ) );
896
897 // Loop through each forum and update them
898 foreach ( $forums as $forum_id )
899 bbp_update_forum( array( 'forum_id' => $forum_id ) );
900
901 // Complete results
902 $result = __( 'Complete!', 'bbpress' );
903 return array( 0, sprintf( $statement, $result ) );
904 }
905
906 /**
907 * Filter sample permalinks so that certain languages display properly.
908 *
909 * @since bbPress (r3336)
910 *
911 * @param string $post_link Custom post type permalink
912 * @param object $post Post data object
913 * @param bool $leavename Optional, defaults to false. Whether to keep post name or page name.
914 * @param bool $sample Optional, defaults to false. Is it a sample permalink.
915 *
916 * @uses is_admin() To make sure we're on an admin page
917 * @uses bbp_is_custom_post_type() To get the forum post type
918 *
919 * @return string The custom post type permalink
920 */
921 function bbp_filter_sample_permalink( $post_link, $post, $leavename, $sample ) {
922
923 // Bail if not on an admin page and not getting a sample permalink
924 if ( !empty( $sample ) && is_admin() && bbp_is_custom_post_type() )
925 return urldecode( $post_link );
926
927 // Return post link
928 return $post_link;
929 }
930
931 ?>
932