PluginProbe
bbPress / 2.0.3
bbPress v2.0.3
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
bbpress / bbp-admin / bbp-functions.php

bbp-functions.php in bbPress 2.0.3, at bbp-admin/bbp-functions.php

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