diff -r c7c0fbc09788 -r 5e8dcbe22c24 web/wp-content/plugins/bbpress/includes/admin/tools.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/web/wp-content/plugins/bbpress/includes/admin/tools.php Tue Dec 04 18:43:10 2012 -0800 @@ -0,0 +1,1129 @@ + + +
+ + + + + +

+

+ +
+ + + + + + + +
+
+ + + + +
+ + + +
+
+ +
+ + +
+
+
+ +' . $message . '

'; + $class = $class ? $class : 'updated'; + } elseif ( is_wp_error( $message ) ) { + $errors = $message->get_error_messages(); + + switch ( count( $errors ) ) { + case 0: + return false; + break; + + case 1: + $message = '

' . $errors[0] . '

'; + break; + + default: + $message = ''; + break; + } + + $class = $class ? $class : 'error'; + } else { + return false; + } + + $message = '
' . $message . '
'; + $message = str_replace( "'", "\'", $message ); + $lambda = create_function( '', "echo '$message';" ); + + add_action( 'admin_notices', $lambda ); + + return $lambda; +} + +/** + * Get the array of the repair list + * + * @since bbPress (r2613) + * + * @uses apply_filters() Calls 'bbp_repair_list' with the list array + * @return array Repair list of options + */ +function bbp_admin_repair_list() { + $repair_list = array( + 0 => array( 'bbp-sync-topic-meta', __( 'Recalculate the parent topic for each post', 'bbpress' ), 'bbp_admin_repair_topic_meta' ), + 5 => array( 'bbp-sync-forum-meta', __( 'Recalculate the parent forum for each post', 'bbpress' ), 'bbp_admin_repair_forum_meta' ), + 10 => array( 'bbp-sync-forum-visibility', __( 'Recalculate private and hidden forums', 'bbpress' ), 'bbp_admin_repair_forum_visibility' ), + 15 => array( 'bbp-sync-all-topics-forums', __( 'Recalculate last activity in each topic and forum', 'bbpress' ), 'bbp_admin_repair_freshness' ), + 20 => array( 'bbp-group-forums', __( 'Repair BuddyPress Group Forum relationships', 'bbpress' ), 'bbp_admin_repair_group_forum_relationship' ), + 25 => array( 'bbp-forum-topics', __( 'Count topics in each forum', 'bbpress' ), 'bbp_admin_repair_forum_topic_count' ), + 30 => array( 'bbp-forum-replies', __( 'Count replies in each forum', 'bbpress' ), 'bbp_admin_repair_forum_reply_count' ), + 35 => array( 'bbp-topic-replies', __( 'Count replies in each topic', 'bbpress' ), 'bbp_admin_repair_topic_reply_count' ), + 40 => array( 'bbp-topic-voices', __( 'Count voices in each topic', 'bbpress' ), 'bbp_admin_repair_topic_voice_count' ), + 45 => array( 'bbp-topic-hidden-replies', __( 'Count spammed & trashed replies in each topic', 'bbpress' ), 'bbp_admin_repair_topic_hidden_reply_count' ), + 50 => array( 'bbp-user-replies', __( 'Count topics for each user', 'bbpress' ), 'bbp_admin_repair_user_topic_count' ), + 55 => array( 'bbp-user-topics', __( 'Count replies for each user', 'bbpress' ), 'bbp_admin_repair_user_reply_count' ), + 60 => array( 'bbp-user-favorites', __( 'Remove trashed topics from user favorites', 'bbpress' ), 'bbp_admin_repair_user_favorites' ), + 65 => array( 'bbp-user-subscriptions', __( 'Remove trashed topics from user subscriptions', 'bbpress' ), 'bbp_admin_repair_user_subscriptions' ), + 70 => array( 'bbp-user-role-map', __( 'Remap existing users to default forum roles', 'bbpress' ), 'bbp_admin_repair_user_roles' ) + ); + ksort( $repair_list ); + + return (array) apply_filters( 'bbp_repair_list', $repair_list ); +} + +/** + * Recount topic replies + * + * @since bbPress (r2613) + * + * @uses bbp_get_reply_post_type() To get the reply post type + * @uses wpdb::query() To run our recount sql queries + * @uses is_wp_error() To check if the executed query returned {@link WP_Error} + * @return array An array of the status code and the message + */ +function bbp_admin_repair_topic_reply_count() { + global $wpdb; + + $statement = __( 'Counting the number of replies in each topic… %s', 'bbpress' ); + $result = __( 'Failed!', 'bbpress' ); + + $sql_delete = "DELETE FROM `{$wpdb->postmeta}` WHERE `meta_key` = '_bbp_reply_count';"; + if ( is_wp_error( $wpdb->query( $sql_delete ) ) ) + return array( 1, sprintf( $statement, $result ) ); + + // Post types and status + $tpt = bbp_get_topic_post_type(); + $rpt = bbp_get_reply_post_type(); + $pps = bbp_get_public_status_id(); + $cps = bbp_get_closed_status_id(); + + $sql = "INSERT INTO `{$wpdb->postmeta}` (`post_id`, `meta_key`, `meta_value`) ( + SELECT `topics`.`ID` AS `post_id`, '_bbp_reply_count' AS `meta_key`, COUNT(`replies`.`ID`) As `meta_value` + FROM `{$wpdb->posts}` AS `topics` + LEFT JOIN `{$wpdb->posts}` as `replies` + ON `replies`.`post_parent` = `topics`.`ID` + AND `replies`.`post_status` = '{$pps}' + AND `replies`.`post_type` = '{$rpt}' + WHERE `topics`.`post_type` = '{$tpt}' + AND `topics`.`post_status` IN ( '{$pps}', '{$cps}' ) + GROUP BY `topics`.`ID`);"; + + if ( is_wp_error( $wpdb->query( $sql ) ) ) + return array( 2, sprintf( $statement, $result ) ); + + return array( 0, sprintf( $statement, __( 'Complete!', 'bbpress' ) ) ); +} + +/** + * Recount topic voices + * + * @since bbPress (r2613) + * + * @uses bbp_get_reply_post_type() To get the reply post type + * @uses wpdb::query() To run our recount sql queries + * @uses is_wp_error() To check if the executed query returned {@link WP_Error} + * @return array An array of the status code and the message + */ +function bbp_admin_repair_topic_voice_count() { + global $wpdb; + + $statement = __( 'Counting the number of voices in each topic… %s', 'bbpress' ); + $result = __( 'Failed!', 'bbpress' ); + + $sql_delete = "DELETE FROM `{$wpdb->postmeta}` WHERE `meta_key` = '_bbp_voice_count';"; + if ( is_wp_error( $wpdb->query( $sql_delete ) ) ) + return array( 1, sprintf( $statement, $result ) ); + + // Post types and status + $tpt = bbp_get_topic_post_type(); + $rpt = bbp_get_reply_post_type(); + $pps = bbp_get_public_status_id(); + $cps = bbp_get_closed_status_id(); + + $sql = "INSERT INTO `{$wpdb->postmeta}` (`post_id`, `meta_key`, `meta_value`) ( + SELECT `postmeta`.`meta_value`, '_bbp_voice_count', COUNT(DISTINCT `post_author`) as `meta_value` + FROM `{$wpdb->posts}` AS `posts` + LEFT JOIN `{$wpdb->postmeta}` AS `postmeta` + ON `posts`.`ID` = `postmeta`.`post_id` + AND `postmeta`.`meta_key` = '_bbp_topic_id' + WHERE `posts`.`post_type` IN ( '{$tpt}', '{$rpt}' ) + AND `posts`.`post_status` IN ( '{$pps}', '{$cps}' ) + AND `posts`.`post_author` != '0' + GROUP BY `postmeta`.`meta_value`);"; + + if ( is_wp_error( $wpdb->query( $sql ) ) ) + return array( 2, sprintf( $statement, $result ) ); + + return array( 0, sprintf( $statement, __( 'Complete!', 'bbpress' ) ) ); +} + +/** + * Recount topic hidden replies (spammed/trashed) + * + * @since bbPress (r2747) + * + * @uses wpdb::query() To run our recount sql queries + * @uses is_wp_error() To check if the executed query returned {@link WP_Error} + * @return array An array of the status code and the message + */ +function bbp_admin_repair_topic_hidden_reply_count() { + global $wpdb; + + $statement = __( 'Counting the number of spammed and trashed replies in each topic… %s', 'bbpress' ); + $result = __( 'Failed!', 'bbpress' ); + + $sql_delete = "DELETE FROM `{$wpdb->postmeta}` WHERE `meta_key` = '_bbp_reply_count_hidden';"; + if ( is_wp_error( $wpdb->query( $sql_delete ) ) ) + return array( 1, sprintf( $statement, $result ) ); + + $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`);"; + if ( is_wp_error( $wpdb->query( $sql ) ) ) + return array( 2, sprintf( $statement, $result ) ); + + return array( 0, sprintf( $statement, __( 'Complete!', 'bbpress' ) ) ); +} + +/** + * Repair group forum ID mappings after a bbPress 1.1 to bbPress 2.2 conversion + * + * @since bbPress (r4395) + * + * @global WPDB $wpdb + * @return If a wp_error() occurs and no converted forums are found + */ +function bbp_admin_repair_group_forum_relationship() { + global $wpdb; + + $statement = __( 'Repairing BuddyPress group-forum relationships… %s', 'bbpress' ); + $g_count = 0; + $f_count = 0; + + // Copy the BuddyPress filter here, incase BuddyPress is not active + $prefix = apply_filters( 'bp_core_get_table_prefix', $wpdb->base_prefix ); + $tablename = $prefix . 'bp_groups_groupmeta'; + + // Get the converted forum IDs + $forum_ids = $wpdb->query( "SELECT `forum`.`ID`, `forummeta`.`meta_value` + FROM `{$wpdb->posts}` AS `forum` + LEFT JOIN `{$wpdb->postmeta}` AS `forummeta` + ON `forum`.`ID` = `forummeta`.`post_id` + AND `forummeta`.`meta_key` = '_bbp_old_forum_id' + WHERE `forum`.`post_type` = 'forum' + GROUP BY `forum`.`ID`;" ); + + // Bail if forum IDs returned an error + if ( is_wp_error( $forum_ids ) || empty( $wpdb->last_result ) ) + return array( 2, sprintf( $statement, __( 'Failed!', 'bbpress' ) ) ); + + // Stash the last results + $results = $wpdb->last_result; + + // Update each group forum + foreach ( $results as $group_forums ) { + + // Only update if is a converted forum + if ( ! isset( $group_forums->meta_value ) ) + continue; + + // Attempt to update group meta + $updated = $wpdb->query( "UPDATE `{$tablename}` SET `meta_value` = '{$group_forums->ID}' WHERE `meta_key` = 'forum_id' AND `meta_value` = '{$group_forums->meta_value}';" ); + + // Bump the count + if ( !empty( $updated ) && ! is_wp_error( $updated ) ) { + ++$g_count; + } + + // Update group's forum metadata + $group_id = (int) $wpdb->get_var( "SELECT `group_id` FROM `{$tablename}` WHERE `meta_key` = 'forum_id' AND `meta_value` = '{$group_forums->ID}';" ); + if ( !empty( $group_id ) ) { + update_post_meta( $group_forums->ID, '_bbp_group_ids', array( $group_id ) ); + ++$f_count; + } + } + + // Make some logical guesses at the old group root forum + if ( function_exists( 'bp_forums_parent_forum_id' ) ) { + $old_default_forum_id = bp_forums_parent_forum_id(); + } elseif ( defined( 'BP_FORUMS_PARENT_FORUM_ID' ) ) { + $old_default_forum_id = (int) BP_FORUMS_PARENT_FORUM_ID; + } else { + $old_default_forum_id = 1; + } + + // Try to get the group root forum + $posts = get_posts( array( + 'post_type' => bbp_get_forum_post_type(), + 'meta_key' => '_bbp_old_forum_id', + 'meta_value' => $old_default_forum_id, + 'numberposts' => 1 + ) ); + + // Found the group root forum + if ( ! empty( $posts ) ) { + + // Rename 'Default Forum' since it's now visible in sitewide forums + if ( 'Default Forum' == $posts[0]->post_title ) { + wp_update_post( array( + 'ID' => $posts[0]->ID, + 'post_title' => __( 'Group Forums', 'bbpress' ), + ) ); + } + + // Update the group forums root metadata + update_option( '_bbp_group_forums_root_id', $posts[0]->ID ); + } + + // Complete results + $result = sprintf( __( 'Complete! %s groups updated; %s forums updated.', 'bbpress' ), bbp_number_format( $g_count ), bbp_number_format( $f_count ) ); + return array( 0, sprintf( $statement, $result ) ); +} + +/** + * Recount forum topics + * + * @since bbPress (r2613) + * + * @uses wpdb::query() To run our recount sql queries + * @uses is_wp_error() To check if the executed query returned {@link WP_Error} + * @uses bbp_get_forum_post_type() To get the forum post type + * @uses get_posts() To get the forums + * @uses bbp_update_forum_topic_count() To update the forum topic count + * @return array An array of the status code and the message + */ +function bbp_admin_repair_forum_topic_count() { + global $wpdb; + + $statement = __( 'Counting the number of topics in each forum… %s', 'bbpress' ); + $result = __( 'Failed!', 'bbpress' ); + + $sql_delete = "DELETE FROM {$wpdb->postmeta} WHERE meta_key IN ( '_bbp_topic_count', '_bbp_total_topic_count' );"; + if ( is_wp_error( $wpdb->query( $sql_delete ) ) ) + return array( 1, sprintf( $statement, $result ) ); + + $forums = get_posts( array( 'post_type' => bbp_get_forum_post_type(), 'numberposts' => -1 ) ); + if ( !empty( $forums ) ) { + foreach( $forums as $forum ) { + bbp_update_forum_topic_count( $forum->ID ); + } + } else { + return array( 2, sprintf( $statement, $result ) ); + } + + return array( 0, sprintf( $statement, __( 'Complete!', 'bbpress' ) ) ); +} + +/** + * Recount forum replies + * + * @since bbPress (r2613) + * + * @uses wpdb::query() To run our recount sql queries + * @uses is_wp_error() To check if the executed query returned {@link WP_Error} + * @uses bbp_get_forum_post_type() To get the forum post type + * @uses get_posts() To get the forums + * @uses bbp_update_forum_reply_count() To update the forum reply count + * @return array An array of the status code and the message + */ +function bbp_admin_repair_forum_reply_count() { + global $wpdb; + + $statement = __( 'Counting the number of replies in each forum… %s', 'bbpress' ); + $result = __( 'Failed!', 'bbpress' ); + + $sql_delete = "DELETE FROM `{$wpdb->postmeta}` WHERE `meta_key` IN ( '_bbp_reply_count', '_bbp_total_reply_count' );"; + if ( is_wp_error( $wpdb->query( $sql_delete ) ) ) + return array( 1, sprintf( $statement, $result ) ); + + $forums = get_posts( array( 'post_type' => bbp_get_forum_post_type(), 'numberposts' => -1 ) ); + if ( !empty( $forums ) ) { + foreach( $forums as $forum ) { + bbp_update_forum_reply_count( $forum->ID ); + } + } else { + return array( 2, sprintf( $statement, $result ) ); + } + + return array( 0, sprintf( $statement, __( 'Complete!', 'bbpress' ) ) ); +} + +/** + * Recount topics by the users + * + * @since bbPress (r3889) + * + * @uses bbp_get_reply_post_type() To get the reply post type + * @uses wpdb::query() To run our recount sql queries + * @uses is_wp_error() To check if the executed query returned {@link WP_Error} + * @return array An array of the status code and the message + */ +function bbp_admin_repair_user_topic_count() { + global $wpdb; + + $statement = __( 'Counting the number of topics each user has created… %s', 'bbpress' ); + $result = __( 'Failed!', 'bbpress' ); + $sql_select = "SELECT `post_author`, COUNT(DISTINCT `ID`) as `_count` FROM `{$wpdb->posts}` WHERE `post_type` = '" . bbp_get_topic_post_type() . "' AND `post_status` = '" . bbp_get_public_status_id() . "' GROUP BY `post_author`;"; + $insert_rows = $wpdb->get_results( $sql_select ); + + if ( is_wp_error( $insert_rows ) ) + return array( 1, sprintf( $statement, $result ) ); + + $key = $wpdb->prefix . '_bbp_topic_count'; + $insert_values = array(); + foreach ( $insert_rows as $insert_row ) + $insert_values[] = "('{$insert_row->post_author}', '{$key}', '{$insert_row->_count}')"; + + if ( !count( $insert_values ) ) + return array( 2, sprintf( $statement, $result ) ); + + $sql_delete = "DELETE FROM `{$wpdb->usermeta}` WHERE `meta_key` = '{$key}';"; + if ( is_wp_error( $wpdb->query( $sql_delete ) ) ) + return array( 3, sprintf( $statement, $result ) ); + + foreach ( array_chunk( $insert_values, 10000 ) as $chunk ) { + $chunk = "\n" . join( ",\n", $chunk ); + $sql_insert = "INSERT INTO `{$wpdb->usermeta}` (`user_id`, `meta_key`, `meta_value`) VALUES $chunk;"; + + if ( is_wp_error( $wpdb->query( $sql_insert ) ) ) { + return array( 4, sprintf( $statement, $result ) ); + } + } + + return array( 0, sprintf( $statement, __( 'Complete!', 'bbpress' ) ) ); +} + +/** + * Recount topic replied by the users + * + * @since bbPress (r2613) + * + * @uses bbp_get_reply_post_type() To get the reply post type + * @uses wpdb::query() To run our recount sql queries + * @uses is_wp_error() To check if the executed query returned {@link WP_Error} + * @return array An array of the status code and the message + */ +function bbp_admin_repair_user_reply_count() { + global $wpdb; + + $statement = __( 'Counting the number of topics to which each user has replied… %s', 'bbpress' ); + $result = __( 'Failed!', 'bbpress' ); + $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`;"; + $insert_rows = $wpdb->get_results( $sql_select ); + + if ( is_wp_error( $insert_rows ) ) + return array( 1, sprintf( $statement, $result ) ); + + $key = $wpdb->prefix . '_bbp_reply_count'; + $insert_values = array(); + foreach ( $insert_rows as $insert_row ) + $insert_values[] = "('{$insert_row->post_author}', '{$key}', '{$insert_row->_count}')"; + + if ( !count( $insert_values ) ) + return array( 2, sprintf( $statement, $result ) ); + + $sql_delete = "DELETE FROM `{$wpdb->usermeta}` WHERE `meta_key` = '{$key}';"; + if ( is_wp_error( $wpdb->query( $sql_delete ) ) ) + return array( 3, sprintf( $statement, $result ) ); + + foreach ( array_chunk( $insert_values, 10000 ) as $chunk ) { + $chunk = "\n" . join( ",\n", $chunk ); + $sql_insert = "INSERT INTO `{$wpdb->usermeta}` (`user_id`, `meta_key`, `meta_value`) VALUES $chunk;"; + + if ( is_wp_error( $wpdb->query( $sql_insert ) ) ) { + return array( 4, sprintf( $statement, $result ) ); + } + } + + return array( 0, sprintf( $statement, __( 'Complete!', 'bbpress' ) ) ); +} + +/** + * Clean the users' favorites + * + * @since bbPress (r2613) + * + * @uses bbp_get_topic_post_type() To get the topic post type + * @uses wpdb::query() To run our recount sql queries + * @uses is_wp_error() To check if the executed query returned {@link WP_Error} + * @return array An array of the status code and the message + */ +function bbp_admin_repair_user_favorites() { + global $wpdb; + + $statement = __( 'Removing trashed topics from user favorites… %s', 'bbpress' ); + $result = __( 'Failed!', 'bbpress' ); + $key = $wpdb->prefix . '_bbp_favorites'; + $users = $wpdb->get_results( "SELECT `user_id`, `meta_value` AS `favorites` FROM `{$wpdb->usermeta}` WHERE `meta_key` = '{$key}';" ); + + if ( is_wp_error( $users ) ) + return array( 1, sprintf( $statement, $result ) ); + + $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() . "';" ); + + if ( is_wp_error( $topics ) ) + return array( 2, sprintf( $statement, $result ) ); + + $values = array(); + foreach ( $users as $user ) { + if ( empty( $user->favorites ) || !is_string( $user->favorites ) ) + continue; + + $favorites = array_intersect( $topics, (array) explode( ',', $user->favorites ) ); + if ( empty( $favorites ) || !is_array( $favorites ) ) + continue; + + $favorites_joined = join( ',', $favorites ); + $values[] = "('{$user->user_id}', '{$key}, '{$favorites_joined}')"; + + // Cleanup + unset( $favorites, $favorites_joined ); + } + + if ( !count( $values ) ) { + $result = __( 'Nothing to remove!', 'bbpress' ); + return array( 0, sprintf( $statement, $result ) ); + } + + $sql_delete = "DELETE FROM `{$wpdb->usermeta}` WHERE `meta_key` = '{$key}';"; + if ( is_wp_error( $wpdb->query( $sql_delete ) ) ) + return array( 4, sprintf( $statement, $result ) ); + + foreach ( array_chunk( $values, 10000 ) as $chunk ) { + $chunk = "\n" . join( ",\n", $chunk ); + $sql_insert = "INSERT INTO `$wpdb->usermeta` (`user_id`, `meta_key`, `meta_value`) VALUES $chunk;"; + if ( is_wp_error( $wpdb->query( $sql_insert ) ) ) { + return array( 5, sprintf( $statement, $result ) ); + } + } + + return array( 0, sprintf( $statement, __( 'Complete!', 'bbpress' ) ) ); +} + +/** + * Clean the users' subscriptions + * + * @since bbPress (r2668) + * + * @uses bbp_get_topic_post_type() To get the topic post type + * @uses wpdb::query() To run our recount sql queries + * @uses is_wp_error() To check if the executed query returned {@link WP_Error} + * @return array An array of the status code and the message + */ +function bbp_admin_repair_user_subscriptions() { + global $wpdb; + + $statement = __( 'Removing trashed topics from user subscriptions… %s', 'bbpress' ); + $result = __( 'Failed!', 'bbpress' ); + $key = $wpdb->prefix . '_bbp_subscriptions'; + $users = $wpdb->get_results( "SELECT `user_id`, `meta_value` AS `subscriptions` FROM `{$wpdb->usermeta}` WHERE `meta_key` = '{$key}';" ); + + if ( is_wp_error( $users ) ) + return array( 1, sprintf( $statement, $result ) ); + + $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() . "';" ); + if ( is_wp_error( $topics ) ) + return array( 2, sprintf( $statement, $result ) ); + + $values = array(); + foreach ( $users as $user ) { + if ( empty( $user->subscriptions ) || !is_string( $user->subscriptions ) ) + continue; + + $subscriptions = array_intersect( $topics, (array) explode( ',', $user->subscriptions ) ); + if ( empty( $subscriptions ) || !is_array( $subscriptions ) ) + continue; + + $subscriptions_joined = join( ',', $subscriptions ); + $values[] = "('{$user->user_id}', '{$key}', '{$subscriptions_joined}')"; + + // Cleanup + unset( $subscriptions, $subscriptions_joined ); + } + + if ( !count( $values ) ) { + $result = __( 'Nothing to remove!', 'bbpress' ); + return array( 0, sprintf( $statement, $result ) ); + } + + $sql_delete = "DELETE FROM `{$wpdb->usermeta}` WHERE `meta_key` = '{$key}';"; + if ( is_wp_error( $wpdb->query( $sql_delete ) ) ) + return array( 4, sprintf( $statement, $result ) ); + + foreach ( array_chunk( $values, 10000 ) as $chunk ) { + $chunk = "\n" . join( ",\n", $chunk ); + $sql_insert = "INSERT INTO `{$wpdb->usermeta}` (`user_id`, `meta_key`, `meta_value`) VALUES $chunk;"; + if ( is_wp_error( $wpdb->query( $sql_insert ) ) ) { + return array( 5, sprintf( $statement, $result ) ); + } + } + + return array( 0, sprintf( $statement, __( 'Complete!', 'bbpress' ) ) ); +} + +/** + * This repair tool will map each user of the current site to their respective + * forums role. By default, Admins will be Key Masters, and every other role + * will be the default role defined in Settings > Forums (Participant). + * + * @since bbPress (r4340) + * + * @uses bbp_get_user_role_map() To get the map of user roles + * @uses get_editable_roles() To get the current WordPress roles + * @uses get_users() To get the users of each role (limited to ID field) + * @uses bbp_set_user_role() To set each user's forums role + */ +function bbp_admin_repair_user_roles() { + + $statement = __( 'Remapping forum role for each user on this site… %s', 'bbpress' ); + $changed = 0; + $role_map = bbp_get_user_role_map(); + $default_role = bbp_get_default_role(); + + // Bail if no role map exists + if ( empty( $role_map ) ) + return array( 1, sprintf( $statement, __( 'Failed!', 'bbpress' ) ) ); + + // Iterate through each role... + foreach ( array_keys( get_editable_roles() ) as $role ) { + + // Reset the offset + $offset = 0; + + // If no role map exists, give the default forum role (bbp-participant) + $new_role = isset( $role_map[$role] ) ? $role_map[$role] : $default_role; + + // Get users of this site, limited to 1000 + while ( $users = get_users( array( + 'role' => $role, + 'fields' => 'ID', + 'number' => 1000, + 'offset' => $offset + ) ) ) { + + // Iterate through each user of $role and try to set it + foreach ( (array) $users as $user_id ) { + if ( bbp_set_user_role( $user_id, $new_role ) ) { + ++$changed; // Keep a count to display at the end + } + } + + // Bump the offset for the next query iteration + $offset = $offset + 1000; + } + } + + $result = sprintf( __( 'Complete! %s users updated.', 'bbpress' ), bbp_number_format( $changed ) ); + return array( 0, sprintf( $statement, $result ) ); +} + +/** + * Recaches the last post in every topic and forum + * + * @since bbPress (r3040) + * + * @uses wpdb::query() To run our recount sql queries + * @uses is_wp_error() To check if the executed query returned {@link WP_Error} + * @return array An array of the status code and the message + */ +function bbp_admin_repair_freshness() { + global $wpdb; + + $statement = __( 'Recomputing latest post in every topic and forum… %s', 'bbpress' ); + $result = __( 'Failed!', 'bbpress' ); + + // First, delete everything. + 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' );" ) ) ) + return array( 1, sprintf( $statement, $result ) ); + + // Next, give all the topics with replies the ID their last reply. + if ( is_wp_error( $wpdb->query( "INSERT INTO `$wpdb->postmeta` (`post_id`, `meta_key`, `meta_value`) + ( SELECT `topic`.`ID`, '_bbp_last_reply_id', MAX( `reply`.`ID` ) + FROM `$wpdb->posts` AS `topic` INNER JOIN `$wpdb->posts` AS `reply` ON `topic`.`ID` = `reply`.`post_parent` + WHERE `reply`.`post_status` IN ( '" . bbp_get_public_status_id() . "' ) AND `topic`.`post_type` = 'topic' AND `reply`.`post_type` = 'reply' + GROUP BY `topic`.`ID` );" ) ) ) + return array( 2, sprintf( $statement, $result ) ); + + // For any remaining topics, give a reply ID of 0. + if ( is_wp_error( $wpdb->query( "INSERT INTO `$wpdb->postmeta` (`post_id`, `meta_key`, `meta_value`) + ( SELECT `ID`, '_bbp_last_reply_id', 0 + FROM `$wpdb->posts` AS `topic` LEFT JOIN `$wpdb->postmeta` AS `reply` + ON `topic`.`ID` = `reply`.`post_id` AND `reply`.`meta_key` = '_bbp_last_reply_id' + WHERE `reply`.`meta_id` IS NULL AND `topic`.`post_type` = 'topic' );" ) ) ) + return array( 3, sprintf( $statement, $result ) ); + + // Now we give all the forums with topics the ID their last topic. + if ( is_wp_error( $wpdb->query( "INSERT INTO `$wpdb->postmeta` (`post_id`, `meta_key`, `meta_value`) + ( SELECT `forum`.`ID`, '_bbp_last_topic_id', `topic`.`ID` + FROM `$wpdb->posts` AS `forum` INNER JOIN `$wpdb->posts` AS `topic` ON `forum`.`ID` = `topic`.`post_parent` + WHERE `topic`.`post_status` IN ( '" . bbp_get_public_status_id() . "' ) AND `forum`.`post_type` = 'forum' AND `topic`.`post_type` = 'topic' + GROUP BY `forum`.`ID` );" ) ) ) + return array( 4, sprintf( $statement, $result ) ); + + // For any remaining forums, give a topic ID of 0. + if ( is_wp_error( $wpdb->query( "INSERT INTO `$wpdb->postmeta` (`post_id`, `meta_key`, `meta_value`) + ( SELECT `ID`, '_bbp_last_topic_id', 0 + FROM `$wpdb->posts` AS `forum` LEFT JOIN `$wpdb->postmeta` AS `topic` + ON `forum`.`ID` = `topic`.`post_id` AND `topic`.`meta_key` = '_bbp_last_topic_id' + WHERE `topic`.`meta_id` IS NULL AND `forum`.`post_type` = 'forum' );" ) ) ) + return array( 5, sprintf( $statement, $result ) ); + + // After that, we give all the topics with replies the ID their last reply (again, this time for a different reason). + if ( is_wp_error( $wpdb->query( "INSERT INTO `$wpdb->postmeta` (`post_id`, `meta_key`, `meta_value`) + ( SELECT `topic`.`ID`, '_bbp_last_active_id', MAX( `reply`.`ID` ) + FROM `$wpdb->posts` AS `topic` INNER JOIN `$wpdb->posts` AS `reply` ON `topic`.`ID` = `reply`.`post_parent` + WHERE `reply`.`post_status` IN ( '" . bbp_get_public_status_id() . "' ) AND `topic`.`post_type` = 'topic' AND `reply`.`post_type` = 'reply' + GROUP BY `topic`.`ID` );" ) ) ) + return array( 6, sprintf( $statement, $result ) ); + + // For any remaining topics, give a reply ID of themself. + if ( is_wp_error( $wpdb->query( "INSERT INTO `$wpdb->postmeta` (`post_id`, `meta_key`, `meta_value`) + ( SELECT `ID`, '_bbp_last_active_id', `ID` + FROM `$wpdb->posts` AS `topic` LEFT JOIN `$wpdb->postmeta` AS `reply` + ON `topic`.`ID` = `reply`.`post_id` AND `reply`.`meta_key` = '_bbp_last_active_id' + WHERE `reply`.`meta_id` IS NULL AND `topic`.`post_type` = 'topic' );" ) ) ) + return array( 7, sprintf( $statement, $result ) ); + + // Give topics with replies their last update time. + if ( is_wp_error( $wpdb->query( "INSERT INTO `$wpdb->postmeta` (`post_id`, `meta_key`, `meta_value`) + ( SELECT `topic`.`ID`, '_bbp_last_active_time', MAX( `reply`.`post_date` ) + FROM `$wpdb->posts` AS `topic` INNER JOIN `$wpdb->posts` AS `reply` ON `topic`.`ID` = `reply`.`post_parent` + WHERE `reply`.`post_status` IN ( '" . bbp_get_public_status_id() . "' ) AND `topic`.`post_type` = 'topic' AND `reply`.`post_type` = 'reply' + GROUP BY `topic`.`ID` );" ) ) ) + return array( 8, sprintf( $statement, $result ) ); + + // Give topics without replies their last update time. + if ( is_wp_error( $wpdb->query( "INSERT INTO `$wpdb->postmeta` (`post_id`, `meta_key`, `meta_value`) + ( SELECT `ID`, '_bbp_last_active_time', `post_date` + FROM `$wpdb->posts` AS `topic` LEFT JOIN `$wpdb->postmeta` AS `reply` + ON `topic`.`ID` = `reply`.`post_id` AND `reply`.`meta_key` = '_bbp_last_active_time' + WHERE `reply`.`meta_id` IS NULL AND `topic`.`post_type` = 'topic' );" ) ) ) + return array( 9, sprintf( $statement, $result ) ); + + // Forums need to know what their last active item is as well. Now it gets a bit more complex to do in the database. + $forums = $wpdb->get_col( "SELECT `ID` FROM `$wpdb->posts` WHERE `post_type` = 'forum' and `post_status` != 'auto-draft';" ); + if ( is_wp_error( $forums ) ) + return array( 10, sprintf( $statement, $result ) ); + + // Loop through forums + foreach ( $forums as $forum_id ) { + if ( !bbp_is_forum_category( $forum_id ) ) { + bbp_update_forum( array( 'forum_id' => $forum_id ) ); + } + } + + // Loop through categories when forums are done + foreach ( $forums as $forum_id ) { + if ( bbp_is_forum_category( $forum_id ) ) { + bbp_update_forum( array( 'forum_id' => $forum_id ) ); + } + } + + // Complete results + return array( 0, sprintf( $statement, __( 'Complete!', 'bbpress' ) ) ); +} + +/** + * Recaches the private and hidden forums + * + * @since bbPress (r4104) + * + * @uses delete_option() to delete private and hidden forum pointers + * @uses WP_Query() To query post IDs + * @uses is_wp_error() To return if error occurred + * @uses update_option() To update the private and hidden post ID pointers + * @return array An array of the status code and the message + */ +function bbp_admin_repair_forum_visibility() { + + $statement = __( 'Recalculating forum visibility … %s', 'bbpress' ); + $result = __( 'Failed!', 'bbpress' ); + + // First, delete everything. + delete_option( '_bbp_private_forums' ); + delete_option( '_bbp_hidden_forums' ); + + // Next, get all the private and hidden forums + $private_forums = new WP_Query( array( + 'suppress_filters' => true, + 'nopaging' => true, + 'post_type' => bbp_get_forum_post_type(), + 'post_status' => bbp_get_private_status_id(), + 'fields' => 'ids' + ) ); + $hidden_forums = new WP_Query( array( + 'suppress_filters' => true, + 'nopaging' => true, + 'post_type' => bbp_get_forum_post_type(), + 'post_status' => bbp_get_hidden_status_id(), + 'fields' => 'ids' + ) ); + + // Bail if queries returned errors + if ( is_wp_error( $private_forums ) || is_wp_error( $hidden_forums ) ) + return array( 2, sprintf( $statement, $result ) ); + + update_option( '_bbp_private_forums', $private_forums->posts ); // Private forums + update_option( '_bbp_hidden_forums', $hidden_forums->posts ); // Hidden forums + + // Reset the $post global + wp_reset_postdata(); + + // Complete results + return array( 0, sprintf( $statement, __( 'Complete!', 'bbpress' ) ) ); +} + +/** + * Recaches the forum for each post + * + * @since bbPress (r3876) + * + * @uses wpdb::query() To run our recount sql queries + * @uses is_wp_error() To check if the executed query returned {@link WP_Error} + * @return array An array of the status code and the message + */ +function bbp_admin_repair_forum_meta() { + global $wpdb; + + $statement = __( 'Recalculating the forum for each post … %s', 'bbpress' ); + $result = __( 'Failed!', 'bbpress' ); + + // First, delete everything. + if ( is_wp_error( $wpdb->query( "DELETE FROM `$wpdb->postmeta` WHERE `meta_key` = '_bbp_forum_id';" ) ) ) + return array( 1, sprintf( $statement, $result ) ); + + // Next, give all the topics with replies the ID their last reply. + if ( is_wp_error( $wpdb->query( "INSERT INTO `$wpdb->postmeta` (`post_id`, `meta_key`, `meta_value`) + ( SELECT `forum`.`ID`, '_bbp_forum_id', `forum`.`post_parent` + FROM `$wpdb->posts` + AS `forum` + WHERE `forum`.`post_type` = 'forum' + GROUP BY `forum`.`ID` );" ) ) ) + return array( 2, sprintf( $statement, $result ) ); + + // Next, give all the topics with replies the ID their last reply. + if ( is_wp_error( $wpdb->query( "INSERT INTO `$wpdb->postmeta` (`post_id`, `meta_key`, `meta_value`) + ( SELECT `topic`.`ID`, '_bbp_forum_id', `topic`.`post_parent` + FROM `$wpdb->posts` + AS `topic` + WHERE `topic`.`post_type` = 'topic' + GROUP BY `topic`.`ID` );" ) ) ) + return array( 3, sprintf( $statement, $result ) ); + + // Next, give all the topics with replies the ID their last reply. + if ( is_wp_error( $wpdb->query( "INSERT INTO `$wpdb->postmeta` (`post_id`, `meta_key`, `meta_value`) + ( SELECT `reply`.`ID`, '_bbp_forum_id', `topic`.`post_parent` + FROM `$wpdb->posts` + AS `reply` + INNER JOIN `$wpdb->posts` + AS `topic` + ON `reply`.`post_parent` = `topic`.`ID` + WHERE `topic`.`post_type` = 'topic' + AND `reply`.`post_type` = 'reply' + GROUP BY `reply`.`ID` );" ) ) ) + return array( 4, sprintf( $statement, $result ) ); + + // Complete results + return array( 0, sprintf( $statement, __( 'Complete!', 'bbpress' ) ) ); +} + +/** + * Recaches the topic for each post + * + * @since bbPress (r3876) + * + * @uses wpdb::query() To run our recount sql queries + * @uses is_wp_error() To check if the executed query returned {@link WP_Error} + * @return array An array of the status code and the message + */ +function bbp_admin_repair_topic_meta() { + global $wpdb; + + $statement = __( 'Recalculating the topic for each post … %s', 'bbpress' ); + $result = __( 'Failed!', 'bbpress' ); + + // First, delete everything. + if ( is_wp_error( $wpdb->query( "DELETE FROM `$wpdb->postmeta` WHERE `meta_key` = '_bbp_topic_id';" ) ) ) + return array( 1, sprintf( $statement, $result ) ); + + // Next, give all the topics with replies the ID their last reply. + if ( is_wp_error( $wpdb->query( "INSERT INTO `$wpdb->postmeta` (`post_id`, `meta_key`, `meta_value`) + ( SELECT `topic`.`ID`, '_bbp_topic_id', `topic`.`ID` + FROM `$wpdb->posts` + AS `topic` + WHERE `topic`.`post_type` = 'topic' + GROUP BY `topic`.`ID` );" ) ) ) + return array( 3, sprintf( $statement, $result ) ); + + // Next, give all the topics with replies the ID their last reply. + if ( is_wp_error( $wpdb->query( "INSERT INTO `$wpdb->postmeta` (`post_id`, `meta_key`, `meta_value`) + ( SELECT `reply`.`ID`, '_bbp_topic_id', `topic`.`ID` + FROM `$wpdb->posts` + AS `reply` + INNER JOIN `$wpdb->posts` + AS `topic` + ON `reply`.`post_parent` = `topic`.`ID` + WHERE `topic`.`post_type` = 'topic' + AND `reply`.`post_type` = 'reply' + GROUP BY `reply`.`ID` );" ) ) ) + return array( 4, sprintf( $statement, $result ) ); + + // Complete results + return array( 0, sprintf( $statement, __( 'Complete!', 'bbpress' ) ) ); +} + +/** Reset ********************************************************************/ + +/** + * Admin reset page + * + * @since bbPress (r2613) + * + * @uses check_admin_referer() To verify the nonce and the referer + * @uses do_action() Calls 'admin_notices' to display the notices + * @uses screen_icon() To display the screen icon + * @uses wp_nonce_field() To add a hidden nonce field + */ +function bbp_admin_reset() { +?> + +
+ + + + +

