| Server IP : 172.67.134.116 / Your IP : 216.73.216.214 Web Server : Apache System : Linux server.rehabsharif.com 5.14.0-611.54.3.el9_7.x86_64 #1 SMP PREEMPT_DYNAMIC Thu May 7 16:31:24 EDT 2026 x86_64 User : nobi37te ( 1003) PHP Version : 8.2.33 Disable Function : exec,passthru,shell_exec,system MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : ON Directory : /home/nobi37te/public_html/wp-content/plugins/buddyboss-platform/bp-forums/admin/ |
Upload File : |
<?php
/**
* Forums Converter
*
* Based on the hard work of Adam Ellis at http://bbconverter.com
*
* @package BuddyBoss\Administration
*/
// Exit if accessed directly.
defined( 'ABSPATH' ) || exit;
/**
* Main BBP_Converter Class
*/
class BBP_Converter {
/**
* @var int Number of rows
*/
public $max = 0;
/**
* @var int Start
*/
public $start = 0;
/**
* @var int Step in converter process
*/
public $step = 0;
/**
* @var int Number of rows
*/
public $rows = 0;
/**
* @var int Maximum number of converter steps
*/
public $max_steps = 17;
/**
* @var int Number of rows in the current step
*/
public $rows_in_step = 0;
/**
* @var int Percent complete of current step
*/
public $step_percentage = 0;
/**
* @var int Percent complete of all step
*/
public $total_percentage = 0;
/**
* @var int Name of source forum platform
*/
public $platform = '';
/**
* @var BBP_Converter_Base Type of converter to use
*/
public $converter = null;
/**
* @var string Path to included platforms
*/
public $converters_dir = '';
/**
* @var array Map of steps to methods
*/
private $steps = array(
1 => 'sync_table',
2 => 'users',
3 => 'passwords',
4 => 'forums',
5 => 'forum_hierarchy',
6 => 'forum_subscriptions',
7 => 'topics',
8 => 'topics_authors',
9 => 'stickies',
10 => 'super_stickies',
11 => 'closed_topics',
12 => 'topic_tags',
13 => 'topic_subscriptions',
14 => 'topic_favorites',
15 => 'replies',
16 => 'reply_authors',
17 => 'reply_hierarchy',
);
/**
* The main Forums Converter loader
*
* @since bbPress (r3813)
* @uses BBP_Converter::includes() Include the required files
* @uses BBP_Converter::setup_actions() Setup the actions
*/
public function __construct() {
$this->setup_globals();
$this->setup_actions();
}
/**
* Admin globals
*
* @since 2.6.0 bbPress (r6598)
*/
public function setup_globals() {
$this->converters_dir = bbpress()->admin->admin_dir . 'converters/';
}
/**
* Setup the default actions
*
* @since bbPress (r3813)
* @uses add_action() To add various actions
*/
private function setup_actions() {
// Attach to the admin head with our ajax requests cycle and css.
add_action( 'admin_head-buddyboss_page_bbp-converter', array( $this, 'admin_head' ) );
// Attach the bbConverter admin settings action to the WordPress admin init action.
add_action( 'bbp_register_admin_settings', array( $this, 'register_admin_settings' ) );
// Attach to the admin ajax request to process cycles.
add_action( 'wp_ajax_bbp_converter_process', array( $this, 'process_callback' ) );
}
/**
* Register the settings
*
* @since bbPress (r3813)
* @uses add_settings_section() To add our own settings section
* @uses add_settings_field() To add various settings fields
* @uses register_setting() To register various settings
*/
public function register_admin_settings() {
global $wp_settings_sections;
// Add the main section.
add_settings_section( 'bbpress_converter_main', '', 'bbp_converter_setting_callback_main_section', 'bbpress_converter' );
if ( function_exists( 'bb_admin_icons' ) ) {
$meta_icon = bb_admin_icons( 'bbpress_converter_main' );
if ( ! empty( $meta_icon ) ) {
$wp_settings_sections['bbpress_converter']['bbpress_converter_main']['icon'] = $meta_icon;
}
}
// System Select.
add_settings_field( '_bbp_converter_platform', __( 'Select Platform', 'buddyboss' ), 'bbp_converter_setting_callback_platform', 'bbpress_converter', 'bbpress_converter_main' );
register_setting( 'bbpress_converter_main', '_bbp_converter_platform', 'sanitize_text_field' );
// Database Server.
add_settings_field( '_bbp_converter_db_server', __( 'Database Server', 'buddyboss' ), 'bbp_converter_setting_callback_dbserver', 'bbpress_converter', 'bbpress_converter_main' );
register_setting( 'bbpress_converter_main', '_bbp_converter_db_server', 'sanitize_text_field' );
// Database Server Port.
add_settings_field( '_bbp_converter_db_port', __( 'Database Port', 'buddyboss' ), 'bbp_converter_setting_callback_dbport', 'bbpress_converter', 'bbpress_converter_main' );
register_setting( 'bbpress_converter_main', '_bbp_converter_db_port', 'intval' );
// Database Name.
add_settings_field( '_bbp_converter_db_name', __( 'Database Name', 'buddyboss' ), 'bbp_converter_setting_callback_dbname', 'bbpress_converter', 'bbpress_converter_main' );
register_setting( 'bbpress_converter_main', '_bbp_converter_db_name', 'sanitize_text_field' );
// Database User.
add_settings_field( '_bbp_converter_db_user', __( 'Database User', 'buddyboss' ), 'bbp_converter_setting_callback_dbuser', 'bbpress_converter', 'bbpress_converter_main' );
register_setting( 'bbpress_converter_main', '_bbp_converter_db_user', 'sanitize_text_field' );
// Database Pass.
add_settings_field( '_bbp_converter_db_pass', __( 'Database Password', 'buddyboss' ), 'bbp_converter_setting_callback_dbpass', 'bbpress_converter', 'bbpress_converter_main' );
register_setting( 'bbpress_converter_main', '_bbp_converter_db_pass', 'sanitize_text_field' );
// Database Prefix.
add_settings_field( '_bbp_converter_db_prefix', __( 'Table Prefix', 'buddyboss' ), 'bbp_converter_setting_callback_dbprefix', 'bbpress_converter', 'bbpress_converter_main' );
register_setting( 'bbpress_converter_main', '_bbp_converter_db_prefix', 'sanitize_text_field' );
// Add the options section.
add_settings_section( 'bbpress_converter_opt', __( '', 'buddyboss' ), 'bbp_converter_setting_callback_options_section', 'bbpress_converter' );
// Rows Limit.
add_settings_field( '_bbp_converter_rows', __( 'Rows Limit', 'buddyboss' ), 'bbp_converter_setting_callback_rows', 'bbpress_converter', 'bbpress_converter_opt' );
register_setting( 'bbpress_converter_opt', '_bbp_converter_rows', 'intval' );
// Delay Time.
add_settings_field( '_bbp_converter_delay_time', __( 'Delay Time', 'buddyboss' ), 'bbp_converter_setting_callback_delay_time', 'bbpress_converter', 'bbpress_converter_opt' );
register_setting( 'bbpress_converter_opt', '_bbp_converter_delay_time', 'intval' );
// Convert Users ?
add_settings_field( '_bbp_converter_convert_users', __( 'Convert Users', 'buddyboss' ), 'bbp_converter_setting_callback_convert_users', 'bbpress_converter', 'bbpress_converter_opt' );
register_setting( 'bbpress_converter_opt', '_bbp_converter_convert_users', 'intval' );
// Restart.
add_settings_field( '_bbp_converter_restart', __( 'Start Over', 'buddyboss' ), 'bbp_converter_setting_callback_restart', 'bbpress_converter', 'bbpress_converter_opt' );
register_setting( 'bbpress_converter_opt', '_bbp_converter_restart', 'intval' );
// Clean.
add_settings_field( '_bbp_converter_clean', __( 'Purge Previous Import', 'buddyboss' ), 'bbp_converter_setting_callback_clean', 'bbpress_converter', 'bbpress_converter_opt' );
register_setting( 'bbpress_converter_opt', '_bbp_converter_clean', 'intval' );
}
/**
* Admin scripts
*
* @since bbPress (r3813)
*/
public function admin_head() {
// Enqueue scripts.
wp_enqueue_script( 'bbp-converter' );
// Localize JS.
wp_localize_script(
'bbp-converter',
'BBP_Converter',
array(
// Nonce.
'ajax_nonce' => wp_create_nonce( 'bbp_converter_process' ),
// UI State.
'state' => array(
'delay' => (int) get_option( '_bbp_converter_delay_time', 2 ),
'started' => (bool) get_option( '_bbp_converter_step', 0 ),
'running' => false,
'status' => false,
'step_percent' => $this->step_percentage,
'total_percent' => $this->total_percentage,
),
// Strings.
'strings' => array(
// Button text.
'button_start' => esc_html__( 'Start', 'buddyboss' ),
'button_continue' => esc_html__( 'Continue', 'buddyboss' ),
// Start button clicked.
'start_start' => esc_html__( 'Starting Import...', 'buddyboss' ),
'start_continue' => esc_html__( 'Continuing Import...', 'buddyboss' ),
// Import.
'import_complete' => esc_html__( 'Import Finished.', 'buddyboss' ),
'import_stopped_user' => esc_html__( 'Import Stopped (by User.)', 'buddyboss' ),
'import_error_halt' => esc_html__( 'Import Halted (Error.)', 'buddyboss' ),
'import_error_db' => esc_html__( 'Database Connection Failed.', 'buddyboss' ),
// Status.
'status_complete' => esc_html__( 'Finished', 'buddyboss' ),
'status_stopped' => esc_html__( 'Stopped', 'buddyboss' ),
'status_starting' => esc_html__( 'Starting', 'buddyboss' ),
'status_up_next' => esc_html__( 'Doing step %s...', 'buddyboss' ),
'status_counting' => esc_html__( 'Next in %s seconds...', 'buddyboss' ),
),
)
);
}
/**
* Callback processor
*
* @since bbPress (r3813)
*/
public function process_callback() {
// Ready the converter.
$this->check_access();
$this->maybe_set_memory();
$this->maybe_restart();
$this->setup_options();
$this->maybe_update_options();
// Bail if no converter.
if ( ! empty( $this->converter ) ) {
$this->do_steps();
}
}
/**
* Wrap the converter output in HTML, so styling can be applied
*
* @since 2.1.0 bbPress (r4052)
*
* @param string $output
*/
private function converter_response( $output = '' ) {
// Sanitize output.
$output = wp_kses_data( $output );
// Maybe prepend the step.
if ( ! empty( $this->step ) ) {
// Include percentage.
if ( ! empty( $this->rows_in_step ) ) {
$progress = sprintf( '<span class="step">%s.</span><span class="output">%s</span><span class="mini-step">%s</span>', $this->step, $output, $this->step_percentage . '%' );
// Don't include percentage.
} else {
$progress = sprintf( '<span class="step">%s.</span><span class="output">%s</span>', $this->step, $output );
}
// Raw text.
} else {
$progress = $output;
}
// Output.
wp_send_json_success(
array(
'query' => get_option( '_bbp_converter_query', '' ),
'current_step' => $this->step,
'final_step' => $this->max_steps,
'rows_in_step' => $this->rows_in_step,
'step_percent' => $this->step_percentage,
'total_percent' => $this->total_percentage,
'progress' => $progress,
)
);
}
/**
* Attempt to increase memory and set other system settings
*
* @since 2.6.0 bbPress (r6460)
*/
private function maybe_set_memory() {
// Filter args.
$r = apply_filters(
'bbp_converter_php_ini_overrides',
array(
'implicit_flush' => '1',
'memory_limit' => '256M',
'max_execution_time' => HOUR_IN_SECONDS * 6,
)
);
// Get disabled PHP functions (to avoid using them).
$disabled = explode( ',', @ini_get( 'disable_functions' ) );
// Maybe avoid terminating when the client goes away (if function is not disabled).
if ( ! in_array( 'ignore_user_abort', $disabled, true ) ) {
@ignore_user_abort( true );
}
// Maybe set memory & time limits, and flush style (if function is not disabled).
if ( ! in_array( 'ini_set', $disabled, true ) ) {
foreach ( $r as $key => $value ) {
@ini_set( $key, $value );
}
}
}
/**
* Maybe restart the converter
*
* @since 2.6.0 bbPress (r6460)
*/
private function maybe_restart() {
// Save step and count so that it can be restarted.
if ( ! get_option( '_bbp_converter_step' ) || ! empty( $_POST['_bbp_converter_restart'] ) ) {
$this->step = 1;
$this->start = 0;
$this->step_percentage = 0;
$this->total_percentage = 0;
$this->rows_in_step = 0;
$this->maybe_update_options();
}
}
/**
* Maybe update options
*
* @since 2.6.0 bbPress (r6637)
*/
private function maybe_update_options() {
// Default options
$options = array(
// Step & Start.
'_bbp_converter_step' => $this->step,
'_bbp_converter_start' => $this->start,
'_bbp_converter_rows_in_step' => $this->rows_in_step,
// Halt.
'_bbp_converter_halt' => ! empty( $_POST['_bbp_converter_halt'] )
? (int) $_POST['_bbp_converter_halt']
: 0,
// Rows (bound between 1 and 5000).
'_bbp_converter_rows' => ! empty( $_POST['_bbp_converter_rows'] )
? min( max( (int) $_POST['_bbp_converter_rows'], 1 ), 5000 )
: 0,
// Platform.
'_bbp_converter_platform' => ! empty( $_POST['_bbp_converter_platform'] )
? sanitize_text_field( $_POST['_bbp_converter_platform'] )
: '',
// Convert Users.
'_bbp_converter_convert_users' => ! empty( $_POST['_bbp_converter_convert_users'] ) ? (bool) $_POST['_bbp_converter_convert_users'] : false,
// DB User.
'_bbp_converter_db_user' => ! empty( $_POST['_bbp_converter_db_user'] )
? sanitize_text_field( $_POST['_bbp_converter_db_user'] )
: '',
// DB Password.
'_bbp_converter_db_pass' => ! empty( $_POST['_bbp_converter_db_pass'] )
? sanitize_text_field( $_POST['_bbp_converter_db_pass'] )
: '',
// DB Name.
'_bbp_converter_db_name' => ! empty( $_POST['_bbp_converter_db_name'] )
? sanitize_text_field( $_POST['_bbp_converter_db_name'] )
: '',
// DB Server.
'_bbp_converter_db_server' => ! empty( $_POST['_bbp_converter_db_server'] )
? sanitize_text_field( $_POST['_bbp_converter_db_server'] )
: '',
// DB Port.
'_bbp_converter_db_port' => ! empty( $_POST['_bbp_converter_db_port'] )
? (int) sanitize_text_field( $_POST['_bbp_converter_db_port'] )
: '',
// DB Table Prefix.
'_bbp_converter_db_prefix' => ! empty( $_POST['_bbp_converter_db_prefix'] )
? sanitize_text_field( $_POST['_bbp_converter_db_prefix'] )
: '',
);
// Update/delete options
foreach ( $options as $key => $value ) {
$new_val = update_option( $key, $value );
}
}
/**
* Setup converter options
*
* @since 2.6.0 bbPress (r6460)
*/
private function setup_options() {
// Set starting point & rows.
$this->step = (int) get_option( '_bbp_converter_step', 1 );
$this->start = (int) get_option( '_bbp_converter_start', 0 );
$this->rows = (int) get_option( '_bbp_converter_rows', 100 );
$this->rows_in_step = (int) get_option( '_bbp_converter_rows_in_step', 0 );
// Set boundaries.
$this->max = ( $this->start + $this->rows ) - 1;
// Set platform.
$this->platform = get_option( '_bbp_converter_platform' );
// Total percentage.
$this->total_percentage = round( ( $this->step / $this->max_steps ) * 100, 2 );
// Total mini steps.
if ( $this->rows_in_step > 0 ) {
$total_mini_steps = ceil( $this->rows_in_step / $this->rows );
$current_mini_step = ceil( $this->start / $this->rows );
$this->step_percentage = round( ( $current_mini_step / $total_mini_steps ) * 100, 2 );
} else {
$this->step_percentage = 0;
}
// Maybe include the appropriate converter.
if ( ! empty( $this->platform ) ) {
$this->converter = bbp_new_converter( $this->platform );
}
}
/**
* Check that user can access the converter
*
* @since 2.6.0 bbPress (r6460)
*/
private function check_access() {
// Bail if user cannot view import page.
if ( ! current_user_can( 'bbp_tools_import_page' ) ) {
wp_die( '0' );
}
// Verify intent.
check_ajax_referer( 'bbp_converter_process' );
}
/**
* Reset the converter
*
* @since 2.6.0 bbPress (r6460)
*/
private function reset() {
update_option( '_bbp_converter_step', 0 );
update_option( '_bbp_converter_start', 0 );
update_option( '_bbp_converter_rows_in_step', 0 );
update_option( '_bbp_converter_query', '' );
}
/**
* Bump the step and reset the start
*
* @since 2.6.0 bbPress (r6460)
*/
private function bump_step() {
// Next step.
$next_step = (int) ( $this->step + 1 );
// Don't let step go over max.
$step = ( $next_step <= $this->max_steps )
? $next_step
: 0;
// Update step and start at 0.
update_option( '_bbp_converter_step', $step );
update_option( '_bbp_converter_start', 0 );
update_option( '_bbp_converter_rows_in_step', 0 );
}
/**
* Bump the start within the current step
*
* @since 2.6.0 bbPress (r6460)
*/
private function bump_start() {
// Set rows in step from option.
$this->rows_in_step = get_option( '_bbp_converter_rows_in_step', 0 );
// Get rows to start from.
$start = (int) ( $this->start + $this->rows );
// Enforce maximum if exists.
if ( $this->rows_in_step > 0 ) {
// Start cannot be larger than total rows.
if ( $start > $this->rows_in_step ) {
$start = $this->rows_in_step;
}
// Max can't be greater than total rows.
if ( $this->max > $this->rows_in_step ) {
$this->max = $this->rows_in_step;
}
}
// Update the start option.
update_option( '_bbp_converter_start', $start );
}
/**
* Do the converter step
*
* @since 2.6.0 bbPress (r6460)
*/
private function do_steps() {
// Step exists in map, and method exists.
if ( isset( $this->steps[ $this->step ] ) && method_exists( $this, "step_{$this->steps[ $this->step ]}" ) ) {
return call_user_func( array( $this, "step_{$this->steps[ $this->step ]}" ) );
}
// Done!
$this->step_done();
}
/** Steps *****************************************************************/
/**
* Maybe clean the sync table
*
* @since 2.6.0 bbPress (r6513)
*/
private function step_sync_table() {
if ( true === $this->converter->clean ) {
if ( $this->converter->clean() ) {
$this->bump_step();
$this->sync_table( true );
empty( $this->start )
? $this->converter_response( esc_html__( 'Readying sync-table', 'buddyboss' ) )
: $this->converter_response( esc_html__( 'Sync-table ready', 'buddyboss' ) );
} else {
$this->bump_start();
$this->converter_response( sprintf( esc_html__( 'Deleting previously converted data (%1$s through %2$s)', 'buddyboss' ), $this->start, $this->max ) );
}
$this->converter->clean = false;
} else {
$this->bump_step();
$this->sync_table( false );
$this->converter_response( esc_html__( 'Skipping sync-table clean-up', 'buddyboss' ) );
}
}
/**
* Maybe convert users
*
* @since 2.6.0 bbPress (r6513)
*/
private function step_users() {
if ( true === $this->converter->convert_users ) {
if ( $this->converter->convert_users( $this->start ) ) {
$this->bump_step();
empty( $this->start )
? $this->converter_response( esc_html__( 'No users to import', 'buddyboss' ) )
: $this->converter_response( esc_html__( 'All users imported', 'buddyboss' ) );
} else {
$this->bump_start();
$this->converter_response( sprintf( esc_html__( 'Converting users (%1$s through %2$s of %3$s)', 'buddyboss' ), $this->start, $this->max, $this->rows_in_step ) );
}
} else {
$this->bump_step();
$this->converter_response( esc_html__( 'Skipping user clean-up', 'buddyboss' ) );
}
}
/**
* Maybe clean up passwords
*
* @since 2.6.0 bbPress (r6513)
*/
private function step_passwords() {
if ( true === $this->converter->convert_users ) {
if ( $this->converter->clean_passwords( $this->start ) ) {
$this->bump_step();
empty( $this->start )
? $this->converter_response( esc_html__( 'No passwords to clear', 'buddyboss' ) )
: $this->converter_response( esc_html__( 'All passwords cleared', 'buddyboss' ) );
} else {
$this->bump_start();
$this->converter_response( sprintf( esc_html__( 'Delete default WordPress user passwords (%1$s through %2$s)', 'buddyboss' ), $this->start, $this->max ) );
}
} else {
$this->bump_step();
$this->converter_response( esc_html__( 'Skipping password clean-up', 'buddyboss' ) );
}
}
/**
* Maybe convert forums
*
* @since 2.6.0 bbPress (r6513)
*/
private function step_forums() {
if ( $this->converter->convert_forums( $this->start ) ) {
$this->bump_step();
empty( $this->start )
? $this->converter_response( esc_html__( 'No forums to import', 'buddyboss' ) )
: $this->converter_response( esc_html__( 'All forums imported', 'buddyboss' ) );
} else {
$this->bump_start();
$this->converter_response( sprintf( esc_html__( 'Converting forums (%1$s through %2$s of %3$s)', 'buddyboss' ), $this->start, $this->max, $this->rows_in_step ) );
}
}
/**
* Maybe walk the forum hierarchy
*
* @since 2.6.0 bbPress (r6513)
*/
private function step_forum_hierarchy() {
if ( $this->converter->convert_forum_parents( $this->start ) ) {
$this->bump_step();
empty( $this->start )
? $this->converter_response( esc_html__( 'No forum parents to import', 'buddyboss' ) )
: $this->converter_response( esc_html__( 'All forum parents imported', 'buddyboss' ) );
} else {
$this->bump_start();
$this->converter_response( sprintf( esc_html__( 'Calculating forum hierarchy (%1$s through %2$s of %3$s)', 'buddyboss' ), $this->start, $this->max, $this->rows_in_step ) );
}
}
/**
* Maybe convert forum subscriptions
*
* @since 2.6.0 bbPress (r6513)
*/
private function step_forum_subscriptions() {
if ( $this->converter->convert_forum_subscriptions( $this->start ) ) {
$this->bump_step();
empty( $this->start )
? $this->converter_response( esc_html__( 'No forum subscriptions to import', 'buddyboss' ) )
: $this->converter_response( esc_html__( 'All forum subscriptions imported', 'buddyboss' ) );
} else {
$this->bump_start();
$this->converter_response( sprintf( esc_html__( 'Converting forum subscriptions (%1$s through %2$s of %3$s)', 'buddyboss' ), $this->start, $this->max, $this->rows_in_step ) );
}
}
/**
* Maybe convert topics
*
* @since 2.6.0 bbPress (r6513)
*/
private function step_topics() {
if ( $this->converter->convert_topics( $this->start ) ) {
$this->bump_step();
empty( $this->start )
? $this->converter_response( esc_html__( 'No topics to import', 'buddyboss' ) )
: $this->converter_response( esc_html__( 'All topics imported', 'buddyboss' ) );
} else {
$this->bump_start();
$this->converter_response( sprintf( esc_html__( 'Converting topics (%1$s through %2$s of %3$s)', 'buddyboss' ), $this->start, $this->max, $this->rows_in_step ) );
}
}
/**
* Maybe convert topic authors (anonymous)
*
* @since 2.6.0 bbPress (r6513)
*/
private function step_topics_authors() {
if ( $this->converter->convert_anonymous_topic_authors( $this->start ) ) {
$this->bump_step();
empty( $this->start )
? $this->converter_response( esc_html__( 'No anonymous topic authors to import', 'buddyboss' ) )
: $this->converter_response( esc_html__( 'All anonymous topic authors imported', 'buddyboss' ) );
} else {
$this->bump_start();
$this->converter_response( sprintf( esc_html__( 'Converting anonymous topic authors (%1$s through %2$s of %3$s)', 'buddyboss' ), $this->start, $this->max, $this->rows_in_step ) );
}
}
/**
* Maybe convert sticky topics (not super stickies)
*
* @since 2.6.0 bbPress (r6513)
*/
private function step_stickies() {
if ( $this->converter->convert_topic_stickies( $this->start ) ) {
$this->bump_step();
empty( $this->start )
? $this->converter_response( esc_html__( 'No stickies to import', 'buddyboss' ) )
: $this->converter_response( esc_html__( 'All stickies imported', 'buddyboss' ) );
} else {
$this->bump_start();
$this->converter_response( sprintf( esc_html__( 'Calculating topic stickies (%1$s through %2$s of %3$s)', 'buddyboss' ), $this->start, $this->max, $this->rows_in_step ) );
}
}
/**
* Maybe convert super-sticky topics (not per-forum)
*
* @since 2.6.0 bbPress (r6513)
*/
private function step_super_stickies() {
if ( $this->converter->convert_topic_super_stickies( $this->start ) ) {
$this->bump_step();
empty( $this->start )
? $this->converter_response( esc_html__( 'No super stickies to import', 'buddyboss' ) )
: $this->converter_response( esc_html__( 'All super stickies imported', 'buddyboss' ) );
} else {
$this->bump_start();
$this->converter_response( sprintf( esc_html__( 'Calculating topic super stickies (%1$s through %2$s of %3$s)', 'buddyboss' ), $this->start, $this->max, $this->rows_in_step ) );
}
}
/**
* Maybe close converted topics
*
* @since 2.6.0 bbPress (r6513)
*/
private function step_closed_topics() {
if ( $this->converter->convert_topic_closed_topics( $this->start ) ) {
$this->bump_step();
empty( $this->start )
? $this->converter_response( esc_html__( 'No closed topics to import', 'buddyboss' ) )
: $this->converter_response( esc_html__( 'All closed topics imported', 'buddyboss' ) );
} else {
$this->bump_start();
$this->converter_response( sprintf( esc_html__( 'Calculating closed topics (%1$s through %2$s of %3$s)', 'buddyboss' ), $this->start, $this->max, $this->rows_in_step ) );
}
}
/**
* Maybe convert topic tags
*
* @since 2.6.0 bbPress (r6513)
*/
private function step_topic_tags() {
if ( $this->converter->convert_tags( $this->start ) ) {
$this->bump_step();
empty( $this->start )
? $this->converter_response( esc_html__( 'No topic tags to import', 'buddyboss' ) )
: $this->converter_response( esc_html__( 'All topic tags imported', 'buddyboss' ) );
} else {
$this->bump_start();
$this->converter_response( sprintf( esc_html__( 'Converting topic tags (%1$s through %2$s of %3$s)', 'buddyboss' ), $this->start, $this->max, $this->rows_in_step ) );
}
}
/**
* Maybe convert topic subscriptions
*
* @since 2.6.0 bbPress (r6513)
*/
private function step_topic_subscriptions() {
if ( $this->converter->convert_topic_subscriptions( $this->start ) ) {
$this->bump_step();
empty( $this->start )
? $this->converter_response( esc_html__( 'No topic subscriptions to import', 'buddyboss' ) )
: $this->converter_response( esc_html__( 'All topic subscriptions imported', 'buddyboss' ) );
} else {
$this->bump_start();
$this->converter_response( sprintf( esc_html__( 'Converting topic subscriptions (%1$s through %2$s of %3$s)', 'buddyboss' ), $this->start, $this->max, $this->rows_in_step ) );
}
}
/**
* Maybe convert topic favorites
*
* @since 2.6.0 bbPress (r6513)
*/
private function step_topic_favorites() {
if ( $this->converter->convert_favorites( $this->start ) ) {
$this->bump_step();
empty( $this->start )
? $this->converter_response( esc_html__( 'No favorites to import', 'buddyboss' ) )
: $this->converter_response( esc_html__( 'All favorites imported', 'buddyboss' ) );
} else {
$this->bump_start();
$this->converter_response( sprintf( esc_html__( 'Converting favorites (%1$s through %2$s of %3$s)', 'buddyboss' ), $this->start, $this->max, $this->rows_in_step ) );
}
}
/**
* Maybe convert replies
*
* @since 2.6.0 bbPress (r6513)
*/
private function step_replies() {
if ( $this->converter->convert_replies( $this->start ) ) {
$this->bump_step();
empty( $this->start )
? $this->converter_response( esc_html__( 'No replies to import', 'buddyboss' ) )
: $this->converter_response( esc_html__( 'All replies imported', 'buddyboss' ) );
} else {
$this->bump_start();
$this->converter_response( sprintf( esc_html__( 'Converting replies (%1$s through %2$s of %3$s)', 'buddyboss' ), $this->start, $this->max, $this->rows_in_step ) );
}
}
/**
* Maybe convert reply authors (anonymous)
*
* @since 2.6.0 bbPress (r6513)
*/
private function step_reply_authors() {
if ( $this->converter->convert_anonymous_reply_authors( $this->start ) ) {
$this->bump_step();
empty( $this->start )
? $this->converter_response( esc_html__( 'No anonymous reply authors to import', 'buddyboss' ) )
: $this->converter_response( esc_html__( 'All anonymous reply authors imported', 'buddyboss' ) );
} else {
$this->bump_start();
$this->converter_response( sprintf( esc_html__( 'Converting anonymous reply authors (%1$s through %2$s of %3$s)', 'buddyboss' ), $this->start, $this->max, $this->rows_in_step ) );
}
}
/**
* Maybe convert the threaded reply hierarchy
*
* @since 2.6.0 bbPress (r6513)
*/
private function step_reply_hierarchy() {
if ( $this->converter->convert_reply_to_parents( $this->start ) ) {
$this->bump_step();
empty( $this->start )
? $this->converter_response( esc_html__( 'No threaded replies to import', 'buddyboss' ) )
: $this->converter_response( esc_html__( 'All threaded replies imported', 'buddyboss' ) );
} else {
$this->bump_start();
$this->converter_response( sprintf( esc_html__( 'Calculating threaded replies parents (%1$s through %2$s of %3$s)', 'buddyboss' ), $this->start, $this->max, $this->rows_in_step ) );
}
}
/**
* Done!
*
* @since 2.6.0 bbPress (r6513)
*/
private function step_done() {
$this->reset();
$this->converter_response( esc_html__( 'Import Finished', 'buddyboss' ) );
}
/** Helper Table **********************************************************/
/**
* Create Tables for fast syncing
*
* @since 2.1.0 bbPress (r3813)
*/
public static function sync_table( $drop = false ) {
// Setup DB.
$bbp_db = bbp_db();
$table_name = $bbp_db->prefix . 'bbp_converter_translator';
$table_exists = $bbp_db->get_var( "SHOW TABLES LIKE '{$table_name}'" ) === $table_name;
// Maybe drop the sync table.
if ( ( true === $drop ) && ( true === $table_exists ) ) {
$bbp_db->query( "DROP TABLE {$table_name}" );
}
// Maybe include the upgrade functions, for dbDelta().
if ( ! function_exists( 'dbDelta' ) ) {
require_once ABSPATH . '/wp-admin/includes/upgrade.php';
}
// Defaults.
$sql = array();
$charset_collate = '';
// https://bbpress.trac.wordpress.org/ticket/3145
$max_index_length = 75;
// Maybe override the character set.
if ( ! empty( $bbp_db->charset ) ) {
$charset_collate .= "DEFAULT CHARACTER SET {$bbp_db->charset}";
}
// Maybe override the collation.
if ( ! empty( $bbp_db->collate ) ) {
$charset_collate .= " COLLATE {$bbp_db->collate}";
}
/** Translator */
$sql[] = "CREATE TABLE {$table_name} (
meta_id mediumint(8) unsigned not null auto_increment,
value_type varchar(25) null,
value_id bigint(20) unsigned not null default '0',
meta_key varchar({$max_index_length}) null,
meta_value varchar({$max_index_length}) null,
PRIMARY KEY (meta_id),
KEY value_id (value_id),
KEY meta_join (meta_key({$max_index_length}), meta_value({$max_index_length}))
) {$charset_collate}";
dbDelta( $sql );
}
}
/**
* Base class to be extended by specific individual importers
*
* @since bbPress (r3813)
*/
abstract class BBP_Converter_Base {
/**
* @var array() This is the field mapping array to process.
*/
protected $field_map = array();
/**
* @var object This is the connection to the WordPress database.
*/
protected $wpdb;
/**
* @var object This is the connection to the other platforms database.
*/
protected $opdb;
/**
* @var int Maximum number of rows to convert at 1 time. Default 100.
*/
protected $max_rows = 100;
/**
* @var array() Map of topic to forum. It is for optimization.
*/
protected $map_topicid_to_forumid = array();
/**
* @var array() Map of from old forum ids to new forum ids. It is for optimization.
*/
protected $map_forumid = array();
/**
* @var array() Map of from old topic ids to new topic ids. It is for optimization.
*/
protected $map_topicid = array();
/**
* @var array() Map of from old reply_to ids to new reply_to ids. It is for optimization.
*/
protected $map_reply_to = array();
/**
* @var array() Map of from old user ids to new user ids. It is for optimization.
*/
protected $map_userid = array();
/**
* @var string This is the charset for your wp database.
*/
public $charset = '';
/**
* @var boolean Sync table available.
*/
public $sync_table = false;
/**
* @var string Sync table name.
*/
public $sync_table_name = '';
/**
* @var bool Whether users should be converted or not. Default false.
*/
public $convert_users = false;
/**
* @var bool Whether to clean up any old converter data. Default false.
*/
public $clean = false;
/**
* @var array Custom BBCode class properties in a key => value format
*/
public $bbcode_parser_properties = array();
/** Methods ***************************************************************/
/**
* This is the constructor and it connects to the platform databases.
*/
public function __construct() {
$this->init();
$this->setup_globals();
}
/**
* Initialize the converter
*
* @since 2.1.0
*/
private function init() {
/** BBCode Parse Properties */
// Setup smiley URL & path.
$this->bbcode_parser_properties = array(
'smiley_url' => includes_url( 'images/smilies' ),
'smiley_dir' => '/' . WPINC . '/images/smilies',
);
/** Sanitize Options */
$this->clean = ! empty( $_POST['_bbp_converter_clean'] );
$this->convert_users = (bool) get_option( '_bbp_converter_convert_users', false );
$this->halt = (bool) get_option( '_bbp_converter_halt', 0 );
$this->max_rows = (int) get_option( '_bbp_converter_rows', 100 );
/** Sanitize Connection */
$db_user = get_option( '_bbp_converter_db_user', DB_USER );
$db_pass = get_option( '_bbp_converter_db_pass', DB_PASSWORD );
$db_name = get_option( '_bbp_converter_db_name', DB_NAME );
$db_host = get_option( '_bbp_converter_db_server', DB_HOST );
$db_port = get_option( '_bbp_converter_db_port', '' );
$db_prefix = get_option( '_bbp_converter_db_prefix', '' );
// Maybe add port to server.
if ( ! empty( $db_port ) && ! empty( $db_host ) && ! str_contains( $db_host, ':' ) ) {
$db_host = "{$db_host}:{$db_port}";
}
/** Get database connections */
// Setup WordPress Database.
$this->wpdb = bbp_db();
// Setup old forum Database.
$this->opdb = new wpdb( $db_user, $db_pass, $db_name, $db_host );
// Connection failed.
if ( ! $this->opdb->db_connect( false ) ) {
$error = new WP_Error( 'bbp_converter_db_connection_failed', esc_html__( 'Database connection failed.', 'buddyboss' ) );
wp_send_json_error( $error );
}
// Maybe setup the database prefix.
$this->opdb->prefix = $db_prefix;
/**
* Don't wp_die() uncontrollably
*/
$this->wpdb->show_errors( false );
$this->opdb->show_errors( false );
/**
* Syncing
*/
$this->sync_table_name = $this->wpdb->prefix . 'bbp_converter_translator';
$this->sync_table = $this->sync_table_name === $this->wpdb->get_var( "SHOW TABLES LIKE '{$this->sync_table_name}'" );
/**
* Character set
*/
$this->charset = ! empty( $this->wpdb->charset )
? $this->wpdb->charset
: 'UTF8';
/**
* Default mapping.
*/
/** Forum Section */
$this->field_map[] = array(
'to_type' => 'forum',
'to_fieldname' => 'post_status',
'default' => 'publish',
);
$this->field_map[] = array(
'to_type' => 'forum',
'to_fieldname' => 'comment_status',
'default' => 'closed',
);
$this->field_map[] = array(
'to_type' => 'forum',
'to_fieldname' => 'ping_status',
'default' => 'closed',
);
$this->field_map[] = array(
'to_type' => 'forum',
'to_fieldname' => 'post_type',
'default' => 'forum',
);
/** Topic Section */
$this->field_map[] = array(
'to_type' => 'topic',
'to_fieldname' => 'post_status',
'default' => 'publish',
);
$this->field_map[] = array(
'to_type' => 'topic',
'to_fieldname' => 'comment_status',
'default' => 'closed',
);
$this->field_map[] = array(
'to_type' => 'topic',
'to_fieldname' => 'ping_status',
'default' => 'closed',
);
$this->field_map[] = array(
'to_type' => 'topic',
'to_fieldname' => 'post_type',
'default' => 'topic',
);
/** Post Section */
$this->field_map[] = array(
'to_type' => 'reply',
'to_fieldname' => 'post_status',
'default' => 'publish',
);
$this->field_map[] = array(
'to_type' => 'reply',
'to_fieldname' => 'comment_status',
'default' => 'closed',
);
$this->field_map[] = array(
'to_type' => 'reply',
'to_fieldname' => 'ping_status',
'default' => 'closed',
);
$this->field_map[] = array(
'to_type' => 'reply',
'to_fieldname' => 'post_type',
'default' => 'reply',
);
/** User Section */
$this->field_map[] = array(
'to_type' => 'user',
'to_fieldname' => 'role',
'default' => get_option( 'default_role' ),
);
}
/**
* Setup global values
*/
public function setup_globals() {}
/**
* Convert Forums
*/
public function convert_forums( $start = 1 ) {
return $this->convert_table( 'forum', $start );
}
/**
* Convert Topics / Threads
*/
public function convert_topics( $start = 1 ) {
return $this->convert_table( 'topic', $start );
}
/**
* Convert Posts
*/
public function convert_replies( $start = 1 ) {
return $this->convert_table( 'reply', $start );
}
/**
* Convert Users
*/
public function convert_users( $start = 1 ) {
return $this->convert_table( 'user', $start );
}
/**
* Convert Topic Tags
*/
public function convert_tags( $start = 1 ) {
return $this->convert_table( 'tags', $start );
}
/**
* Convert Forum Subscriptions
*/
public function convert_forum_subscriptions( $start = 1 ) {
return $this->convert_table( 'forum_subscriptions', $start );
}
/**
* Convert Topic Subscriptions
*/
public function convert_topic_subscriptions( $start = 1 ) {
return $this->convert_table( 'topic_subscriptions', $start );
}
/**
* Convert Favorites
*/
public function convert_favorites( $start = 1 ) {
return $this->convert_table( 'favorites', $start );
}
/**
* Convert Table
*
* @param string to type
* @param int Start row
*/
public function convert_table( $to_type, $start ) {
// Set some defaults.
$has_insert = false;
$from_tablename = '';
$field_list = $from_tables = $tablefield_array = array();
// Toggle Table Name based on $to_type (destination).
switch ( $to_type ) {
case 'user':
$tablename = $this->wpdb->users;
break;
case 'tags':
$tablename = '';
break;
case 'favorites':
case 'topic_subscriptions':
case 'forum_subscriptions':
$tablename = $this->wpdb->postmeta;
break;
default:
$tablename = $this->wpdb->posts;
}
// Get the fields from the destination table.
if ( ! empty( $tablename ) ) {
$tablefield_array = $this->get_fields( $tablename );
}
/** Step 1 */
// Loop through the field maps, and look for to_type matches.
foreach ( $this->field_map as $item ) {
// Yay a match, and we have a from table, too.
if (
( $item['to_type'] === $to_type ) &&
! empty( $item['from_tablename'] ) &&
bb_check_table_exists( $this->opdb, $this->opdb->prefix . $item['from_tablename'] )
) {
// $from_tablename was set from a previous loop iteration.
if ( ! empty( $from_tablename ) ) {
// Doing some joining.
if ( ! in_array( $item['from_tablename'], $from_tables, true ) && in_array( $item['join_tablename'], $from_tables, true ) ) {
$from_tablename .= ' ' . $item['join_type'] . ' JOIN ' . $this->opdb->prefix . $item['from_tablename'] . ' AS ' . $item['from_tablename'] . ' ' . $item['join_expression'];
}
// $from_tablename needs to be set.
} else {
$from_tablename = $item['from_tablename'] . ' AS ' . $item['from_tablename'];
}
// Specific FROM expression data used.
if ( ! empty( $item['from_expression'] ) ) {
// No 'WHERE' in expression.
if ( stripos( $from_tablename, 'WHERE' ) === false ) {
$from_tablename .= ' ' . $item['from_expression'];
// 'WHERE' in expression, so replace with 'AND'.
} else {
$from_tablename .= ' ' . str_replace( 'WHERE', 'AND', $item['from_expression'] );
}
}
// Add tablename and fieldname to arrays, formatted for querying.
$from_tables[] = $item['from_tablename'];
$field_list[] = 'convert(' . $item['from_tablename'] . '.' . $item['from_fieldname'] . ' USING "' . $this->charset . '") AS ' . $item['from_fieldname'];
}
}
/** Step 2 */
// We have a $from_tablename, so we want to get some data to convert.
if ( ! empty( $from_tablename ) ) {
// Update rows.
$this->count_rows_by_table( "{$this->opdb->prefix}{$from_tablename}" );
// Get some data from the old forums.
$field_list = array_unique( $field_list );
$fields = implode( ',', $field_list );
$forum_query = "SELECT {$fields} FROM {$this->opdb->prefix}{$from_tablename} LIMIT {$start}, {$this->max_rows}";
// Set this query as the last one ran.
$this->update_query( $forum_query );
// Get results as an array
$forum_array = $this->opdb->get_results( $forum_query, ARRAY_A );
// Query returned some results.
if ( ! empty( $forum_array ) ) {
// Loop through results.
foreach ( (array) $forum_array as $forum ) {
// Reset some defaults.
$insert_post = $insert_postmeta = $insert_data = array();
// Loop through field map, again...
foreach ( $this->field_map as $row ) {
// Types match and to_fieldname is present. This means
// we have some work to do here.
if ( ( $row['to_type'] === $to_type ) && isset( $row['to_fieldname'] ) ) {
// This row has a destination that matches one of the
// columns in this table.
if ( in_array( $row['to_fieldname'], $tablefield_array, true ) ) {
// Allows us to set default fields.
if ( isset( $row['default'] ) ) {
$insert_post[ $row['to_fieldname'] ] = $row['default'];
// Translates a field from the old forum.
} elseif ( isset( $row['callback_method'] ) ) {
if ( ( 'callback_userid' === $row['callback_method'] ) && ( false === $this->convert_users ) ) {
$insert_post[ $row['to_fieldname'] ] = $forum[ $row['from_fieldname'] ];
} else {
$insert_post[ $row['to_fieldname'] ] = call_user_func_array( array( $this, $row['callback_method'] ), array( $forum[ $row['from_fieldname'] ], $forum ) );
}
// Maps the field from the old forum.
} else {
$insert_post[ $row['to_fieldname'] ] = $forum[ $row['from_fieldname'] ];
}
// Destination field is not empty, so we might need
// to do some extra work or set a default.
} elseif ( ! empty( $row['to_fieldname'] ) ) {
// Allows us to set default fields.
if ( isset( $row['default'] ) ) {
$insert_postmeta[ $row['to_fieldname'] ] = $row['default'];
// Translates a field from the old forum.
} elseif ( isset( $row['callback_method'] ) ) {
if ( ( $row['callback_method'] === 'callback_userid' ) && ( false === $this->convert_users ) ) {
$insert_postmeta[ $row['to_fieldname'] ] = $forum[ $row['from_fieldname'] ];
} else {
$insert_postmeta[ $row['to_fieldname'] ] = call_user_func_array( array( $this, $row['callback_method'] ), array( $forum[ $row['from_fieldname'] ], $forum ) );
}
// Maps the field from the old forum.
} else {
$insert_postmeta[ $row['to_fieldname'] ] = $forum[ $row['from_fieldname'] ];
}
}
}
}
/** Step 3 */
// Something to insert into the destination field.
switch ( $to_type ) {
/** New user */
case 'user':
if ( 0 === count( $insert_post ) ) {
break;
}
if ( username_exists( $insert_post['user_login'] ) ) {
$insert_post['user_login'] = "imported_{$insert_post['user_login']}";
}
if ( email_exists( $insert_post['user_email'] ) ) {
$insert_post['user_email'] = "imported_{$insert_post['user_email']}";
}
if ( empty( $insert_post['user_pass'] ) ) {
$insert_post['user_pass'] = '';
}
// Internally re-calls _exists() checks above.
// Also checks for existing nicename.
$post_id = wp_insert_user( $insert_post );
if ( is_numeric( $post_id ) ) {
foreach ( $insert_postmeta as $key => $value ) {
add_user_meta( $post_id, $key, $value, true );
if ( '_id' == substr( $key, -3 ) && ( true === $this->sync_table ) ) {
$this->wpdb->insert(
$this->sync_table_name,
array(
'value_type' => 'user',
'value_id' => $post_id,
'meta_key' => $key,
'meta_value' => $value,
)
);
}
}
}
break;
/** New Topic-Tag */
case 'tags':
if ( 0 === count( $insert_postmeta ) ) {
break;
}
$post_id = wp_set_object_terms( $insert_postmeta['objectid'], $insert_postmeta['name'], 'topic-tag', true );
$term = get_term_by( 'name', $insert_postmeta['name'], 'topic-tag' );
if ( false !== $term ) {
wp_update_term(
$term->term_id,
'topic-tag',
array(
'description' => $insert_postmeta['description'],
'slug' => $insert_postmeta['slug'],
)
);
}
break;
/** Forum Subscriptions */
case 'forum_subscriptions':
if ( 0 === count( $insert_postmeta ) ) {
break;
}
$user_id = isset( $insert_postmeta['user_id'] ) ? $insert_postmeta['user_id'] : 0;
$item_id = isset( $insert_postmeta['_bbp_forum_subscriptions'] ) ? $insert_postmeta['_bbp_forum_subscriptions'] : 0;
if ( $user_id && $item_id ) {
bbp_add_user_subscription( $user_id, $this->callback_forumid( $item_id ) );
}
break;
/** Subscriptions */
case 'topic_subscriptions':
if ( 0 === count( $insert_postmeta ) ) {
break;
}
$user_id = isset( $insert_postmeta['user_id'] ) ? $insert_postmeta['user_id'] : 0;
$item_id = isset( $insert_postmeta['_bbp_subscriptions'] ) ? $insert_postmeta['_bbp_subscriptions'] : 0;
if ( $user_id && $item_id ) {
bbp_add_user_subscription( $user_id, $this->callback_topicid( $item_id ) );
}
break;
/** Favorites */
case 'favorites':
if ( 0 === count( $insert_postmeta ) ) {
break;
}
$user_id = isset( $insert_postmeta['user_id'] ) ? $insert_postmeta['user_id'] : 0;
$item_id = isset( $insert_postmeta['_bbp_favorites'] ) ? $insert_postmeta['_bbp_favorites'] : 0;
if ( $user_id && $item_id ) {
bbp_add_user_favorite( $user_id, $this->callback_topicid( $item_id ) );
}
break;
/** Forum, Topic, Reply */
default:
if ( 0 === count( $insert_post ) ) {
break;
}
// Avoid trim deprecation error when post_title empty.
if ( ! empty( $insert_post['post_name'] ) && empty( $insert_post['post_title'] ) ) {
$insert_post['post_title'] = sanitize_title( $insert_post['post_name'] );
}
$post_id = wp_insert_post( $insert_post, true );
if ( is_numeric( $post_id ) && count( $insert_postmeta ) > 0 ) {
foreach ( $insert_postmeta as $key => $value ) {
add_post_meta( $post_id, $key, $value, true );
/**
* If we are using the sync_table add
* the meta '_id' keys to the table
*
* Forums: _bbp_old_forum_id // The old forum ID
* _bbp_old_forum_parent_id // The old forum parent ID
*
* Topics: _bbp_forum_id // The new forum ID
* _bbp_old_topic_id // The old topic ID
* _bbp_old_closed_status_id // The old topic open/closed status
* _bbp_old_sticky_status_id // The old topic sticky status
*
* Replies: _bbp_forum_id // The new forum ID
* _bbp_topic_id // The new topic ID
* _bbp_old_reply_id // The old reply ID
* _bbp_old_reply_to_id // The old reply to ID
*/
if ( '_id' === substr( $key, -3 ) && ( true === $this->sync_table ) ) {
$this->wpdb->insert(
$this->sync_table_name,
array(
'value_type' => 'post',
'value_id' => $post_id,
'meta_key' => $key,
'meta_value' => $value,
)
);
}
/**
* Replies need to save their old reply_to ID for
* hierarchical replies association. Later we update
* the _bbp_reply_to value with the new bbPress
* value using convert_reply_to_parents()
*/
if ( ( 'reply' === $to_type ) && ( '_bbp_old_reply_to_id' === $key ) ) {
add_post_meta( $post_id, '_bbp_reply_to', $value );
}
}
}
break;
}
$has_insert = true;
}
}
}
return ! $has_insert;
}
/**
* This method converts old forum hierarchy to new bbPress hierarchy.
*/
public function convert_forum_parents( $start = 1 ) {
$has_update = false;
$query = ! empty( $this->sync_table )
? $this->wpdb->prepare( "SELECT value_id, meta_value FROM {$this->sync_table_name} WHERE meta_key = %s AND meta_value > 0", '_bbp_old_forum_parent_id' )
: $this->wpdb->prepare( "SELECT post_id AS value_id, meta_value FROM {$this->wpdb->postmeta} WHERE meta_key = %s AND meta_value > 0", '_bbp_old_forum_parent_id' );
// Set max row in '_bbp_converter_rows_in_step' variable.
if ( 0 === $start ) {
$this->count_rows_by_results( $query );
}
// Create main query.
$query = $this->wpdb->prepare( $query . " LIMIT %d, %d", $start, $this->max_rows );
foreach ( $this->get_results( $query ) as $row ) {
$parent_id = $this->callback_forumid( $row->meta_value );
$this->query( $this->wpdb->prepare( "UPDATE {$this->wpdb->posts} SET post_parent = %d WHERE ID = %d LIMIT 1", $parent_id, $row->value_id ) );
$has_update = true;
}
return ! $has_update;
}
/**
* This method converts old topic stickies to new bbPress stickies.
*
* @since 2.5.0 bbPress (r5170)
*/
public function convert_topic_stickies( $start = 1 ) {
$has_update = false;
$query = ! empty( $this->sync_table )
? $this->wpdb->prepare( "SELECT value_id, meta_value FROM {$this->sync_table_name} WHERE meta_key = %s AND meta_value = %s", '_bbp_old_sticky_status_id', 'sticky' )
: $this->wpdb->prepare( "SELECT post_id AS value_id, meta_value FROM {$this->wpdb->postmeta} WHERE meta_key = %s AND meta_value = %s", '_bbp_old_sticky_status_id', 'sticky' );
// Set max row in '_bbp_converter_rows_in_step' variable.
if ( 0 === $start ) {
$this->count_rows_by_results( $query );
}
// Create main query.
$query = $this->wpdb->prepare( $query . " LIMIT %d, %d", $start, $this->max_rows );
foreach ( $this->get_results( $query ) as $row ) {
bbp_stick_topic( $row->value_id );
$has_update = true;
}
return ! $has_update;
}
/**
* This method converts old topic super stickies to new bbPress super stickies.
*
* @since 2.5.0 bbPress (r5170)
*/
public function convert_topic_super_stickies( $start = 1 ) {
$has_update = false;
$query = ! empty( $this->sync_table )
? $this->wpdb->prepare( "SELECT value_id, meta_value FROM {$this->sync_table_name} WHERE meta_key = %s AND meta_value = %s", '_bbp_old_sticky_status_id', 'super-sticky' )
: $this->wpdb->prepare( "SELECT post_id AS value_id, meta_value FROM {$this->wpdb->postmeta} WHERE meta_key = %s AND meta_value = %s", '_bbp_old_sticky_status_id', 'super-sticky' );
// Set max row in '_bbp_converter_rows_in_step' variable.
if ( 0 === $start ) {
$this->count_rows_by_results( $query );
}
// Create main query.
$query = $this->wpdb->prepare( $query . " LIMIT %d, %d", $start, $this->max_rows );
foreach ( $this->get_results( $query ) as $row ) {
bbp_stick_topic( $row->value_id, true );
$has_update = true;
}
return ! $has_update;
}
/**
* This method converts old closed topics to bbPress closed topics.
*
* @since 2.6.0 bbPress (r5425)
*/
public function convert_topic_closed_topics( $start = 1 ) {
$has_update = false;
$query = ! empty( $this->sync_table )
? $this->wpdb->prepare( "SELECT value_id, meta_value FROM {$this->sync_table_name} WHERE meta_key = %s AND meta_value = %s", '_bbp_old_closed_status_id', 'closed' )
: $this->wpdb->prepare( "SELECT post_id AS value_id, meta_value FROM {$this->wpdb->postmeta} WHERE meta_key = %s AND meta_value = %s", '_bbp_old_closed_status_id', 'closed' );
// Set max row in '_bbp_converter_rows_in_step' variable.
if ( 0 === $start ) {
$this->count_rows_by_results( $query );
}
// Create main query.
$query = $this->wpdb->prepare( $query . " LIMIT %d, %d", $start, $this->max_rows );
foreach ( $this->get_results( $query ) as $row ) {
bbp_close_topic( $row->value_id );
$has_update = true;
}
return ! $has_update;
}
/**
* This method converts old reply_to post id to new bbPress reply_to post id.
*
* @since 2.4.0 bbPress (r5093)
*/
public function convert_reply_to_parents( $start = 1 ) {
$has_update = false;
$query = ! empty( $this->sync_table )
? $this->wpdb->prepare( "SELECT value_id, meta_value FROM {$this->sync_table_name} WHERE meta_key = %s AND meta_value > 0", '_bbp_old_reply_to_id' )
: $this->wpdb->prepare( "SELECT post_id AS value_id, meta_value FROM {$this->wpdb->postmeta} WHERE meta_key = %s AND meta_value > 0", '_bbp_old_reply_to_id' );
// Set max row in '_bbp_converter_rows_in_step' variable.
if ( 0 === $start ) {
$this->count_rows_by_results( $query );
}
// Create main query.
$query = $this->wpdb->prepare( $query . " LIMIT %d, %d", $start, $this->max_rows );
foreach ( $this->get_results( $query ) as $row ) {
$reply_to = $this->callback_reply_to( $row->meta_value );
$this->query( $this->wpdb->prepare( "UPDATE {$this->wpdb->postmeta} SET meta_value = %s WHERE meta_key = %s AND post_id = %d LIMIT 1", $reply_to, '_bbp_reply_to', $row->value_id ) );
$has_update = true;
}
return ! $has_update;
}
/**
* This method converts anonymous topics.
*
* @since 2.6.0 bbPress (r5538)
*/
public function convert_anonymous_topic_authors( $start = 1 ) {
$has_update = false;
if ( ! empty( $this->sync_table ) ) {
$query = $this->wpdb->prepare(
"SELECT sync_table1.value_id AS topic_id, sync_table1.meta_value AS topic_is_anonymous, sync_table2.meta_value AS topic_author
FROM {$this->sync_table_name} AS sync_table1
INNER JOIN {$this->sync_table_name} AS sync_table2
ON ( sync_table1.value_id = sync_table2.value_id )
WHERE sync_table1.meta_value = %s
AND sync_table2.meta_key = %s",
'true',
'_bbp_old_topic_author_name_id'
);
} else {
$query = $this->wpdb->prepare(
"SELECT wp_postmeta1.post_id AS topic_id, wp_postmeta1.meta_value AS topic_is_anonymous, wp_postmeta2.meta_value AS topic_author
FROM {$this->wpdb->postmeta} AS wp_postmeta1
INNER JOIN {$this->wpdb->postmeta} AS wp_postmeta2
ON ( wp_postmeta1.post_id = wp_postmeta2.post_id )
WHERE wp_postmeta1.meta_value = %s
AND wp_postmeta2.meta_key = %s",
'true',
'_bbp_old_topic_author_name_id'
);
}
// Set max row in '_bbp_converter_rows_in_step' variable.
if ( 0 === $start ) {
$this->count_rows_by_results( $query );
}
// Create main query.
$query = $this->wpdb->prepare( $query . " LIMIT %d, %d", $start, $this->max_rows );
foreach ( $this->get_results( $query ) as $row ) {
$anonymous_topic_author_id = 0;
$this->query( $this->wpdb->prepare( "UPDATE {$this->wpdb->posts} SET post_author = %d WHERE ID = %d LIMIT 1", $anonymous_topic_author_id, $row->topic_id ) );
add_post_meta( $row->topic_id, '_bbp_anonymous_name', $row->topic_author );
$has_update = true;
}
return ! $has_update;
}
/**
* This method converts anonymous replies.
*
* @since 2.6.0 bbPress (r5538)
*/
public function convert_anonymous_reply_authors( $start = 1 ) {
$has_update = false;
if ( ! empty( $this->sync_table ) ) {
$query = $this->wpdb->prepare(
"SELECT sync_table1.value_id AS reply_id, sync_table1.meta_value AS reply_is_anonymous, sync_table2.meta_value AS reply_author
FROM {$this->sync_table_name} AS sync_table1
INNER JOIN {$this->sync_table_name} AS sync_table2
ON ( sync_table1.value_id = sync_table2.value_id )
WHERE sync_table1.meta_value = %s
AND sync_table2.meta_key = %s",
'true',
'_bbp_old_reply_author_name_id'
);
} else {
$query = $this->wpdb->prepare(
"SELECT wp_postmeta1.post_id AS reply_id, wp_postmeta1.meta_value AS reply_is_anonymous, wp_postmeta2.meta_value AS reply_author
FROM {$this->wpdb->postmeta} AS wp_postmeta1
INNER JOIN {$this->wpdb->postmeta} AS wp_postmeta2
ON ( wp_postmeta1.post_id = wp_postmeta2.post_id )
WHERE wp_postmeta1.meta_value = %s
AND wp_postmeta2.meta_key = %s",
'true',
'_bbp_old_reply_author_name_id'
);
}
// Set max row in '_bbp_converter_rows_in_step' variable.
if ( 0 === $start ) {
$this->count_rows_by_results( $query );
}
// Create main query.
$query = $this->wpdb->prepare( $query . " LIMIT %d, %d", $start, $this->max_rows );
foreach ( $this->get_results( $query ) as $row ) {
$anonymous_reply_author_id = 0;
$this->query( $this->wpdb->prepare( "UPDATE {$this->wpdb->posts} SET post_author = %d WHERE ID = %d LIMIT 1", $anonymous_reply_author_id, $row->reply_id ) );
add_post_meta( $row->reply_id, '_bbp_anonymous_name', $row->reply_author );
$has_update = true;
}
return ! $has_update;
}
/**
* This method deletes data from the wp database.
*
* @since 2.6.0 bbPress (r6456)
*/
public function clean() {
// Defaults
$has_delete = false;
/** Delete topics/forums/posts */
$esc_like = $this->wpdb->esc_like( '_bbp_' ) . '%';
$query = ! empty( $this->sync_table )
? $this->wpdb->prepare( "SELECT value_id FROM {$this->sync_table_name} INNER JOIN {$this->wpdb->posts} ON(value_id = ID) WHERE meta_key LIKE %s AND value_type = %s GROUP BY value_id ORDER BY value_id DESC LIMIT {$this->max_rows}", $esc_like, 'post' )
: $this->wpdb->prepare( "SELECT post_id AS value_id FROM {$this->wpdb->postmeta} WHERE meta_key LIKE %s GROUP BY post_id ORDER BY post_id DESC LIMIT {$this->max_rows}", $esc_like );
$posts = $this->get_results( $query, ARRAY_A );
if ( isset( $posts[0] ) && ! empty( $posts[0]['value_id'] ) ) {
foreach ( (array) $posts as $value ) {
$deleted = wp_delete_post( $value['value_id'], true );
// Only flag if not empty or error.
if ( ( false === $has_delete ) && ! empty( $deleted ) && ! is_wp_error( $deleted ) ) {
$has_delete = true;
}
}
}
/** Delete users */
$query = ! empty( $this->sync_table )
? $this->wpdb->prepare( "SELECT value_id FROM {$this->sync_table_name} INNER JOIN {$this->wpdb->users} ON(value_id = ID) WHERE meta_key = %s AND value_type = %s LIMIT {$this->max_rows}", '_bbp_old_user_id', 'user' )
: $this->wpdb->prepare( "SELECT user_id AS value_id FROM {$this->wpdb->usermeta} WHERE meta_key = %s LIMIT {$this->max_rows}", '_bbp_old_user_id' );
$users = $this->get_results( $query, ARRAY_A );
if ( ! empty( $users ) ) {
foreach ( $users as $value ) {
$deleted = wp_delete_user( $value['value_id'] );
// Only flag if not empty or error.
if ( ( false === $has_delete ) && ! empty( $deleted ) && ! is_wp_error( $deleted ) ) {
$has_delete = true;
}
}
}
unset( $posts );
unset( $users );
return ! $has_delete;
}
/**
* This method deletes passwords from the wp database.
*
* @param int Start row
*/
public function clean_passwords( $start = 1 ) {
$has_delete = false;
$query = $this->wpdb->prepare( "SELECT user_id, meta_value FROM {$this->wpdb->usermeta} WHERE meta_key = %s LIMIT {$start}, {$this->max_rows}", '_bbp_password' );
$converted = $this->get_results( $query, ARRAY_A );
if ( ! empty( $converted ) ) {
foreach ( $converted as $value ) {
if ( is_serialized( $value['meta_value'] ) ) {
$this->query( $this->wpdb->prepare( "UPDATE {$this->wpdb->users} SET user_pass = '' WHERE ID = %d", $value['user_id'] ) );
} else {
$this->query( $this->wpdb->prepare( "UPDATE {$this->wpdb->users} SET user_pass = %s WHERE ID = %d", $value['meta_value'], $value['user_id'] ) );
$this->query( $this->wpdb->prepare( "DELETE FROM {$this->wpdb->usermeta} WHERE meta_key = %s AND user_id = %d", '_bbp_password', $value['user_id'] ) );
}
}
$has_delete = true;
}
return ! $has_delete;
}
/**
* This method implements the authentication for the different forums.
*
* @param string Un-encoded password.
*/
abstract protected function authenticate_pass( $password, $hash );
/**
* Info
*/
abstract protected function info();
/**
* This method grabs appropriate fields from the table specified
*
* @param string The table name to grab fields from
*/
private function get_fields( $tablename = '' ) {
$retval = array();
$field_array = $this->get_results( "DESCRIBE {$tablename}", ARRAY_A );
// Bail if no fields.
if ( empty( $field_array ) ) {
return $retval;
}
// Add fields to array.
foreach ( $field_array as $field ) {
if ( ! empty( $field['Field'] ) ) {
$retval[] = $field['Field'];
}
}
// Add social fields for users table.
if ( $tablename === $this->wpdb->users ) {
$retval[] = 'role';
$retval[] = 'yim';
$retval[] = 'aim';
$retval[] = 'jabber';
}
return $retval;
}
/** Database Wrappers *****************************************************/
/**
* Update the last query option and return results
*
* @param string $query
* @param string $output
*/
private function get_row( $query = '' ) {
$this->update_query( $query );
return $this->wpdb->get_row( $query );
}
/**
* Update the last query option and return results
*
* @param string $query
* @param string $output
*/
private function get_results( $query = '', $output = OBJECT ) {
$this->update_query( $query );
return (array) $this->wpdb->get_results( $query, $output );
}
/**
* Update the last query option and do a general query
*
* @param string $query
*/
private function query( $query = '' ) {
$this->update_query( $query );
return $this->wpdb->query( $query );
}
/**
* Update the last query ran
*
* @since 2.6.0 bbPress (r6637)
*
* @param string $query The literal MySQL query.
* @return bool
*/
private function update_query( $query = '' ) {
return update_option( '_bbp_converter_query', $query );
}
/**
* Update the number of rows in the current step
*
* @since 2.6.0 bbPress (r6637)
*
* @param string $query The literal MySQL query.
*/
private function count_rows_by_results( $query = '' ) {
$results = $this->get_results( $query );
update_option( '_bbp_converter_rows_in_step', count( $results ) );
}
/**
* Update the number of rows in the current step
*
* @since 2.6.0 bbPress (r6637)
*
* @param string $table_name The literal MySQL query.
* @return bool
*/
private function count_rows_by_table( $table_name = '' ) {
$count = 0;
if ( bb_check_table_exists( $this->opdb, $this->opdb->prefix . $table_name ) ) {
$count = (int) $this->opdb->get_var( "SELECT COUNT(*) FROM {$table_name}" );
}
return update_option( '_bbp_converter_rows_in_step', $count );
}
/** Callbacks *************************************************************/
/**
* Run password through wp_hash_password()
*
* @param string $username.
* @param string $password.
*/
public function callback_pass( $username, $password ) {
$user = $this->get_row( $this->wpdb->prepare( "SELECT * FROM {$this->wpdb->users} WHERE user_login = %s AND user_pass = '' LIMIT 1", $username ) );
if ( ! empty( $user ) ) {
$usermeta = $this->get_row( $this->wpdb->prepare( "SELECT * FROM {$this->wpdb->usermeta} WHERE meta_key = %s AND user_id = %d LIMIT 1", '_bbp_password', $user->ID ) );
if ( ! empty( $usermeta ) ) {
if ( $this->authenticate_pass( $password, $usermeta->meta_value ) ) {
$this->query( $this->wpdb->prepare( "UPDATE {$this->wpdb->users} SET user_pass = %s WHERE ID = %d", wp_hash_password( $password ), $user->ID ) );
$this->query( $this->wpdb->prepare( "DELETE FROM {$this->wpdb->usermeta} WHERE meta_key = %s AND user_id = %d", '_bbp_password', $user->ID ) );
// Clean the cache for this user since their password was
// upgraded from the old platform to the new.
clean_user_cache( $user->ID );
}
}
}
}
/**
* A mini cache system to reduce database calls to forum ID's
*
* @param string $field.
* @return string
*/
private function callback_forumid( $field ) {
if ( ! isset( $this->map_forumid[ $field ] ) ) {
$row = ! empty( $this->sync_table )
? $this->get_row( $this->wpdb->prepare( "SELECT value_id, meta_value FROM {$this->sync_table_name} WHERE meta_key = %s AND meta_value = %s LIMIT 1", '_bbp_old_forum_id', $field ) )
: $this->get_row( $this->wpdb->prepare( "SELECT post_id AS value_id FROM {$this->wpdb->postmeta} WHERE meta_key = %s AND meta_value = %s LIMIT 1", '_bbp_old_forum_id', $field ) );
$this->map_forumid[ $field ] = ! is_null( $row )
? $row->value_id
: 0;
}
return $this->map_forumid[ $field ];
}
/**
* A mini cache system to reduce database calls to topic ID's
*
* @param string $field.
* @return string
*/
private function callback_topicid( $field ) {
if ( ! isset( $this->map_topicid[ $field ] ) ) {
$row = ! empty( $this->sync_table )
? $this->get_row( $this->wpdb->prepare( "SELECT value_id, meta_value FROM {$this->sync_table_name} WHERE meta_key = %s AND meta_value = %s LIMIT 1", '_bbp_old_topic_id', $field ) )
: $this->get_row( $this->wpdb->prepare( "SELECT post_id AS value_id FROM {$this->wpdb->postmeta} WHERE meta_key = %s AND meta_value = %s LIMIT 1", '_bbp_old_topic_id', $field ) );
$this->map_topicid[ $field ] = ! is_null( $row )
? $row->value_id
: 0;
}
return $this->map_topicid[ $field ];
}
/**
* A mini cache system to reduce database calls to reply_to post id.
*
* @since 2.4.0 bbPress (r5093)
*
* @param string $field.
* @return string
*/
private function callback_reply_to( $field ) {
if ( ! isset( $this->map_reply_to[ $field ] ) ) {
$row = ! empty( $this->sync_table )
? $this->get_row( $this->wpdb->prepare( "SELECT value_id, meta_value FROM {$this->sync_table_name} WHERE meta_key = %s AND meta_value = %s LIMIT 1", '_bbp_old_reply_id', $field ) )
: $this->get_row( $this->wpdb->prepare( "SELECT post_id AS value_id FROM {$this->wpdb->postmeta} WHERE meta_key = %s AND meta_value = %s LIMIT 1", '_bbp_old_reply_id', $field ) );
$this->map_reply_to[ $field ] = ! is_null( $row )
? $row->value_id
: 0;
}
return $this->map_reply_to[ $field ];
}
/**
* A mini cache system to reduce database calls to user ID's
*
* @param string $field.
* @return string
*/
private function callback_userid( $field ) {
if ( ! isset( $this->map_userid[ $field ] ) ) {
$row = ! empty( $this->sync_table )
? $this->get_row( $this->wpdb->prepare( "SELECT value_id, meta_value FROM {$this->sync_table_name} WHERE meta_key = %s AND meta_value = %s LIMIT 1", '_bbp_old_user_id', $field ) )
: $this->get_row( $this->wpdb->prepare( "SELECT user_id AS value_id FROM {$this->wpdb->usermeta} WHERE meta_key = %s AND meta_value = %s LIMIT 1", '_bbp_old_user_id', $field ) );
if ( ! is_null( $row ) ) {
$this->map_userid[ $field ] = $row->value_id;
} else {
$this->map_userid[ $field ] = ( true === $this->convert_users )
? 0
: $field;
}
}
return $this->map_userid[ $field ];
}
/**
* Check if the topic or reply author is anonymous
*
* @since 2.6.0 bbPress (r5544)
*
* @param string $field.
* @return string
*/
private function callback_check_anonymous( $field ) {
$field = ( $this->callback_userid( $field ) == 0 )
? 'true'
: 'false';
return $field;
}
/**
* A mini cache system to reduce database calls map topics ID's to forum ID's
*
* @param string $field.
* @return string
*/
private function callback_topicid_to_forumid( $field ) {
$topicid = $this->callback_topicid( $field );
if ( empty( $topicid ) ) {
$this->map_topicid_to_forumid[ $topicid ] = 0;
} elseif ( ! isset( $this->map_topicid_to_forumid[ $topicid ] ) ) {
$row = $this->get_row( $this->wpdb->prepare( "SELECT post_parent FROM {$this->wpdb->posts} WHERE ID = %d LIMIT 1", $topicid ) );
$this->map_topicid_to_forumid[ $topicid ] = ! is_null( $row )
? $row->post_parent
: 0;
}
return $this->map_topicid_to_forumid[ $topicid ];
}
protected function callback_slug( $field ) {
return sanitize_title( $field );
}
protected function callback_negative( $field ) {
return ( $field < 0 )
? 0
: $field;
}
protected function callback_html( $field ) {
require_once bbpress()->admin->admin_dir . 'parser.php';
// Setup the BBCode parser
$bbcode = BBCode::getInstance();
// Pass BBCode properties to the parser
foreach ( $this->bbcode_parser_properties as $prop => $value ) {
$bbcode->{$prop} = $value;
}
return html_entity_decode( $bbcode->Parse( $field ), ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401 );
}
protected function callback_null( $field ) {
return is_null( $field )
? ''
: $field;
}
protected function callback_datetime( $field ) {
if ( empty( $field ) ) {
return '';
}
return is_numeric( $field )
? date( 'Y-m-d H:i:s', $field )
: date( 'Y-m-d H:i:s', strtotime( $field ) );
}
}
/**
* This is a function that is purposely written to look like a "new" statement.
* It is basically a dynamic loader that will load in the platform conversion
* of your choice.
*
* @since 2.0.0
*
* @param string $platform Name of valid platform class.
*
* @return mixed Object if converter exists, null if not
*/
function bbp_new_converter( $platform = '' ) {
$found = false;
if ( ! file_exists( bbpress()->admin->admin_dir . 'converters/' ) ) {
return null;
}
if ( $curdir = opendir( bbpress()->admin->admin_dir . 'converters/' ) ) {
while ( $file = readdir( $curdir ) ) {
if ( stristr( $file, '.php' ) && stristr( $file, 'index' ) === false ) {
$file = preg_replace( '/.php/', '', $file );
if ( $platform == $file ) {
$found = true;
continue;
}
}
}
closedir( $curdir );
}
if ( true === $found ) {
require_once bbpress()->admin->admin_dir . 'converters/' . $platform . '.php';
return new $platform();
} else {
return null;
}
}