[ Index ] |
PHP Cross Reference of BBPress |
[Summary view] [Print] [Text view]
1 <?php 2 3 /** 4 * bbPress Admin Repair Page 5 * 6 * @package bbPress 7 * @subpackage Administration 8 */ 9 10 // Exit if accessed directly 11 defined( 'ABSPATH' ) || exit; 12 13 /** 14 * Admin repair page 15 * 16 * @since 2.0.0 bbPress (r2613) Converted from bbPress 1.2 17 * @since 2.6.0 bbPress (r5885) Upgraded to list-table UI 18 * 19 * @todo Use a real list table 20 * 21 */ 22 function bbp_admin_repair_page() { 23 24 // Get the registered repair tools 25 $tools = bbp_admin_repair_list(); 26 27 // Orderby 28 $orderby = ! empty( $_GET['orderby'] ) 29 ? sanitize_key( $_GET['orderby'] ) 30 : 'priority'; 31 32 // Order 33 $order = ! empty( $_GET['order'] ) && in_array( strtolower( $_GET['order'] ), array( 'asc', 'desc' ), true ) 34 ? strtolower( $_GET['order'] ) 35 : 'asc'; 36 37 // New order 38 $new_order = ( 'desc' === $order ) 39 ? 'asc' 40 : 'desc'; ?> 41 42 <div class="wrap"> 43 <h1 class="wp-heading-inline"><?php esc_html_e( 'Forum Tools', 'bbpress' ); ?></h1> 44 <hr class="wp-header-end"> 45 <h2 class="nav-tab-wrapper"><?php bbp_tools_admin_tabs( 'bbp-repair' ); ?></h2> 46 47 <p><?php esc_html_e( 'bbPress keeps track of relationships between forums, topics, replies, topic-tags, favorites, subscriptions, and users. Occasionally these relationships become out of sync, most often after an import or migration. Use the tools below to manually recalculate these relationships.', 'bbpress' ); ?></p> 48 <p class="description"><?php esc_html_e( 'Some of these tools create substantial database overhead. Use caution when running more than 1 repair at a time.', 'bbpress' ); ?></p> 49 50 <?php bbp_admin_repair_tool_status_filters(); ?> 51 52 <form class="settings" method="get" action=""> 53 54 <?php bbp_admin_repair_list_search_form(); ?> 55 56 <input type="hidden" name="page" value="bbp-repair" /> 57 <?php wp_nonce_field( 'bbpress-do-counts' ); ?> 58 59 <div class="tablenav top"> 60 <div class="alignleft actions bulkactions"> 61 <label for="bulk-action-selector-top" class="screen-reader-text"><?php esc_html_e( 'Select bulk action', 'bbpress' ); ?></label> 62 <select name="action" id="bulk-action-selector-top"> 63 <option value="" selected="selected"><?php esc_html_e( 'Bulk Actions', 'bbpress' ); ?></option> 64 <option value="run" class="hide-if-no-js"><?php esc_html_e( 'Run', 'bbpress' ); ?></option> 65 </select> 66 <input type="submit" id="doaction" class="button action" value="<?php esc_attr_e( 'Apply', 'bbpress' ); ?>"> 67 </div> 68 <div class="alignleft actions"> 69 70 <?php bbp_admin_repair_list_components_filter(); ?> 71 72 <input type="submit" name="filter_action" id="components-submit" class="button" value="<?php esc_html_e( 'Filter', 'bbpress' ); ?>"> 73 </div> 74 <br class="clear"> 75 </div> 76 <table class="wp-list-table widefat striped posts"> 77 <thead> 78 <tr> 79 <td id="cb" class="manage-column column-cb check-column"> 80 <label class="screen-reader-text" for="cb-select-all-1"> 81 <?php esc_html_e( 'Select All', 'bbpress' ); ?> 82 </label> 83 <input id="cb-select-all-1" type="checkbox"> 84 </td> 85 <th scope="col" id="description" class="manage-column column-primary column-description sortable <?php echo ( 'priority' === $orderby ) ? esc_attr( $order ) : 'asc'; ?>"> 86 <a href="<?php echo esc_url( bbp_get_admin_repair_tool_page_url( array( 87 'orderby' => 'priority', 88 'order' => $new_order 89 ) ) ); ?>"><span><?php esc_html_e( 'Description', 'bbpress' ); ?></span><span class="sorting-indicator"></span> 90 </a> 91 </th> 92 <th scope="col" id="components" class="manage-column column-components"> 93 <span><?php esc_html_e( 'Components', 'bbpress' ); ?></span> 94 </th> 95 <th scope="col" id="overhead" class="manage-column column-overhead sortable <?php echo ( 'overhead' === $orderby ) ? esc_attr( $order ) : 'asc'; ?>"> 96 <a href="<?php echo esc_url( bbp_get_admin_repair_tool_page_url( array( 97 'orderby' => 'overhead', 98 'order' => $new_order 99 ) ) ); ?>"><span><?php esc_html_e( 'Overhead', 'bbpress' ); ?></span><span class="sorting-indicator"></span> 100 </a> 101 </th> 102 </tr> 103 </thead> 104 105 <tbody id="the-list"> 106 107 <?php if ( ! empty( $tools ) ) : ?> 108 109 <?php foreach ( $tools as $item ) : ?> 110 111 <tr id="bbp-repair-tools" class="inactive"> 112 <th scope="row" class="check-column"> 113 <label class="screen-reader-text" for="<?php echo esc_attr( str_replace( '_', '-', $item['id'] ) ); ?>"></label> 114 <input type="checkbox" name="checked[]" value="<?php echo esc_attr( $item['id'] ); ?>" id="<?php echo esc_attr( str_replace( '_', '-', $item['id'] ) ); ?>"> 115 </th> 116 <td class="bbp-tool-title column-primary column-description" data-colname="<?php esc_html_e( 'Description', 'bbpress' ); ?>"> 117 <strong><?php echo esc_html( $item['title'] ); ?></strong><?php 118 119 // Optional description 120 if ( ! empty( $item['description'] ) ) : 121 echo '<p class="description">' . esc_html( $item['description'] ) . '</p>'; 122 endif; 123 124 ?><div class="row-actions hide-if-no-js"> 125 <span class="run"> 126 <a href="<?php bbp_admin_repair_tool_run_url( $item ); ?>" aria-label="<?php printf( esc_html__( 'Run %s', 'bbpress' ), $item['title'] ); ?>" id="<?php echo esc_attr( $item['id'] ); ?>" ><?php esc_html_e( 'Run', 'bbpress' ); ?></a> 127 </span> 128 </div> 129 <button type="button" class="toggle-row"> 130 <span class="screen-reader-text"><?php esc_html_e( 'Show more details', 'bbpress' ); ?></span> 131 </button> 132 </td> 133 <td class="column-components desc" data-colname="<?php esc_html_e( 'Components', 'bbpress' ); ?>"> 134 <div class="bbp-tool-overhead"> 135 136 <?php echo implode( ', ', bbp_get_admin_repair_tool_components( $item ) ); ?> 137 138 </div> 139 </td> 140 <td class="column-overhead desc" data-colname="<?php esc_html_e( 'Overhead', 'bbpress' ); ?>"> 141 <div class="bbp-tool-overhead"> 142 143 <?php echo implode( ', ', bbp_get_admin_repair_tool_overhead( $item ) ); ?> 144 145 </div> 146 </td> 147 </tr> 148 149 <?php endforeach; ?> 150 151 <?php else : ?> 152 153 <tr> 154 <td colspan="4"> 155 <?php esc_html_e( 'No repair tools match this criteria.', 'bbpress' ); ?> 156 </td> 157 </tr> 158 159 <?php endif; ?> 160 161 </tbody> 162 <tfoot> 163 <tr> 164 <td class="manage-column column-cb check-column"> 165 <label class="screen-reader-text" for="cb-select-all-2"> 166 <?php esc_html_e( 'Select All', 'bbpress' ); ?> 167 </label> 168 <input id="cb-select-all-2" type="checkbox"> 169 </td> 170 <th scope="col" class="manage-column column-primary column-description"><?php esc_html_e( 'Description', 'bbpress' ); ?></th> 171 <th scope="col" class="manage-column column-components"><?php esc_html_e( 'Components', 'bbpress' ); ?></th> 172 <th scope="col" class="manage-column column-overhead"><?php esc_html_e( 'Overhead', 'bbpress' ); ?></th> 173 </tr> 174 </tfoot> 175 </table> 176 <div class="tablenav bottom"> 177 <div class="alignleft actions bulkactions"> 178 <label for="bulk-action-selector-bottom" class="screen-reader-text"><?php esc_html_e( 'Select bulk action', 'bbpress' ); ?></label> 179 <select name="action2" id="bulk-action-selector-bottom"> 180 <option value="" selected="selected"><?php esc_html_e( 'Bulk Actions', 'bbpress' ); ?></option> 181 <option value="run" class="hide-if-no-js"><?php esc_html_e( 'Run', 'bbpress' ); ?></option> 182 </select> 183 <input type="submit" id="doaction2" class="button action" value="<?php esc_attr_e( 'Apply', 'bbpress' ); ?>"> 184 </div> 185 </div> 186 </form> 187 </div> 188 189 <?php 190 } 191 192 /** 193 * Recount topic replies 194 * 195 * @since 2.0.0 bbPress (r2613) 196 * 197 * @return array An array of the status code and the message 198 */ 199 function bbp_admin_repair_topic_reply_count() { 200 201 // Define variables 202 $bbp_db = bbp_db(); 203 $statement = esc_html__( 'Counting the number of replies in each topic… %s', 'bbpress' ); 204 $result = esc_html__( 'Failed!', 'bbpress' ); 205 206 // Post types and status 207 $tpt = bbp_get_topic_post_type(); 208 $rpt = bbp_get_reply_post_type(); 209 $pps = bbp_get_public_status_id(); 210 $cps = bbp_get_closed_status_id(); 211 212 // Delete the meta key _bbp_reply_count for each topic 213 $sql_delete = "DELETE `postmeta` FROM `{$bbp_db->postmeta}` AS `postmeta` 214 LEFT JOIN `{$bbp_db->posts}` AS `posts` ON `posts`.`ID` = `postmeta`.`post_id` 215 WHERE `posts`.`post_type` = '{$tpt}' 216 AND `postmeta`.`meta_key` = '_bbp_reply_count'"; 217 218 if ( is_wp_error( $bbp_db->query( $sql_delete ) ) ) { 219 return array( 1, sprintf( $statement, $result ) ); 220 } 221 222 // Recalculate the meta key _bbp_reply_count for each topic 223 $sql = "INSERT INTO `{$bbp_db->postmeta}` (`post_id`, `meta_key`, `meta_value`) ( 224 SELECT `topics`.`ID` AS `post_id`, '_bbp_reply_count' AS `meta_key`, COUNT(`replies`.`ID`) As `meta_value` 225 FROM `{$bbp_db->posts}` AS `topics` 226 LEFT JOIN `{$bbp_db->posts}` as `replies` 227 ON `replies`.`post_parent` = `topics`.`ID` 228 AND `replies`.`post_status` = '{$pps}' 229 AND `replies`.`post_type` = '{$rpt}' 230 WHERE `topics`.`post_type` = '{$tpt}' 231 AND `topics`.`post_status` IN ( '{$pps}', '{$cps}' ) 232 GROUP BY `topics`.`ID`)"; 233 234 if ( is_wp_error( $bbp_db->query( $sql ) ) ) { 235 return array( 2, sprintf( $statement, $result ) ); 236 } 237 238 return array( 0, sprintf( $statement, esc_html__( 'Complete!', 'bbpress' ) ) ); 239 } 240 241 /** 242 * Recount topic voices 243 * 244 * @since 2.0.0 bbPress (r2613) 245 * 246 * @return array An array of the status code and the message 247 */ 248 function bbp_admin_repair_topic_voice_count() { 249 250 // Define variables 251 $bbp_db = bbp_db(); 252 $statement = esc_html__( 'Counting the number of voices in each topic… %s', 'bbpress' ); 253 $result = esc_html__( 'Failed!', 'bbpress' ); 254 255 $sql_delete = "DELETE FROM {$bbp_db->postmeta} WHERE meta_key IN ('_bbp_voice_count', '_bbp_engagement')"; 256 if ( is_wp_error( $bbp_db->query( $sql_delete ) ) ) { 257 return array( 1, sprintf( $statement, $result ) ); 258 } 259 260 // Post types and status 261 $tpt = bbp_get_topic_post_type(); 262 $rpt = bbp_get_reply_post_type(); 263 $pps = bbp_get_public_status_id(); 264 $cps = bbp_get_closed_status_id(); 265 266 $engagements_sql = $bbp_db->prepare( "INSERT INTO {$bbp_db->postmeta} (post_id, meta_key, meta_value) ( 267 SELECT postmeta.meta_value, '_bbp_engagement', posts.post_author 268 FROM {$bbp_db->posts} AS posts 269 LEFT JOIN {$bbp_db->postmeta} AS postmeta 270 ON posts.ID = postmeta.post_id 271 AND postmeta.meta_key = '_bbp_topic_id' 272 WHERE posts.post_type IN (%s, %s) 273 AND posts.post_status IN (%s, %s) 274 GROUP BY postmeta.meta_value, posts.post_author)", $tpt, $rpt, $pps, $cps ); 275 276 if ( is_wp_error( $bbp_db->query( $engagements_sql ) ) ) { 277 return array( 2, sprintf( $statement, $result ) ); 278 } 279 280 $voice_count_sql = "INSERT INTO {$bbp_db->postmeta} (post_id, meta_key, meta_value) ( 281 SELECT post_id, '_bbp_voice_count', COUNT(DISTINCT meta_value) 282 FROM {$bbp_db->postmeta} 283 WHERE meta_key = '_bbp_engagement' 284 GROUP BY post_id)"; 285 286 if ( is_wp_error( $bbp_db->query( $voice_count_sql ) ) ) { 287 return array( 3, sprintf( $statement, $result ) ); 288 } 289 290 return array( 0, sprintf( $statement, esc_html__( 'Complete!', 'bbpress' ) ) ); 291 } 292 293 /** 294 * Recount non-public replies per topic (pending/spammed/trashed) 295 * 296 * @since 2.0.0 bbPress (r2747) 297 * 298 * @return array An array of the status code and the message 299 */ 300 function bbp_admin_repair_topic_hidden_reply_count() { 301 302 // Define variables 303 $bbp_db = bbp_db(); 304 $statement = esc_html__( 'Counting the number of pending, spammed, and trashed replies in each topic… %s', 'bbpress' ); 305 $result = esc_html__( 'Failed!', 'bbpress' ); 306 307 $sql_delete = "DELETE FROM `{$bbp_db->postmeta}` WHERE `meta_key` = '_bbp_reply_count_hidden'"; 308 if ( is_wp_error( $bbp_db->query( $sql_delete ) ) ) { 309 return array( 1, sprintf( $statement, $result ) ); 310 } 311 312 // Post types and status 313 $rpt = bbp_get_reply_post_type(); 314 $sta = bbp_get_non_public_topic_statuses(); 315 316 // SQL 317 $sql_status = "'" . implode( "','", $sta ) . "'"; 318 319 $sql = "INSERT INTO `{$bbp_db->postmeta}` (`post_id`, `meta_key`, `meta_value`) (SELECT `post_parent`, '_bbp_reply_count_hidden', COUNT(`post_status`) as `meta_value` FROM `{$bbp_db->posts}` WHERE `post_type` = '{$rpt}' AND `post_status` IN ({$sql_status}) GROUP BY `post_parent`)"; 320 if ( is_wp_error( $bbp_db->query( $sql ) ) ) { 321 return array( 2, sprintf( $statement, $result ) ); 322 } 323 324 return array( 0, sprintf( $statement, esc_html__( 'Complete!', 'bbpress' ) ) ); 325 } 326 327 /** 328 * Recount forum topics 329 * 330 * @since 2.0.0 bbPress (r2613) 331 * 332 * @return array An array of the status code and the message 333 */ 334 function bbp_admin_repair_forum_topic_count() { 335 336 // Define variables 337 $bbp_db = bbp_db(); 338 $statement = esc_html__( 'Counting the number of topics in each forum… %s', 'bbpress' ); 339 $result = esc_html__( 'Failed!', 'bbpress' ); 340 341 $sql_delete = "DELETE FROM {$bbp_db->postmeta} WHERE meta_key IN ( '_bbp_topic_count', '_bbp_total_topic_count', '_bbp_topic_count_hidden' )"; 342 if ( is_wp_error( $bbp_db->query( $sql_delete ) ) ) { 343 return array( 1, sprintf( $statement, $result ) ); 344 } 345 346 $forums = get_posts( array( 'post_type' => bbp_get_forum_post_type(), 'numberposts' => -1 ) ); 347 if ( ! empty( $forums ) ) { 348 foreach ( $forums as $forum ) { 349 bbp_update_forum_topic_count( $forum->ID ); 350 bbp_update_forum_topic_count_hidden( $forum->ID ); 351 } 352 } else { 353 return array( 2, sprintf( $statement, $result ) ); 354 } 355 356 return array( 0, sprintf( $statement, esc_html__( 'Complete!', 'bbpress' ) ) ); 357 } 358 359 /** 360 * Recount topic in each topic-tag 361 * 362 * @since 2.6.0 bbPress (r6256) 363 * 364 * @return array An array of the status code and the message 365 */ 366 function bbp_admin_repair_topic_tag_count() { 367 368 // Define variables 369 $statement = esc_html__( 'Counting the number of topics in each topic-tag… %s', 'bbpress' ); 370 $result = esc_html__( 'Failed!', 'bbpress' ); 371 $tax_id = bbp_get_topic_tag_tax_id(); 372 $terms = get_terms( $tax_id, array( 'hide_empty' => false ) ); 373 $tt_ids = wp_list_pluck( $terms, 'term_taxonomy_id' ); 374 $ints = array_map( 'intval', $tt_ids ); 375 $taxonomy = get_taxonomy( $tax_id ); 376 377 // Bail if taxonomy does not exist 378 if ( empty( $taxonomy ) ) { 379 return array( 1, sprintf( $statement, $result ) ); 380 } 381 382 // Custom callback 383 if ( ! empty( $taxonomy->update_count_callback ) ) { 384 385 // Bail if callback is not callable 386 if ( ! is_callable( $taxonomy->update_count_callback ) ) { 387 return array( 1, sprintf( $statement, $result ) ); 388 } 389 390 call_user_func( $taxonomy->update_count_callback, $ints, $taxonomy ); 391 392 // Generic callback fallback 393 } else { 394 _update_post_term_count( $ints, $taxonomy ); 395 } 396 397 // Bust the cache 398 clean_term_cache( $ints, '', false ); 399 400 return array( 0, sprintf( $statement, esc_html__( 'Complete!', 'bbpress' ) ) ); 401 } 402 403 /** 404 * Recount forum replies 405 * 406 * @since 2.0.0 bbPress (r2613) 407 * 408 * @return array An array of the status code and the message 409 */ 410 function bbp_admin_repair_forum_reply_count() { 411 412 // Define variables 413 $bbp_db = bbp_db(); 414 $statement = esc_html__( 'Counting the number of replies in each forum… %s', 'bbpress' ); 415 $result = esc_html__( 'Failed!', 'bbpress' ); 416 417 // Post type 418 $fpt = bbp_get_forum_post_type(); 419 420 // Delete the meta keys _bbp_reply_count and _bbp_total_reply_count for each forum 421 $sql_delete = "DELETE `postmeta` FROM `{$bbp_db->postmeta}` AS `postmeta` 422 LEFT JOIN `{$bbp_db->posts}` AS `posts` ON `posts`.`ID` = `postmeta`.`post_id` 423 WHERE `posts`.`post_type` = '{$fpt}' 424 AND `postmeta`.`meta_key` = '_bbp_reply_count' 425 OR `postmeta`.`meta_key` = '_bbp_total_reply_count'"; 426 427 if ( is_wp_error( $bbp_db->query( $sql_delete ) ) ) { 428 return array( 1, sprintf( $statement, $result ) ); 429 } 430 431 // Recalculate the metas key _bbp_reply_count and _bbp_total_reply_count for each forum 432 $forums = get_posts( array( 'post_type' => bbp_get_forum_post_type(), 'numberposts' => -1 ) ); 433 if ( ! empty( $forums ) ) { 434 foreach ( $forums as $forum ) { 435 bbp_update_forum_reply_count( $forum->ID ); 436 } 437 } else { 438 return array( 2, sprintf( $statement, $result ) ); 439 } 440 441 return array( 0, sprintf( $statement, esc_html__( 'Complete!', 'bbpress' ) ) ); 442 } 443 444 /** 445 * Recount non-public forum replies 446 * 447 * @since 2.6.0 bbPress (r6922) 448 * @since 2.6.0 bbPress (r6932) Rename to match the topic reply recount function 449 * 450 * @return array An array of the status code and the message 451 */ 452 function bbp_admin_repair_forum_hidden_reply_count() { 453 454 // Define variables 455 $bbp_db = bbp_db(); 456 $statement = esc_html__( 'Counting the number of pending, spammed, and trashed replies in each forum… %s', 'bbpress' ); 457 $result = esc_html__( 'Failed!', 'bbpress' ); 458 459 // Post type 460 $fpt = bbp_get_forum_post_type(); 461 462 // Delete the meta keys _bbp_reply_count and _bbp_total_reply_count for each forum 463 $sql_delete = "DELETE `postmeta` FROM `{$bbp_db->postmeta}` AS `postmeta` 464 LEFT JOIN `{$bbp_db->posts}` AS `posts` ON `posts`.`ID` = `postmeta`.`post_id` 465 WHERE `posts`.`post_type` = '{$fpt}' 466 AND `postmeta`.`meta_key` = '_bbp_reply_count_hidden' 467 OR `postmeta`.`meta_key` = '_bbp_total_reply_count_hidden'"; 468 469 if ( is_wp_error( $bbp_db->query( $sql_delete ) ) ) { 470 return array( 1, sprintf( $statement, $result ) ); 471 } 472 473 // Recalculate the metas key _bbp_reply_count and _bbp_total_reply_count for each forum 474 $forums = get_posts( array( 'post_type' => bbp_get_forum_post_type(), 'numberposts' => -1 ) ); 475 if ( ! empty( $forums ) ) { 476 foreach ( $forums as $forum ) { 477 bbp_update_forum_reply_count_hidden( $forum->ID ); 478 } 479 } else { 480 return array( 2, sprintf( $statement, $result ) ); 481 } 482 483 return array( 0, sprintf( $statement, esc_html__( 'Complete!', 'bbpress' ) ) ); 484 } 485 486 /** 487 * Recount topics by the users 488 * 489 * @since 2.1.0 bbPress (r3889) 490 * 491 * @return array An array of the status code and the message 492 */ 493 function bbp_admin_repair_user_topic_count() { 494 495 // Define variables 496 $bbp_db = bbp_db(); 497 $statement = esc_html__( 'Counting the number of topics each user has created… %s', 'bbpress' ); 498 $result = esc_html__( 'Failed!', 'bbpress' ); 499 500 $sql_select = "SELECT `post_author`, COUNT(DISTINCT `ID`) as `_count` FROM `{$bbp_db->posts}` WHERE `post_type` = '" . bbp_get_topic_post_type() . "' AND `post_status` = '" . bbp_get_public_status_id() . "' GROUP BY `post_author`"; 501 $insert_rows = $bbp_db->get_results( $sql_select ); 502 503 if ( is_wp_error( $insert_rows ) ) { 504 return array( 1, sprintf( $statement, $result ) ); 505 } 506 507 $key = $bbp_db->prefix . '_bbp_topic_count'; 508 $insert_values = array(); 509 foreach ( $insert_rows as $insert_row ) { 510 $insert_values[] = "('{$insert_row->post_author}', '{$key}', '{$insert_row->_count}')"; 511 } 512 513 if ( !count( $insert_values ) ) { 514 return array( 2, sprintf( $statement, $result ) ); 515 } 516 517 $sql_delete = "DELETE FROM `{$bbp_db->usermeta}` WHERE `meta_key` = '{$key}'"; 518 if ( is_wp_error( $bbp_db->query( $sql_delete ) ) ) { 519 return array( 3, sprintf( $statement, $result ) ); 520 } 521 522 foreach ( array_chunk( $insert_values, 10000 ) as $chunk ) { 523 $chunk = "\n" . implode( ",\n", $chunk ); 524 $sql_insert = "INSERT INTO `{$bbp_db->usermeta}` (`user_id`, `meta_key`, `meta_value`) VALUES {$chunk}"; 525 526 if ( is_wp_error( $bbp_db->query( $sql_insert ) ) ) { 527 return array( 4, sprintf( $statement, $result ) ); 528 } 529 } 530 531 return array( 0, sprintf( $statement, esc_html__( 'Complete!', 'bbpress' ) ) ); 532 } 533 534 /** 535 * Recount topic replied by the users 536 * 537 * @since 2.0.0 bbPress (r2613) 538 * 539 * @return array An array of the status code and the message 540 */ 541 function bbp_admin_repair_user_reply_count() { 542 543 // Define variables 544 $bbp_db = bbp_db(); 545 $statement = esc_html__( 'Counting the number of topics to which each user has replied… %s', 'bbpress' ); 546 $result = esc_html__( 'Failed!', 'bbpress' ); 547 548 $sql_select = "SELECT `post_author`, COUNT(DISTINCT `ID`) as `_count` FROM `{$bbp_db->posts}` WHERE `post_type` = '" . bbp_get_reply_post_type() . "' AND `post_status` = '" . bbp_get_public_status_id() . "' GROUP BY `post_author`"; 549 $insert_rows = $bbp_db->get_results( $sql_select ); 550 551 if ( is_wp_error( $insert_rows ) ) { 552 return array( 1, sprintf( $statement, $result ) ); 553 } 554 555 $key = $bbp_db->prefix . '_bbp_reply_count'; 556 $insert_values = array(); 557 foreach ( $insert_rows as $insert_row ) { 558 $insert_values[] = "('{$insert_row->post_author}', '{$key}', '{$insert_row->_count}')"; 559 } 560 561 if ( !count( $insert_values ) ) { 562 return array( 2, sprintf( $statement, $result ) ); 563 } 564 565 $sql_delete = "DELETE FROM `{$bbp_db->usermeta}` WHERE `meta_key` = '{$key}'"; 566 if ( is_wp_error( $bbp_db->query( $sql_delete ) ) ) { 567 return array( 3, sprintf( $statement, $result ) ); 568 } 569 570 foreach ( array_chunk( $insert_values, 10000 ) as $chunk ) { 571 $chunk = "\n" . implode( ",\n", $chunk ); 572 $sql_insert = "INSERT INTO `{$bbp_db->usermeta}` (`user_id`, `meta_key`, `meta_value`) VALUES {$chunk}"; 573 574 if ( is_wp_error( $bbp_db->query( $sql_insert ) ) ) { 575 return array( 4, sprintf( $statement, $result ) ); 576 } 577 } 578 579 return array( 0, sprintf( $statement, esc_html__( 'Complete!', 'bbpress' ) ) ); 580 } 581 582 /** 583 * Repair user favorites 584 * 585 * @since 2.0.0 bbPress (r2613) 586 * 587 * @return array An array of the status code and the message 588 */ 589 function bbp_admin_repair_user_favorites() { 590 591 // Define variables 592 $bbp_db = bbp_db(); 593 $statement = esc_html__( 'Removing unpublished topics from user favorites… %s', 'bbpress' ); 594 $result = esc_html__( 'Failed!', 'bbpress' ); 595 596 // Query for users with favorites 597 $key = $bbp_db->prefix . '_bbp_favorites'; 598 $users = $bbp_db->get_results( "SELECT `user_id`, `meta_value` AS `favorites` FROM `{$bbp_db->usermeta}` WHERE `meta_key` = '{$key}'" ); 599 600 if ( is_wp_error( $users ) ) { 601 return array( 1, sprintf( $statement, $result ) ); 602 } 603 604 $topics = $bbp_db->get_col( "SELECT `ID` FROM `{$bbp_db->posts}` WHERE `post_type` = '" . bbp_get_topic_post_type() . "' AND `post_status` = '" . bbp_get_public_status_id() . "'" ); 605 606 if ( is_wp_error( $topics ) ) { 607 return array( 2, sprintf( $statement, $result ) ); 608 } 609 610 $values = array(); 611 foreach ( $users as $user ) { 612 if ( empty( $user->favorites ) || ! is_string( $user->favorites ) ) { 613 continue; 614 } 615 616 $favorites = array_intersect( $topics, explode( ',', $user->favorites ) ); 617 if ( empty( $favorites ) || ! is_array( $favorites ) ) { 618 continue; 619 } 620 621 $favorites_joined = implode( ',', $favorites ); 622 $values[] = "('{$user->user_id}', '{$key}', '{$favorites_joined}')"; 623 624 // Cleanup 625 unset( $favorites, $favorites_joined ); 626 } 627 628 if ( !count( $values ) ) { 629 $result = esc_html__( 'Nothing to remove!', 'bbpress' ); 630 return array( 0, sprintf( $statement, $result ) ); 631 } 632 633 $sql_delete = "DELETE FROM `{$bbp_db->usermeta}` WHERE `meta_key` = '{$key}'"; 634 if ( is_wp_error( $bbp_db->query( $sql_delete ) ) ) { 635 return array( 4, sprintf( $statement, $result ) ); 636 } 637 638 foreach ( array_chunk( $values, 10000 ) as $chunk ) { 639 $chunk = "\n" . implode( ",\n", $chunk ); 640 $sql_insert = "INSERT INTO `{$bbp_db->usermeta}` (`user_id`, `meta_key`, `meta_value`) VALUES {$chunk}"; 641 if ( is_wp_error( $bbp_db->query( $sql_insert ) ) ) { 642 return array( 5, sprintf( $statement, $result ) ); 643 } 644 } 645 646 return array( 0, sprintf( $statement, esc_html__( 'Complete!', 'bbpress' ) ) ); 647 } 648 649 /** 650 * Clean the user topic subscriptions 651 * 652 * @since 2.0.0 bbPress (r2668) 653 * 654 * @return array An array of the status code and the message 655 */ 656 function bbp_admin_repair_user_topic_subscriptions() { 657 658 // Define variables 659 $bbp_db = bbp_db(); 660 $statement = esc_html__( 'Removing trashed topics from user subscriptions… %s', 'bbpress' ); 661 $result = esc_html__( 'Failed!', 'bbpress' ); 662 663 $key = $bbp_db->prefix . '_bbp_subscriptions'; 664 $users = $bbp_db->get_results( "SELECT `user_id`, `meta_value` AS `subscriptions` FROM `{$bbp_db->usermeta}` WHERE `meta_key` = '{$key}'" ); 665 666 if ( is_wp_error( $users ) ) { 667 return array( 1, sprintf( $statement, $result ) ); 668 } 669 670 $topics = $bbp_db->get_col( "SELECT `ID` FROM `{$bbp_db->posts}` WHERE `post_type` = '" . bbp_get_topic_post_type() . "' AND `post_status` = '" . bbp_get_public_status_id() . "'" ); 671 if ( is_wp_error( $topics ) ) { 672 return array( 2, sprintf( $statement, $result ) ); 673 } 674 675 $values = array(); 676 foreach ( $users as $user ) { 677 if ( empty( $user->subscriptions ) || ! is_string( $user->subscriptions ) ) { 678 continue; 679 } 680 681 $subscriptions = array_intersect( $topics, explode( ',', $user->subscriptions ) ); 682 if ( empty( $subscriptions ) || ! is_array( $subscriptions ) ) { 683 continue; 684 } 685 686 $subscriptions_joined = implode( ',', $subscriptions ); 687 $values[] = "('{$user->user_id}', '{$key}', '{$subscriptions_joined}')"; 688 689 // Cleanup 690 unset( $subscriptions, $subscriptions_joined ); 691 } 692 693 if ( !count( $values ) ) { 694 $result = esc_html__( 'Nothing to remove!', 'bbpress' ); 695 return array( 0, sprintf( $statement, $result ) ); 696 } 697 698 $sql_delete = "DELETE FROM `{$bbp_db->usermeta}` WHERE `meta_key` = '{$key}'"; 699 if ( is_wp_error( $bbp_db->query( $sql_delete ) ) ) { 700 return array( 4, sprintf( $statement, $result ) ); 701 } 702 703 foreach ( array_chunk( $values, 10000 ) as $chunk ) { 704 $chunk = "\n" . implode( ",\n", $chunk ); 705 $sql_insert = "INSERT INTO `{$bbp_db->usermeta}` (`user_id`, `meta_key`, `meta_value`) VALUES {$chunk}"; 706 if ( is_wp_error( $bbp_db->query( $sql_insert ) ) ) { 707 return array( 5, sprintf( $statement, $result ) ); 708 } 709 } 710 711 return array( 0, sprintf( $statement, esc_html__( 'Complete!', 'bbpress' ) ) ); 712 } 713 714 /** 715 * Clean the user forum subscriptions 716 * 717 * @since 2.5.0 bbPress (r5155) 718 * 719 * @return array An array of the status code and the message 720 */ 721 function bbp_admin_repair_user_forum_subscriptions() { 722 723 // Define variables 724 $bbp_db = bbp_db(); 725 $statement = esc_html__( 'Removing trashed forums from user subscriptions… %s', 'bbpress' ); 726 $result = esc_html__( 'Failed!', 'bbpress' ); 727 728 $key = $bbp_db->prefix . '_bbp_forum_subscriptions'; 729 $users = $bbp_db->get_results( "SELECT `user_id`, `meta_value` AS `subscriptions` FROM `{$bbp_db->usermeta}` WHERE `meta_key` = '{$key}'" ); 730 731 if ( is_wp_error( $users ) ) { 732 return array( 1, sprintf( $statement, $result ) ); 733 } 734 735 $forums = $bbp_db->get_col( "SELECT `ID` FROM `{$bbp_db->posts}` WHERE `post_type` = '" . bbp_get_forum_post_type() . "' AND `post_status` = '" . bbp_get_public_status_id() . "'" ); 736 if ( is_wp_error( $forums ) ) { 737 return array( 2, sprintf( $statement, $result ) ); 738 } 739 740 $values = array(); 741 foreach ( $users as $user ) { 742 if ( empty( $user->subscriptions ) || ! is_string( $user->subscriptions ) ) { 743 continue; 744 } 745 746 $subscriptions = array_intersect( $forums, explode( ',', $user->subscriptions ) ); 747 if ( empty( $subscriptions ) || ! is_array( $subscriptions ) ) { 748 continue; 749 } 750 751 $subscriptions_joined = implode( ',', $subscriptions ); 752 $values[] = "('{$user->user_id}', '{$key}', '{$subscriptions_joined}')"; 753 754 // Cleanup 755 unset( $subscriptions, $subscriptions_joined ); 756 } 757 758 if ( !count( $values ) ) { 759 $result = esc_html__( 'Nothing to remove!', 'bbpress' ); 760 return array( 0, sprintf( $statement, $result ) ); 761 } 762 763 $sql_delete = "DELETE FROM `{$bbp_db->usermeta}` WHERE `meta_key` = '{$key}'"; 764 if ( is_wp_error( $bbp_db->query( $sql_delete ) ) ) { 765 return array( 4, sprintf( $statement, $result ) ); 766 } 767 768 foreach ( array_chunk( $values, 10000 ) as $chunk ) { 769 $chunk = "\n" . implode( ",\n", $chunk ); 770 $sql_insert = "INSERT INTO `{$bbp_db->usermeta}` (`user_id`, `meta_key`, `meta_value`) VALUES {$chunk}"; 771 if ( is_wp_error( $bbp_db->query( $sql_insert ) ) ) { 772 return array( 5, sprintf( $statement, $result ) ); 773 } 774 } 775 776 return array( 0, sprintf( $statement, esc_html__( 'Complete!', 'bbpress' ) ) ); 777 } 778 779 /** 780 * This repair tool will map each user of the current site to their respective 781 * forums role. By default, Admins will be Key Masters, and every other role 782 * will be the default role defined in Settings > Forums (Participant). 783 * 784 * @since 2.2.0 bbPress (r4340) 785 */ 786 function bbp_admin_repair_user_roles() { 787 788 $statement = esc_html__( 'Remapping forum role for each user on this site… %s', 'bbpress' ); 789 $changed = 0; 790 $role_map = bbp_get_user_role_map(); 791 $default_role = bbp_get_default_role(); 792 793 // Bail if no role map exists 794 if ( empty( $role_map ) ) { 795 return array( 1, sprintf( $statement, esc_html__( 'Failed!', 'bbpress' ) ) ); 796 } 797 798 // Get non-forum roles 799 $blog_roles = array_keys( bbp_get_blog_roles() ); 800 801 // Iterate through each role... 802 foreach ( $blog_roles as $role ) { 803 804 // Reset the offset 805 $offset = 0; 806 807 // If no role map exists, give the default forum role (bbp-participant) 808 $new_role = isset( $role_map[ $role ] ) 809 ? $role_map[ $role ] 810 : $default_role; 811 812 // Get users of this site, limited to 1000 813 while ( $users = get_users( array( 814 'role' => $role, 815 'fields' => 'ID', 816 'number' => 1000, 817 'offset' => $offset 818 ) ) ) { 819 820 // Iterate through each user of $role and try to set it 821 foreach ( (array) $users as $user_id ) { 822 if ( bbp_set_user_role( $user_id, $new_role ) ) { 823 ++$changed; // Keep a count to display at the end 824 } 825 } 826 827 // Bump the offset for the next query iteration 828 $offset = $offset + 1000; 829 } 830 } 831 832 // Reset the offset 833 $offset = 0; 834 $bbp_db = bbp_db(); 835 $cap_key = $bbp_db->get_blog_prefix() . 'capabilities'; 836 837 // Users without roles should be granted the default role, but not on multi- 838 // site installations where not all users get a role by default. 839 if ( ! is_multisite() ) { 840 841 // Get users with missing capabilities on this site, limited to 1000 842 while ( $users = get_users( array( 843 'meta_key' => $cap_key, 844 'meta_compare' => 'NOT EXISTS', 845 'fields' => 'ID', 846 'number' => 1000, 847 'offset' => $offset 848 ) ) ) { 849 850 // Iterate through each user of $role and try to set it 851 foreach ( (array) $users as $user_id ) { 852 if ( bbp_set_user_role( $user_id, $default_role ) ) { 853 ++$changed; // Keep a count to display at the end 854 } 855 } 856 857 // Bump the offset for the next query iteration 858 $offset = $offset + 1000; 859 } 860 861 // On multisite, we'll look for users with an empty capabilities array. 862 // These are users who basically have malformed caps, and we can fix that. 863 } else { 864 865 // Get users with empty capabilities on this site, limited to 1000 866 while ( $users = get_users( array( 867 'meta_key' => $cap_key, 868 'meta_value' => 'a:0:{}', 869 'fields' => 'ID', 870 'number' => 1000, 871 'offset' => $offset 872 ) ) ) { 873 874 // Iterate through each user of $role and try to set it 875 foreach ( (array) $users as $user_id ) { 876 if ( bbp_set_user_role( $user_id, $default_role ) ) { 877 ++$changed; // Keep a count to display at the end 878 } 879 } 880 881 // Bump the offset for the next query iteration 882 $offset = $offset + 1000; 883 } 884 } 885 886 $result = sprintf( esc_html__( 'Complete! %s users updated.', 'bbpress' ), bbp_number_format( $changed ) ); 887 888 return array( 0, sprintf( $statement, $result ) ); 889 } 890 891 /** 892 * Repair the last post in every topic and forum 893 * 894 * @since 2.0.0 bbPress (r3040) 895 * 896 * @return array An array of the status code and the message 897 */ 898 function bbp_admin_repair_freshness() { 899 900 // Define variables 901 $bbp_db = bbp_db(); 902 $statement = esc_html__( 'Recomputing latest post in every topic and forum… %s', 'bbpress' ); 903 $result = esc_html__( 'Failed!', 'bbpress' ); 904 905 // First, delete everything. 906 if ( is_wp_error( $bbp_db->query( "DELETE FROM `{$bbp_db->postmeta}` WHERE `meta_key` IN ( '_bbp_last_reply_id', '_bbp_last_topic_id', '_bbp_last_active_id', '_bbp_last_active_time' )" ) ) ) { 907 return array( 1, sprintf( $statement, $result ) ); 908 } 909 910 // Post types and status 911 $fpt = bbp_get_forum_post_type(); 912 $tpt = bbp_get_topic_post_type(); 913 $rpt = bbp_get_reply_post_type(); 914 $pps = bbp_get_public_status_id(); 915 916 // Next, give all the topics with replies the ID their last reply. 917 if ( is_wp_error( $bbp_db->query( "INSERT INTO `{$bbp_db->postmeta}` (`post_id`, `meta_key`, `meta_value`) 918 ( SELECT `topic`.`ID`, '_bbp_last_reply_id', MAX( `reply`.`ID` ) 919 FROM `{$bbp_db->posts}` AS `topic` INNER JOIN `{$bbp_db->posts}` AS `reply` ON `topic`.`ID` = `reply`.`post_parent` 920 WHERE `reply`.`post_status` = '{$pps}' AND `topic`.`post_type` = '{$tpt}' AND `reply`.`post_type` = '{$rpt}' 921 GROUP BY `topic`.`ID` )" ) ) ) { 922 return array( 2, sprintf( $statement, $result ) ); 923 } 924 925 // For any remaining topics, give a reply ID of 0. 926 if ( is_wp_error( $bbp_db->query( "INSERT INTO `{$bbp_db->postmeta}` (`post_id`, `meta_key`, `meta_value`) 927 ( SELECT `ID`, '_bbp_last_reply_id', 0 928 FROM `{$bbp_db->posts}` AS `topic` LEFT JOIN `{$bbp_db->postmeta}` AS `reply` 929 ON `topic`.`ID` = `reply`.`post_id` AND `reply`.`meta_key` = '_bbp_last_reply_id' 930 WHERE `reply`.`meta_id` IS NULL AND `topic`.`post_type` = '{$tpt}' )" ) ) ) { 931 return array( 3, sprintf( $statement, $result ) ); 932 } 933 934 // Now we give all the forums with topics the ID their last topic. 935 if ( is_wp_error( $bbp_db->query( "INSERT INTO `{$bbp_db->postmeta}` (`post_id`, `meta_key`, `meta_value`) 936 ( SELECT `forum`.`ID`, '_bbp_last_topic_id', MAX( `topic`.`ID` ) 937 FROM `{$bbp_db->posts}` AS `forum` INNER JOIN `{$bbp_db->posts}` AS `topic` ON `forum`.`ID` = `topic`.`post_parent` 938 WHERE `topic`.`post_status` = '{$pps}' AND `forum`.`post_type` = '{$fpt}' AND `topic`.`post_type` = '{$tpt}' 939 GROUP BY `forum`.`ID` )" ) ) ) { 940 return array( 4, sprintf( $statement, $result ) ); 941 } 942 943 // For any remaining forums, give a topic ID of 0. 944 if ( is_wp_error( $bbp_db->query( "INSERT INTO `{$bbp_db->postmeta}` (`post_id`, `meta_key`, `meta_value`) 945 ( SELECT `ID`, '_bbp_last_topic_id', 0 946 FROM `{$bbp_db->posts}` AS `forum` LEFT JOIN `{$bbp_db->postmeta}` AS `topic` 947 ON `forum`.`ID` = `topic`.`post_id` AND `topic`.`meta_key` = '_bbp_last_topic_id' 948 WHERE `topic`.`meta_id` IS NULL AND `forum`.`post_type` = '{$fpt}' )" ) ) ) { 949 return array( 5, sprintf( $statement, $result ) ); 950 } 951 952 // After that, we give all the topics with replies the ID their last reply (again, this time for a different reason). 953 if ( is_wp_error( $bbp_db->query( "INSERT INTO `{$bbp_db->postmeta}` (`post_id`, `meta_key`, `meta_value`) 954 ( SELECT `topic`.`ID`, '_bbp_last_active_id', MAX( `reply`.`ID` ) 955 FROM `{$bbp_db->posts}` AS `topic` INNER JOIN `{$bbp_db->posts}` AS `reply` ON `topic`.`ID` = `reply`.`post_parent` 956 WHERE `reply`.`post_status` = '{$pps}' AND `topic`.`post_type` = '{$tpt}' AND `reply`.`post_type` = '{$rpt}' 957 GROUP BY `topic`.`ID` )" ) ) ) { 958 return array( 6, sprintf( $statement, $result ) ); 959 } 960 961 // For any remaining topics, give a reply ID of themself. 962 if ( is_wp_error( $bbp_db->query( "INSERT INTO `{$bbp_db->postmeta}` (`post_id`, `meta_key`, `meta_value`) 963 ( SELECT `ID`, '_bbp_last_active_id', `ID` 964 FROM `{$bbp_db->posts}` AS `topic` LEFT JOIN `{$bbp_db->postmeta}` AS `reply` 965 ON `topic`.`ID` = `reply`.`post_id` AND `reply`.`meta_key` = '_bbp_last_active_id' 966 WHERE `reply`.`meta_id` IS NULL AND `topic`.`post_type` = '{$tpt}' )" ) ) ) { 967 return array( 7, sprintf( $statement, $result ) ); 968 } 969 970 // Give topics with replies their last update time. 971 if ( is_wp_error( $bbp_db->query( "INSERT INTO `{$bbp_db->postmeta}` (`post_id`, `meta_key`, `meta_value`) 972 ( SELECT `topic`.`ID`, '_bbp_last_active_time', MAX( `reply`.`post_date` ) 973 FROM `{$bbp_db->posts}` AS `topic` INNER JOIN `{$bbp_db->posts}` AS `reply` ON `topic`.`ID` = `reply`.`post_parent` 974 WHERE `reply`.`post_status` = '{$pps}' AND `topic`.`post_type` = '{$tpt}' AND `reply`.`post_type` = '{$rpt}' 975 GROUP BY `topic`.`ID` )" ) ) ) { 976 return array( 8, sprintf( $statement, $result ) ); 977 } 978 979 // Give topics without replies their last update time. 980 if ( is_wp_error( $bbp_db->query( "INSERT INTO `{$bbp_db->postmeta}` (`post_id`, `meta_key`, `meta_value`) 981 ( SELECT `ID`, '_bbp_last_active_time', `post_date` 982 FROM `{$bbp_db->posts}` AS `topic` LEFT JOIN `{$bbp_db->postmeta}` AS `reply` 983 ON `topic`.`ID` = `reply`.`post_id` AND `reply`.`meta_key` = '_bbp_last_active_time' 984 WHERE `reply`.`meta_id` IS NULL AND `topic`.`post_type` = '{$tpt}' )" ) ) ) { 985 return array( 9, sprintf( $statement, $result ) ); 986 } 987 988 // Forums need to know what their last active item is as well. Now it gets a bit more complex to do in the database. 989 $forums = $bbp_db->get_col( "SELECT `ID` FROM `{$bbp_db->posts}` WHERE `post_type` = '{$fpt}' and `post_status` != 'auto-draft'" ); 990 if ( is_wp_error( $forums ) ) { 991 return array( 10, sprintf( $statement, $result ) ); 992 } 993 994 // Loop through forums 995 foreach ( $forums as $forum_id ) { 996 if ( ! bbp_is_forum_category( $forum_id ) ) { 997 bbp_update_forum( array( 'forum_id' => $forum_id ) ); 998 } 999 } 1000 1001 // Loop through categories when forums are done 1002 foreach ( $forums as $forum_id ) { 1003 if ( bbp_is_forum_category( $forum_id ) ) { 1004 bbp_update_forum( array( 'forum_id' => $forum_id ) ); 1005 } 1006 } 1007 1008 // Complete results 1009 return array( 0, sprintf( $statement, esc_html__( 'Complete!', 'bbpress' ) ) ); 1010 } 1011 1012 /** 1013 * Repair the relationship of sticky topics to the actual parent forum 1014 * 1015 * @since 2.3.0 bbPress (r4695) 1016 * 1017 * @return array An array of the status code and the message 1018 */ 1019 function bbp_admin_repair_sticky() { 1020 1021 // Define variables 1022 $bbp_db = bbp_db(); 1023 $statement = esc_html__( 'Repairing the sticky topic to the parent forum relationships… %s', 'bbpress' ); 1024 $result = esc_html__( 'Failed!', 'bbpress' ); 1025 1026 $forums = $bbp_db->get_col( "SELECT ID FROM `{$bbp_db->posts}` WHERE `post_type` = '" . bbp_get_forum_post_type() . "'" ); 1027 1028 // Bail if no forums found 1029 if ( empty( $forums ) || is_wp_error( $forums ) ) { 1030 return array( 1, sprintf( $statement, $result ) ); 1031 } 1032 1033 // Loop through forums and get their sticky topics 1034 foreach ( $forums as $forum ) { 1035 $forum_stickies[ $forum ] = get_post_meta( $forum, '_bbp_sticky_topics', true ); 1036 } 1037 1038 // Cleanup 1039 unset( $forums, $forum ); 1040 1041 // Loop through each forum with sticky topics 1042 foreach ( $forum_stickies as $forum_id => $stickies ) { 1043 1044 // Skip if no stickies 1045 if ( empty( $stickies ) ) { 1046 continue; 1047 } 1048 1049 // Loop through each sticky topic 1050 foreach ( $stickies as $id => $topic_id ) { 1051 1052 // If the topic is not a super sticky, and the forum ID does not 1053 // match the topic's forum ID, unset the forum's sticky meta. 1054 if ( ! bbp_is_topic_super_sticky( $topic_id ) && ( $forum_id !== bbp_get_topic_forum_id( $topic_id ) ) ) { 1055 unset( $forum_stickies[ $forum_id ][ $id ] ); 1056 } 1057 } 1058 1059 // Get sticky topic ID's, or use empty string 1060 $stickers = ! empty( $forum_stickies[ $forum_id ] ) 1061 ? array_values( $forum_stickies[ $forum_id ] ) 1062 : ''; 1063 1064 // Update the forum's sticky topics meta 1065 update_post_meta( $forum_id, '_bbp_sticky_topics', $stickers ); 1066 } 1067 1068 // Complete results 1069 return array( 0, sprintf( $statement, esc_html__( 'Complete!', 'bbpress' ) ) ); 1070 } 1071 1072 /** 1073 * Repair closed topics 1074 * 1075 * Closed topics that are missing the post-meta "_bbp_status" key value "publish" 1076 * result in unexpected behavior, primarily this would have only occurred if you 1077 * had imported forums from another forum package previous to bbPress v2.6, 1078 * https://bbpress.trac.wordpress.org/ticket/2577 1079 * 1080 * @since 2.6.0 bbPress (r5668) 1081 * 1082 * @return array An array of the status code and the message 1083 */ 1084 function bbp_admin_repair_closed_topics() { 1085 1086 // Define variables 1087 $bbp_db = bbp_db(); 1088 $statement = esc_html__( 'Repairing closed topics… %s', 'bbpress' ); 1089 $result = esc_html__( 'No closed topics to repair.', 'bbpress' ); 1090 $changed = 0; 1091 1092 // Results 1093 $query = "SELECT ID FROM `{$bbp_db->posts}` WHERE `post_type` = %s AND `post_status` = %s"; 1094 $prepare = $bbp_db->prepare( $query, bbp_get_topic_post_type(), bbp_get_closed_status_id() ); 1095 $closed_topics = $bbp_db->get_col( $prepare ); 1096 1097 // Bail if no closed topics found 1098 if ( empty( $closed_topics ) || is_wp_error( $closed_topics ) ) { 1099 return array( 1, sprintf( $statement, $result ) ); 1100 } 1101 1102 // Loop through each closed topic 1103 foreach ( $closed_topics as $closed_topic ) { 1104 1105 // Check if the closed topic already has a postmeta _bbp_status value 1106 $topic_status = get_post_meta( $closed_topic, '_bbp_status', true ); 1107 1108 // If we don't have a postmeta _bbp_status value 1109 if ( empty( $topic_status ) ) { 1110 update_post_meta( $closed_topic, '_bbp_status', 'publish' ); 1111 ++$changed; // Keep a count to display at the end 1112 } 1113 } 1114 1115 // Cleanup 1116 unset( $closed_topics, $closed_topic, $topic_status ); 1117 1118 // Complete results 1119 $result = sprintf( _n( 'Complete! %d closed topic repaired.', 'Complete! %d closed topics repaired.', $changed, 'bbpress' ), $changed ); 1120 1121 return array( 0, sprintf( $statement, $result ) ); 1122 } 1123 1124 /** 1125 * Repair the private and hidden forums 1126 * 1127 * @since 2.2.0 bbPress (r4104) 1128 * 1129 * @return array An array of the status code and the message 1130 */ 1131 function bbp_admin_repair_forum_visibility() { 1132 $statement = esc_html__( 'Recalculating forum visibility… %s', 'bbpress' ); 1133 1134 // Bail if queries returned errors 1135 if ( ! bbp_repair_forum_visibility() ) { 1136 return array( 2, sprintf( $statement, esc_html__( 'Failed!', 'bbpress' ) ) ); 1137 1138 // Complete results 1139 } else { 1140 return array( 0, sprintf( $statement, esc_html__( 'Complete!', 'bbpress' ) ) ); 1141 } 1142 } 1143 1144 /** 1145 * Repair the parent forum meta for each topic and reply 1146 * 1147 * @since 2.1.0 bbPress (r3876) 1148 * 1149 * @return array An array of the status code and the message 1150 */ 1151 function bbp_admin_repair_forum_meta() { 1152 1153 // Define variables 1154 $bbp_db = bbp_db(); 1155 $statement = esc_html__( 'Recalculating the forum for each post… %s', 'bbpress' ); 1156 $result = esc_html__( 'Failed!', 'bbpress' ); 1157 1158 // First, delete everything. 1159 if ( is_wp_error( $bbp_db->query( "DELETE FROM `{$bbp_db->postmeta}` WHERE `meta_key` = '_bbp_forum_id'" ) ) ) { 1160 return array( 1, sprintf( $statement, $result ) ); 1161 } 1162 1163 // Post types and status 1164 $tpt = bbp_get_topic_post_type(); 1165 $rpt = bbp_get_reply_post_type(); 1166 $fmt = bbp_get_forum_post_type(); 1167 1168 // Next, give all the topics their parent forum id. 1169 if ( is_wp_error( $bbp_db->query( "INSERT INTO `{$bbp_db->postmeta}` (`post_id`, `meta_key`, `meta_value`) 1170 ( SELECT `topic`.`ID`, '_bbp_forum_id', `topic`.`post_parent` 1171 FROM `$bbp_db->posts` 1172 AS `topic` 1173 WHERE `topic`.`post_type` = '{$tpt}' 1174 GROUP BY `topic`.`ID` )" ) ) ) { 1175 return array( 2, sprintf( $statement, $result ) ); 1176 } 1177 1178 // Next, give all the forums their parent forum id. 1179 if ( is_wp_error( $bbp_db->query( "INSERT INTO `{$bbp_db->postmeta}` (`post_id`, `meta_key`, `meta_value`) 1180 ( SELECT `forum`.`ID`, '_bbp_forum_id', `forum`.`post_parent` 1181 FROM `$bbp_db->posts` 1182 AS `forum` 1183 WHERE `forum`.`post_type` = '{$fmt}' 1184 GROUP BY `forum`.`ID` )" ) ) ) { 1185 return array( 2, sprintf( $statement, $result ) ); 1186 } 1187 1188 // Next, give all the replies their parent forum id. 1189 if ( is_wp_error( $bbp_db->query( "INSERT INTO `{$bbp_db->postmeta}` (`post_id`, `meta_key`, `meta_value`) 1190 ( SELECT `reply`.`ID`, '_bbp_forum_id', `topic`.`post_parent` 1191 FROM `$bbp_db->posts` 1192 AS `reply` 1193 INNER JOIN `$bbp_db->posts` 1194 AS `topic` 1195 ON `reply`.`post_parent` = `topic`.`ID` 1196 WHERE `topic`.`post_type` = '{$tpt}' 1197 AND `reply`.`post_type` = '{$rpt}' 1198 GROUP BY `reply`.`ID` )" ) ) ) { 1199 return array( 3, sprintf( $statement, $result ) ); 1200 } 1201 1202 // Complete results 1203 return array( 0, sprintf( $statement, esc_html__( 'Complete!', 'bbpress' ) ) ); 1204 } 1205 1206 /** 1207 * Repair the topic for each post 1208 * 1209 * @since 2.1.0 bbPress (r3876) 1210 * 1211 * @return array An array of the status code and the message 1212 */ 1213 function bbp_admin_repair_topic_meta() { 1214 1215 // Define variables 1216 $bbp_db = bbp_db(); 1217 $statement = esc_html__( 'Recalculating the topic for each post… %s', 'bbpress' ); 1218 $result = esc_html__( 'Failed!', 'bbpress' ); 1219 1220 // First, delete everything. 1221 if ( is_wp_error( $bbp_db->query( "DELETE FROM `{$bbp_db->postmeta}` WHERE `meta_key` = '_bbp_topic_id'" ) ) ) { 1222 return array( 1, sprintf( $statement, $result ) ); 1223 } 1224 1225 // Post types and status 1226 $tpt = bbp_get_topic_post_type(); 1227 $rpt = bbp_get_reply_post_type(); 1228 1229 // Next, give all the topics with replies the ID their last reply. 1230 if ( is_wp_error( $bbp_db->query( "INSERT INTO `{$bbp_db->postmeta}` (`post_id`, `meta_key`, `meta_value`) 1231 ( SELECT `topic`.`ID`, '_bbp_topic_id', `topic`.`ID` 1232 FROM `$bbp_db->posts` 1233 AS `topic` 1234 WHERE `topic`.`post_type` = '{$tpt}' 1235 GROUP BY `topic`.`ID` )" ) ) ) { 1236 return array( 3, sprintf( $statement, $result ) ); 1237 } 1238 1239 // Next, give all the topics with replies the ID their last reply. 1240 if ( is_wp_error( $bbp_db->query( "INSERT INTO `{$bbp_db->postmeta}` (`post_id`, `meta_key`, `meta_value`) 1241 ( SELECT `reply`.`ID`, '_bbp_topic_id', `topic`.`ID` 1242 FROM `$bbp_db->posts` 1243 AS `reply` 1244 INNER JOIN `$bbp_db->posts` 1245 AS `topic` 1246 ON `reply`.`post_parent` = `topic`.`ID` 1247 WHERE `topic`.`post_type` = '{$tpt}' 1248 AND `reply`.`post_type` = '{$rpt}' 1249 GROUP BY `reply`.`ID` )" ) ) ) { 1250 return array( 4, sprintf( $statement, $result ) ); 1251 } 1252 1253 // Complete results 1254 return array( 0, sprintf( $statement, esc_html__( 'Complete!', 'bbpress' ) ) ); 1255 } 1256 1257 /** 1258 * Recalculate reply menu order 1259 * 1260 * @since 2.5.4 bbPress (r5367) 1261 * 1262 * @return array An array of the status code and the message 1263 */ 1264 function bbp_admin_repair_reply_menu_order() { 1265 1266 // Define variables 1267 $bbp_db = bbp_db(); 1268 $statement = esc_html__( 'Recalculating reply menu order… %s', 'bbpress' ); 1269 $result = esc_html__( 'No reply positions to recalculate.', 'bbpress' ); 1270 1271 // Delete cases where `_bbp_reply_to` was accidentally set to itself 1272 if ( is_wp_error( $bbp_db->query( "DELETE FROM `{$bbp_db->postmeta}` WHERE `meta_key` = '_bbp_reply_to' AND `post_id` = `meta_value`" ) ) ) { 1273 return array( 1, sprintf( $statement, $result ) ); 1274 } 1275 1276 // Post type 1277 $rpt = bbp_get_reply_post_type(); 1278 1279 // Get an array of reply id's to update the menu oder for each reply 1280 $replies = $bbp_db->get_results( "SELECT `a`.`ID` FROM `{$bbp_db->posts}` AS `a` 1281 INNER JOIN ( 1282 SELECT `menu_order`, `post_parent` 1283 FROM `{$bbp_db->posts}` 1284 GROUP BY `menu_order`, `post_parent` 1285 HAVING COUNT( * ) >1 1286 )`b` 1287 ON `a`.`menu_order` = `b`.`menu_order` 1288 AND `a`.`post_parent` = `b`.`post_parent` 1289 WHERE `post_type` = '{$rpt}'", OBJECT_K ); 1290 1291 // Bail if no replies returned 1292 if ( empty( $replies ) ) { 1293 return array( 1, sprintf( $statement, $result ) ); 1294 } 1295 1296 // Recalculate the menu order position for each reply 1297 foreach ( $replies as $reply ) { 1298 bbp_update_reply_position( $reply->ID ); 1299 } 1300 1301 // Cleanup 1302 unset( $replies, $reply ); 1303 1304 // Complete results 1305 return array( 0, sprintf( $statement, esc_html__( 'Complete!', 'bbpress' ) ) ); 1306 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Sat Dec 21 01:00:52 2024 | Cross-referenced by PHPXref 0.7.1 |