Backup your database before proceeding.', 'bbpress' ); ?>

+ +
+ + + + + + + + + + + +
+
+
+
+
+
+
+
+
+
+
+
+ + +
+
+ +
+ + +
+
+
+ +get_results( "SELECT `ID` FROM `{$wpdb->posts}` WHERE `post_type` IN ('forum', 'topic', 'reply')", OBJECT_K ); + $sql_delete = "DELETE FROM `{$wpdb->posts}` WHERE `post_type` IN ('forum', 'topic', 'reply')"; + $result = is_wp_error( $wpdb->query( $sql_delete ) ) ? $failed : $success; + $messages[] = sprintf( $statement, $result ); + + + /** Post Meta *********************************************************/ + + if ( !empty( $sql_posts ) ) { + foreach( $sql_posts as $key => $value ) { + $sql_meta[] = $key; + } + $statement = __( 'Deleting Post Meta… %s', 'bbpress' ); + $sql_meta = implode( "', '", $sql_meta ); + $sql_delete = "DELETE FROM `{$wpdb->postmeta}` WHERE `post_id` IN ('{$sql_meta}');"; + $result = is_wp_error( $wpdb->query( $sql_delete ) ) ? $failed : $success; + $messages[] = sprintf( $statement, $result ); + } + + /** Topic Tags ********************************************************/ + + // @todo + + /** User Meta *********************************************************/ + + $statement = __( 'Deleting User Meta… %s', 'bbpress' ); + $sql_delete = "DELETE FROM `{$wpdb->usermeta}` WHERE `meta_key` LIKE '%%_bbp_%%';"; + $result = is_wp_error( $wpdb->query( $sql_delete ) ) ? $failed : $success; + $messages[] = sprintf( $statement, $result ); + + /** Converter *********************************************************/ + + $statement = __( 'Deleting Conversion Table… %s', 'bbpress' ); + $table_name = $wpdb->prefix . 'bbp_converter_translator'; + if ( $wpdb->get_var( "SHOW TABLES LIKE '{$table_name}'" ) == $table_name ) { + $wpdb->query( "DROP TABLE {$table_name}" ); + $result = $success; + } else { + $result = $failed; + } + $messages[] = sprintf( $statement, $result ); + + /** Options ***********************************************************/ + + $statement = __( 'Deleting Settings… %s', 'bbpress' ); + $sql_delete = bbp_delete_options(); + $messages[] = sprintf( $statement, $success ); + + /** Roles *************************************************************/ + + $statement = __( 'Deleting Roles and Capabilities… %s', 'bbpress' ); + $sql_delete = bbp_remove_roles(); + $sql_delete = bbp_remove_caps(); + $messages[] = sprintf( $statement, $success ); + + /** Output ************************************************************/ + + if ( count( $messages ) ) { + foreach ( $messages as $message ) { + bbp_admin_tools_feedback( $message ); + } + } + } +}