Changeset 6448 for trunk/src/includes/admin/converter.php
- Timestamp:
- 06/01/2017 06:40:48 PM (9 years ago)
- File:
-
- 1 edited
-
trunk/src/includes/admin/converter.php (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/includes/admin/converter.php
r6415 r6448 14 14 15 15 /** 16 * Main BBP_Converter Class 16 * Return an array of available converters 17 * 18 * @since 2.6.0 bbPress (r6447) 19 * 20 * @return array 17 21 */ 18 class BBP_Converter{22 function bbp_get_converters() { 19 23 20 /** 21 * The main bbPress Converter loader 22 * 23 * @since 2.1.0 bbPress (r3813) 24 * 25 * @uses BBP_Converter::includes() Include the required files 26 * @uses BBP_Converter::setup_actions() Setup the actions 27 */ 28 public function __construct() { 24 // Default 25 $files = array(); 26 $path = bbpress()->admin->admin_dir . 'converters/'; 27 $curdir = opendir( $path ); 29 28 30 // "I wonder where I'll float next." 31 if ( empty( $_SERVER['REQUEST_METHOD'] ) ) { 32 return; 33 } 34 35 // Bail if request is not correct 36 switch ( strtoupper( $_SERVER['REQUEST_METHOD'] ) ) { 37 38 // Converter is converting 39 case 'POST' : 40 if ( ( empty( $_POST['action'] ) || ( 'bbconverter_process' != $_POST['action'] ) ) ) { 41 return; 42 } 43 44 break; 45 46 // Some other admin page 47 case 'GET' : 48 if ( ( empty( $_GET['page'] ) || ( 'bbp-converter' != $_GET['page'] ) ) ) { 49 return; 50 } 51 52 break; 53 } 54 55 // Proceed with the actions 56 $this->setup_actions(); 57 } 58 59 /** 60 * Setup the default actions 61 * 62 * @since 2.1.0 bbPress (r3813) 63 * 64 * @uses add_action() To add various actions 65 */ 66 private function setup_actions() { 67 68 // Attach to the admin head with our ajax requests cycle and css 69 add_action( 'bbp_admin_head', array( $this, 'admin_head' ) ); 70 71 // Attach the bbConverter admin settings action to the WordPress admin init action. 72 add_action( 'bbp_register_admin_settings', array( $this, 'register_admin_settings' ) ); 73 74 // Attach to the admin ajax request to process cycles 75 add_action( 'wp_ajax_bbconverter_process', array( $this, 'process_callback' ) ); 76 } 77 78 /** 79 * Register the settings 80 * 81 * @since 2.1.0 bbPress (r3813) 82 * 83 * @uses add_settings_section() To add our own settings section 84 * @uses add_settings_field() To add various settings fields 85 * @uses register_setting() To register various settings 86 */ 87 public function register_admin_settings() { 88 89 // Add the main section 90 add_settings_section( 'bbpress_converter_main', __( 'Database Settings', 'bbpress' ), 'bbp_converter_setting_callback_main_section', 'bbpress_converter' ); 91 92 // System Select 93 add_settings_field( '_bbp_converter_platform', __( 'Select Platform', 'bbpress' ), 'bbp_converter_setting_callback_platform', 'bbpress_converter', 'bbpress_converter_main' ); 94 register_setting ( 'bbpress_converter_main', '_bbp_converter_platform', 'sanitize_title' ); 95 96 // Database Server 97 add_settings_field( '_bbp_converter_db_server', __( 'Database Server', 'bbpress' ), 'bbp_converter_setting_callback_dbserver', 'bbpress_converter', 'bbpress_converter_main' ); 98 register_setting ( 'bbpress_converter_main', '_bbp_converter_db_server', 'sanitize_title' ); 99 100 // Database Server Port 101 add_settings_field( '_bbp_converter_db_port', __( 'Database Port', 'bbpress' ), 'bbp_converter_setting_callback_dbport', 'bbpress_converter', 'bbpress_converter_main' ); 102 register_setting ( 'bbpress_converter_main', '_bbp_converter_db_port', 'sanitize_title' ); 103 104 // Database Name 105 add_settings_field( '_bbp_converter_db_name', __( 'Database Name', 'bbpress' ), 'bbp_converter_setting_callback_dbname', 'bbpress_converter', 'bbpress_converter_main' ); 106 register_setting ( 'bbpress_converter_main', '_bbp_converter_db_name', 'sanitize_title' ); 107 108 // Database User 109 add_settings_field( '_bbp_converter_db_user', __( 'Database User', 'bbpress' ), 'bbp_converter_setting_callback_dbuser', 'bbpress_converter', 'bbpress_converter_main' ); 110 register_setting ( 'bbpress_converter_main', '_bbp_converter_db_user', 'sanitize_title' ); 111 112 // Database Pass 113 add_settings_field( '_bbp_converter_db_pass', __( 'Database Password', 'bbpress' ), 'bbp_converter_setting_callback_dbpass', 'bbpress_converter', 'bbpress_converter_main' ); 114 register_setting ( 'bbpress_converter_main', '_bbp_converter_db_pass', 'sanitize_title' ); 115 116 // Database Prefix 117 add_settings_field( '_bbp_converter_db_prefix', __( 'Table Prefix', 'bbpress' ), 'bbp_converter_setting_callback_dbprefix', 'bbpress_converter', 'bbpress_converter_main' ); 118 register_setting ( 'bbpress_converter_main', '_bbp_converter_db_prefix', 'sanitize_title' ); 119 120 // Add the options section 121 add_settings_section( 'bbpress_converter_opt', __( 'Options', 'bbpress' ), 'bbp_converter_setting_callback_options_section', 'bbpress_converter' ); 122 123 // Rows Limit 124 add_settings_field( '_bbp_converter_rows', __( 'Rows Limit', 'bbpress' ), 'bbp_converter_setting_callback_rows', 'bbpress_converter', 'bbpress_converter_opt' ); 125 register_setting ( 'bbpress_converter_opt', '_bbp_converter_rows', 'intval' ); 126 127 // Delay Time 128 add_settings_field( '_bbp_converter_delay_time', __( 'Delay Time', 'bbpress' ), 'bbp_converter_setting_callback_delay_time', 'bbpress_converter', 'bbpress_converter_opt' ); 129 register_setting ( 'bbpress_converter_opt', '_bbp_converter_delay_time', 'intval' ); 130 131 // Convert Users ? 132 add_settings_field( '_bbp_converter_convert_users', __( 'Convert Users', 'bbpress' ), 'bbp_converter_setting_callback_convert_users', 'bbpress_converter', 'bbpress_converter_opt' ); 133 register_setting ( 'bbpress_converter_opt', '_bbp_converter_convert_users', 'intval' ); 134 135 // Restart 136 add_settings_field( '_bbp_converter_restart', __( 'Start Over', 'bbpress' ), 'bbp_converter_setting_callback_restart', 'bbpress_converter', 'bbpress_converter_opt' ); 137 register_setting ( 'bbpress_converter_opt', '_bbp_converter_restart', 'intval' ); 138 139 // Clean 140 add_settings_field( '_bbp_converter_clean', __( 'Purge Previous Import', 'bbpress' ), 'bbp_converter_setting_callback_clean', 'bbpress_converter', 'bbpress_converter_opt' ); 141 register_setting ( 'bbpress_converter_opt', '_bbp_converter_clean', 'intval' ); 142 } 143 144 /** 145 * Admin scripts 146 * 147 * @since 2.1.0 bbPress (r3813) 148 */ 149 public function admin_head() { ?> 150 151 <style type="text/css" media="screen"> 152 /*<![CDATA[*/ 153 154 div.bbp-converter-updated, 155 div.bbp-converter-warning { 156 border-radius: 3px 3px 3px 3px; 157 border-style: solid; 158 border-width: 1px; 159 padding: 5px 5px 5px 5px; 160 } 161 162 div.bbp-converter-updated { 163 height: 300px; 164 overflow: auto; 165 display: none; 166 background-color: #FFFFE0; 167 border-color: #E6DB55; 168 font-family: monospace; 169 font-weight: bold; 170 } 171 172 div.bbp-converter-updated p { 173 margin: 0.5em 0; 174 padding: 2px; 175 float: left; 176 clear: left; 177 } 178 179 div.bbp-converter-updated p.loading { 180 padding: 2px 20px 2px 2px; 181 background-image: url('<?php echo admin_url(); ?>images/wpspin_light.gif'); 182 background-repeat: no-repeat; 183 background-position: center right; 184 } 185 186 #bbp-converter-stop { 187 display:none; 188 } 189 190 #bbp-converter-progress { 191 display:none; 192 } 193 194 /*]]>*/ 195 </style> 196 197 <script language="javascript"> 198 199 var bbconverter_is_running = false; 200 var bbconverter_run_timer; 201 var bbconverter_delay_time = 0; 202 203 function bbconverter_grab_data() { 204 var values = {}; 205 jQuery.each(jQuery('#bbp-converter-settings').serializeArray(), function(i, field) { 206 values[field.name] = field.value; 207 }); 208 209 if( values['_bbp_converter_restart'] ) { 210 jQuery('#_bbp_converter_restart').removeAttr("checked"); 211 } 212 213 if( values['_bbp_converter_delay_time'] ) { 214 bbconverter_delay_time = values['_bbp_converter_delay_time'] * 1000; 215 } 216 217 values['action'] = 'bbconverter_process'; 218 values['_ajax_nonce'] = '<?php echo wp_create_nonce( 'bbp_converter_process' ); ?>'; 219 220 return values; 221 } 222 223 function bbconverter_start() { 224 if( false === bbconverter_is_running ) { 225 bbconverter_is_running = true; 226 jQuery('#bbp-converter-start').hide(); 227 jQuery('#bbp-converter-stop').show(); 228 jQuery('#bbp-converter-progress').show(); 229 bbconverter_log( '<p class="loading"><?php esc_html_e( 'Starting Conversion', 'bbpress' ); ?></p>' ); 230 bbconverter_run(); 231 } 232 } 233 234 function bbconverter_run() { 235 jQuery.post(ajaxurl, bbconverter_grab_data(), function(response) { 236 var response_length = response.length - 1; 237 response = response.substring(0,response_length); 238 bbconverter_success(response); 239 }); 240 } 241 242 function bbconverter_stop() { 243 jQuery('#bbp-converter-start').show(); 244 jQuery('#bbp-converter-stop').hide(); 245 jQuery('#bbp-converter-progress').hide(); 246 jQuery('#bbp-converter-message p').removeClass( 'loading' ); 247 bbconverter_is_running = false; 248 clearTimeout( bbconverter_run_timer ); 249 } 250 251 function bbconverter_success(response) { 252 bbconverter_log(response); 253 254 if ( response === '<p class="loading"><?php esc_html_e( 'Conversion Complete', 'bbpress' ); ?></p>' || response.indexOf('error') > -1 ) { 255 bbconverter_log('<p>Repair any missing information: <a href="<?php echo admin_url(); ?>tools.php?page=bbp-repair">Continue</a></p>'); 256 bbconverter_stop(); 257 } else if( bbconverter_is_running ) { // keep going 258 jQuery('#bbp-converter-progress').show(); 259 clearTimeout( bbconverter_run_timer ); 260 bbconverter_run_timer = setTimeout( 'bbconverter_run()', bbconverter_delay_time ); 261 } else { 262 bbconverter_stop(); 263 } 264 } 265 266 function bbconverter_log(text) { 267 if ( jQuery('#bbp-converter-message').css('display') === 'none' ) { 268 jQuery('#bbp-converter-message').show(); 269 } 270 if ( text ) { 271 jQuery('#bbp-converter-message p').removeClass( 'loading' ); 272 jQuery('#bbp-converter-message').prepend( text ); 273 } 274 } 275 276 </script> 277 278 <?php 279 } 280 281 /** 282 * Wrap the converter output in paragraph tags, so styling can be applied 283 * 284 * @since 2.1.0 bbPress (r4052) 285 * 286 * @param string $output 287 */ 288 private static function converter_output( $output = '' ) { 289 290 // Get the last query 291 $before = '<p class="loading">'; 292 $after = '</p>'; 293 $query = get_option( '_bbp_converter_query' ); 294 295 if ( ! empty( $query ) ) { 296 $before = '<p class="loading" title="' . esc_attr( $query ) . '">'; 297 } 298 299 echo $before . $output . $after; 300 } 301 302 /** 303 * Callback processor 304 * 305 * @since 2.1.0 bbPress (r3813) 306 */ 307 public function process_callback() { 308 309 // Bail if user cannot view import page 310 if ( ! current_user_can( 'bbp_tools_import_page' ) ) { 311 wp_die( '0' ); 312 } 313 314 // Verify intent 315 check_ajax_referer( 'bbp_converter_process' ); 316 317 if ( ! ini_get( 'safe_mode' ) ) { 318 set_time_limit( 0 ); 319 ini_set( 'memory_limit', '256M' ); 320 ini_set( 'implicit_flush', '1' ); 321 ignore_user_abort( true ); 322 } 323 324 // Save step and count so that it can be restarted. 325 if ( ! get_option( '_bbp_converter_step' ) || ( ! empty( $_POST['_bbp_converter_restart'] ) ) ) { 326 update_option( '_bbp_converter_step', 1 ); 327 update_option( '_bbp_converter_start', 0 ); 328 } 329 330 $step = (int) get_option( '_bbp_converter_step', 1 ); 331 $min = (int) get_option( '_bbp_converter_start', 0 ); 332 $count = (int) ! empty( $_POST['_bbp_converter_rows'] ) ? $_POST['_bbp_converter_rows'] : 100; 333 $max = ( $min + $count ) - 1; 334 $start = $min; 335 336 // Bail if platform did not get saved 337 $platform = ! empty( $_POST['_bbp_converter_platform' ] ) ? $_POST['_bbp_converter_platform' ] : get_option( '_bbp_converter_platform' ); 338 if ( empty( $platform ) ) { 339 return; 340 } 341 342 // Include the appropriate converter. 343 $converter = bbp_new_converter( $platform ); 344 345 switch ( $step ) { 346 347 // STEP 1. Clean all tables. 348 case 1 : 349 if ( ! empty( $_POST['_bbp_converter_clean'] ) ) { 350 if ( $converter->clean( $start ) ) { 351 update_option( '_bbp_converter_step', $step + 1 ); 352 update_option( '_bbp_converter_start', 0 ); 353 $this->sync_table( true ); 354 if ( empty( $start ) ) { 355 $this->converter_output( __( 'No data to clean', 'bbpress' ) ); 356 } 357 } else { 358 update_option( '_bbp_converter_start', $max + 1 ); 359 $this->converter_output( sprintf( __( 'Deleting previously converted data (%1$s - %2$s)', 'bbpress' ), $min, $max ) ); 360 } 361 } else { 362 update_option( '_bbp_converter_step', $step + 1 ); 363 update_option( '_bbp_converter_start', 0 ); 364 } 365 366 break; 367 368 // STEP 2. Convert users. 369 case 2 : 370 if ( ! empty( $_POST['_bbp_converter_convert_users'] ) ) { 371 if ( $converter->convert_users( $start ) ) { 372 update_option( '_bbp_converter_step', $step + 1 ); 373 update_option( '_bbp_converter_start', 0 ); 374 if ( empty( $start ) ) { 375 $this->converter_output( __( 'No users to convert', 'bbpress' ) ); 376 } 377 } else { 378 update_option( '_bbp_converter_start', $max + 1 ); 379 $this->converter_output( sprintf( __( 'Converting users (%1$s - %2$s)', 'bbpress' ), $min, $max ) ); 380 } 381 } else { 382 update_option( '_bbp_converter_step', $step + 1 ); 383 update_option( '_bbp_converter_start', 0 ); 384 } 385 386 break; 387 388 // STEP 3. Clean passwords. 389 case 3 : 390 if ( ! empty( $_POST['_bbp_converter_convert_users'] ) ) { 391 if ( $converter->clean_passwords( $start ) ) { 392 update_option( '_bbp_converter_step', $step + 1 ); 393 update_option( '_bbp_converter_start', 0 ); 394 if ( empty( $start ) ) { 395 $this->converter_output( __( 'No passwords to clear', 'bbpress' ) ); 396 } 397 } else { 398 update_option( '_bbp_converter_start', $max + 1 ); 399 $this->converter_output( sprintf( __( 'Delete users WordPress default passwords (%1$s - %2$s)', 'bbpress' ), $min, $max ) ); 400 } 401 } else { 402 update_option( '_bbp_converter_step', $step + 1 ); 403 update_option( '_bbp_converter_start', 0 ); 404 } 405 406 break; 407 408 // STEP 4. Convert forums. 409 case 4 : 410 if ( $converter->convert_forums( $start ) ) { 411 update_option( '_bbp_converter_step', $step + 1 ); 412 update_option( '_bbp_converter_start', 0 ); 413 if ( empty( $start ) ) { 414 $this->converter_output( __( 'No forums to convert', 'bbpress' ) ); 415 } 416 } else { 417 update_option( '_bbp_converter_start', $max + 1 ); 418 $this->converter_output( sprintf( __( 'Converting forums (%1$s - %2$s)', 'bbpress' ), $min, $max ) ); 419 } 420 421 break; 422 423 // STEP 5. Convert forum parents. 424 case 5 : 425 if ( $converter->convert_forum_parents( $start ) ) { 426 update_option( '_bbp_converter_step', $step + 1 ); 427 update_option( '_bbp_converter_start', 0 ); 428 if ( empty( $start ) ) { 429 $this->converter_output( __( 'No forum parents to convert', 'bbpress' ) ); 430 } 431 } else { 432 update_option( '_bbp_converter_start', $max + 1 ); 433 $this->converter_output( sprintf( __( 'Calculating forum hierarchy (%1$s - %2$s)', 'bbpress' ), $min, $max ) ); 434 } 435 436 break; 437 438 // STEP 6. Convert forum subscriptions. 439 case 6 : 440 if ( $converter->convert_forum_subscriptions( $start ) ) { 441 update_option( '_bbp_converter_step', $step + 1 ); 442 update_option( '_bbp_converter_start', 0 ); 443 if ( empty( $start ) ) { 444 $this->converter_output( __( 'No forum subscriptions to convert', 'bbpress' ) ); 445 } 446 } else { 447 update_option( '_bbp_converter_start', $max + 1 ); 448 $this->converter_output( sprintf( __( 'Converting forum subscriptions (%1$s - %2$s)', 'bbpress' ), $min, $max ) ); 449 } 450 451 break; 452 453 // STEP 7. Convert topics. 454 case 7 : 455 if ( $converter->convert_topics( $start ) ) { 456 update_option( '_bbp_converter_step', $step + 1 ); 457 update_option( '_bbp_converter_start', 0 ); 458 if ( empty( $start ) ) { 459 $this->converter_output( __( 'No topics to convert', 'bbpress' ) ); 460 } 461 } else { 462 update_option( '_bbp_converter_start', $max + 1 ); 463 $this->converter_output( sprintf( __( 'Converting topics (%1$s - %2$s)', 'bbpress' ), $min, $max ) ); 464 } 465 466 break; 467 468 // STEP 8. Convert anonymous topic authors. 469 case 8 : 470 if ( $converter->convert_anonymous_topic_authors( $start ) ) { 471 update_option( '_bbp_converter_step', $step + 1 ); 472 update_option( '_bbp_converter_start', 0 ); 473 if ( empty( $start ) ) { 474 $this->converter_output( __( 'No anonymous topic authors to convert', 'bbpress' ) ); 475 } 476 } else { 477 update_option( '_bbp_converter_start', $max + 1 ); 478 $this->converter_output( sprintf( __( 'Converting anonymous topic authors (%1$s - %2$s)', 'bbpress' ), $min, $max ) ); 479 } 480 481 break; 482 483 // STEP 9. Stick topics. 484 case 9 : 485 if ( $converter->convert_topic_stickies( $start ) ) { 486 update_option( '_bbp_converter_step', $step + 1 ); 487 update_option( '_bbp_converter_start', 0 ); 488 if ( empty( $start ) ) { 489 $this->converter_output( __( 'No stickies to stick', 'bbpress' ) ); 490 } 491 } else { 492 update_option( '_bbp_converter_start', $max + 1 ); 493 $this->converter_output( sprintf( __( 'Calculating topic stickies (%1$s - %2$s)', 'bbpress' ), $min, $max ) ); 494 } 495 496 break; 497 498 // STEP 10. Stick to front topics (Super Sicky). 499 case 10 : 500 if ( $converter->convert_topic_super_stickies( $start ) ) { 501 update_option( '_bbp_converter_step', $step + 1 ); 502 update_option( '_bbp_converter_start', 0 ); 503 if ( empty( $start ) ) { 504 $this->converter_output( __( 'No super stickies to stick', 'bbpress' ) ); 505 } 506 } else { 507 update_option( '_bbp_converter_start', $max + 1 ); 508 $this->converter_output( sprintf( __( 'Calculating topic super stickies (%1$s - %2$s)', 'bbpress' ), $min, $max ) ); 509 } 510 511 break; 512 513 // STEP 11. Closed topics. 514 case 11 : 515 if ( $converter->convert_topic_closed_topics( $start ) ) { 516 update_option( '_bbp_converter_step', $step + 1 ); 517 update_option( '_bbp_converter_start', 0 ); 518 if ( empty( $start ) ) { 519 $this->converter_output( __( 'No closed topics to close', 'bbpress' ) ); 520 } 521 } else { 522 update_option( '_bbp_converter_start', $max + 1 ); 523 $this->converter_output( sprintf( __( 'Calculating closed topics (%1$s - %2$s)', 'bbpress' ), $min, $max ) ); 524 } 525 526 break; 527 528 // STEP 12. Convert topic tags. 529 case 12 : 530 if ( $converter->convert_tags( $start ) ) { 531 update_option( '_bbp_converter_step', $step + 1 ); 532 update_option( '_bbp_converter_start', 0 ); 533 if ( empty( $start ) ) { 534 $this->converter_output( __( 'No topic tags to convert', 'bbpress' ) ); 535 } 536 } else { 537 update_option( '_bbp_converter_start', $max + 1 ); 538 $this->converter_output( sprintf( __( 'Converting topic tags (%1$s - %2$s)', 'bbpress' ), $min, $max ) ); 539 } 540 541 break; 542 543 // STEP 13. Convert topic subscriptions. 544 case 13 : 545 if ( $converter->convert_topic_subscriptions( $start ) ) { 546 update_option( '_bbp_converter_step', $step + 1 ); 547 update_option( '_bbp_converter_start', 0 ); 548 if ( empty( $start ) ) { 549 $this->converter_output( __( 'No topic subscriptions to convert', 'bbpress' ) ); 550 } 551 } else { 552 update_option( '_bbp_converter_start', $max + 1 ); 553 $this->converter_output( sprintf( __( 'Converting topic subscriptions (%1$s - %2$s)', 'bbpress' ), $min, $max ) ); 554 } 555 556 break; 557 558 // STEP 14. Convert topic favorites. 559 case 14 : 560 if ( $converter->convert_favorites( $start ) ) { 561 update_option( '_bbp_converter_step', $step + 1 ); 562 update_option( '_bbp_converter_start', 0 ); 563 if ( empty( $start ) ) { 564 $this->converter_output( __( 'No favorites to convert', 'bbpress' ) ); 565 } 566 } else { 567 update_option( '_bbp_converter_start', $max + 1 ); 568 $this->converter_output( sprintf( __( 'Converting favorites (%1$s - %2$s)', 'bbpress' ), $min, $max ) ); 569 } 570 571 break; 572 573 // STEP 15. Convert replies. 574 case 15 : 575 if ( $converter->convert_replies( $start ) ) { 576 update_option( '_bbp_converter_step', $step + 1 ); 577 update_option( '_bbp_converter_start', 0 ); 578 if ( empty( $start ) ) { 579 $this->converter_output( __( 'No replies to convert', 'bbpress' ) ); 580 } 581 } else { 582 update_option( '_bbp_converter_start', $max + 1 ); 583 $this->converter_output( sprintf( __( 'Converting replies (%1$s - %2$s)', 'bbpress' ), $min, $max ) ); 584 } 585 586 break; 587 588 // STEP 16. Convert anonymous reply authors. 589 case 16 : 590 if ( $converter->convert_anonymous_reply_authors( $start ) ) { 591 update_option( '_bbp_converter_step', $step + 1 ); 592 update_option( '_bbp_converter_start', 0 ); 593 if ( empty( $start ) ) { 594 $this->converter_output( __( 'No anonymous reply authors to convert', 'bbpress' ) ); 595 } 596 } else { 597 update_option( '_bbp_converter_start', $max + 1 ); 598 $this->converter_output( sprintf( __( 'Converting anonymous reply authors (%1$s - %2$s)', 'bbpress' ), $min, $max ) ); 599 } 600 601 break; 602 603 // STEP 17. Convert threaded replies parents. 604 case 17 : 605 if ( $converter->convert_reply_to_parents( $start ) ) { 606 update_option( '_bbp_converter_step', $step + 1 ); 607 update_option( '_bbp_converter_start', 0 ); 608 if ( empty( $start ) ) { 609 $this->converter_output( __( 'No threaded replies to convert', 'bbpress' ) ); 610 } 611 } else { 612 update_option( '_bbp_converter_start', $max + 1 ); 613 $this->converter_output( sprintf( __( 'Calculating threaded replies parents (%1$s - %2$s)', 'bbpress' ), $min, $max ) ); 614 } 615 616 break; 617 618 default : 619 delete_option( '_bbp_converter_step' ); 620 delete_option( '_bbp_converter_start' ); 621 delete_option( '_bbp_converter_query' ); 622 623 $this->converter_output( __( 'Conversion Complete', 'bbpress' ) ); 624 625 break; 626 } 627 } 628 629 /** 630 * Create Tables for fast syncing 631 * 632 * @since 2.1.0 bbPress (r3813) 633 */ 634 public function sync_table( $drop = false ) { 635 636 $bbp_db = bbp_db(); 637 $table_name = $bbp_db->prefix . 'bbp_converter_translator'; 638 if ( ! empty( $drop ) && $bbp_db->get_var( "SHOW TABLES LIKE '{$table_name}'" ) === $table_name ) { 639 $bbp_db->query( "DROP TABLE {$table_name}" ); 640 } 641 642 require_once ABSPATH . '/wp-admin/includes/upgrade.php'; 643 644 if ( ! empty( $bbp_db->charset ) ) { 645 $charset_collate = "DEFAULT CHARACTER SET $bbp_db->charset"; 646 } 647 648 if ( ! empty( $bbp_db->collate ) ) { 649 $charset_collate .= " COLLATE $bbp_db->collate"; 650 } 651 652 $sql = array(); 653 $max_index_length = 191; 654 655 /** Translator ********************************************************/ 656 657 $sql[] = "CREATE TABLE {$table_name} ( 658 meta_id mediumint(8) unsigned not null auto_increment, 659 value_type varchar(25) null, 660 value_id bigint(20) unsigned not null default '0', 661 meta_key varchar(255) null, 662 meta_value varchar(255) null, 663 PRIMARY KEY (meta_id), 664 KEY value_id (value_id), 665 KEY meta_join (meta_key({$max_index_length}), meta_value({$max_index_length})) 666 ) {$charset_collate}"; 667 668 dbDelta( $sql ); 669 } 670 } 671 672 /** 673 * Base class to be extended by specific individual importers 674 * 675 * @since 2.1.0 bbPress (r3813) 676 */ 677 abstract class BBP_Converter_Base { 678 679 /** 680 * @var array() This is the field mapping array to process. 681 */ 682 protected $field_map = array(); 683 684 /** 685 * @var object This is the connection to the WordPress database. 686 */ 687 protected $wpdb; 688 689 /** 690 * @var object This is the connection to the other platforms database. 691 */ 692 protected $opdb; 693 694 /** 695 * @var int This is the max rows to process at a time. 696 */ 697 public $max_rows; 698 699 /** 700 * @var array() Map of topic to forum. It is for optimization. 701 */ 702 private $map_topicid_to_forumid = array(); 703 704 /** 705 * @var array() Map of from old forum ids to new forum ids. It is for optimization. 706 */ 707 private $map_forumid = array(); 708 709 /** 710 * @var array() Map of from old topic ids to new topic ids. It is for optimization. 711 */ 712 private $map_topicid = array(); 713 714 /** 715 * @var array() Map of from old reply_to ids to new reply_to ids. It is for optimization. 716 */ 717 private $map_reply_to = array(); 718 719 /** 720 * @var array() Map of from old user ids to new user ids. It is for optimization. 721 */ 722 private $map_userid = array(); 723 724 /** 725 * @var str This is the charset for your wp database. 726 */ 727 public $charset; 728 729 /** 730 * @var boolean Sync table available. 731 */ 732 public $sync_table = false; 733 734 /** 735 * @var str Sync table name. 736 */ 737 public $sync_table_name; 738 739 /** Methods ***************************************************************/ 740 741 /** 742 * This is the constructor and it connects to the platform databases. 743 */ 744 public function __construct() { 745 $this->setup_globals(); 746 } 747 748 private function setup_globals() { 749 750 /** Get database connections ******************************************/ 751 752 $this->wpdb = bbp_db(); 753 $this->max_rows = (int) $_POST['_bbp_converter_rows']; 754 $this->opdb = new wpdb( $_POST['_bbp_converter_db_user'], $_POST['_bbp_converter_db_pass'], $_POST['_bbp_converter_db_name'], $_POST['_bbp_converter_db_server'] ); 755 $this->opdb->prefix = $_POST['_bbp_converter_db_prefix']; 756 757 /** 758 * Error Reporting 759 */ 760 $this->wpdb->show_errors(); 761 $this->opdb->show_errors(); 762 763 /** 764 * Syncing 765 */ 766 $this->sync_table_name = $this->wpdb->prefix . 'bbp_converter_translator'; 767 if ( $this->wpdb->get_var( "SHOW TABLES LIKE '" . $this->sync_table_name . "'" ) === $this->sync_table_name ) { 768 $this->sync_table = true; 769 } else { 770 $this->sync_table = false; 771 } 772 773 /** 774 * Character set 775 */ 776 if ( empty( $this->wpdb->charset ) ) { 777 $this->charset = 'UTF8'; 778 } else { 779 $this->charset = $this->wpdb->charset; 780 } 781 782 /** 783 * Default mapping. 784 */ 785 786 /** Forum Section *****************************************************/ 787 788 $this->field_map[] = array( 789 'to_type' => 'forum', 790 'to_fieldname' => 'post_status', 791 'default' => 'publish' 792 ); 793 $this->field_map[] = array( 794 'to_type' => 'forum', 795 'to_fieldname' => 'comment_status', 796 'default' => 'closed' 797 ); 798 $this->field_map[] = array( 799 'to_type' => 'forum', 800 'to_fieldname' => 'ping_status', 801 'default' => 'closed' 802 ); 803 $this->field_map[] = array( 804 'to_type' => 'forum', 805 'to_fieldname' => 'post_type', 806 'default' => 'forum' 807 ); 808 809 /** Topic Section *****************************************************/ 810 811 $this->field_map[] = array( 812 'to_type' => 'topic', 813 'to_fieldname' => 'post_status', 814 'default' => 'publish' 815 ); 816 $this->field_map[] = array( 817 'to_type' => 'topic', 818 'to_fieldname' => 'comment_status', 819 'default' => 'closed' 820 ); 821 $this->field_map[] = array( 822 'to_type' => 'topic', 823 'to_fieldname' => 'ping_status', 824 'default' => 'closed' 825 ); 826 $this->field_map[] = array( 827 'to_type' => 'topic', 828 'to_fieldname' => 'post_type', 829 'default' => 'topic' 830 ); 831 832 /** Post Section ******************************************************/ 833 834 $this->field_map[] = array( 835 'to_type' => 'reply', 836 'to_fieldname' => 'post_status', 837 'default' => 'publish' 838 ); 839 $this->field_map[] = array( 840 'to_type' => 'reply', 841 'to_fieldname' => 'comment_status', 842 'default' => 'closed' 843 ); 844 $this->field_map[] = array( 845 'to_type' => 'reply', 846 'to_fieldname' => 'ping_status', 847 'default' => 'closed' 848 ); 849 $this->field_map[] = array( 850 'to_type' => 'reply', 851 'to_fieldname' => 'post_type', 852 'default' => 'reply' 853 ); 854 855 /** User Section ******************************************************/ 856 857 $this->field_map[] = array( 858 'to_type' => 'user', 859 'to_fieldname' => 'role', 860 'default' => get_option( 'default_role' ) 861 ); 862 } 863 864 /** 865 * Convert Forums 866 */ 867 public function convert_forums( $start = 1 ) { 868 return $this->convert_table( 'forum', $start ); 869 } 870 871 /** 872 * Convert Topics / Threads 873 */ 874 public function convert_topics( $start = 1 ) { 875 return $this->convert_table( 'topic', $start ); 876 } 877 878 /** 879 * Convert Posts 880 */ 881 public function convert_replies( $start = 1 ) { 882 return $this->convert_table( 'reply', $start ); 883 } 884 885 /** 886 * Convert Users 887 */ 888 public function convert_users( $start = 1 ) { 889 return $this->convert_table( 'user', $start ); 890 } 891 892 /** 893 * Convert Topic Tags 894 */ 895 public function convert_tags( $start = 1 ) { 896 return $this->convert_table( 'tags', $start ); 897 } 898 899 /** 900 * Convert Forum Subscriptions 901 */ 902 public function convert_forum_subscriptions( $start = 1 ) { 903 return $this->convert_table( 'forum_subscriptions', $start ); 904 } 905 906 /** 907 * Convert Topic Subscriptions 908 */ 909 public function convert_topic_subscriptions( $start = 1 ) { 910 return $this->convert_table( 'topic_subscriptions', $start ); 911 } 912 913 /** 914 * Convert Favorites 915 */ 916 public function convert_favorites( $start = 1 ) { 917 return $this->convert_table( 'favorites', $start ); 918 } 919 920 /** 921 * Convert Table 922 * 923 * @param string to type 924 * @param int Start row 925 */ 926 public function convert_table( $to_type, $start ) { 927 928 // Are we usig a sync table, or postmeta? 929 if ( $this->wpdb->get_var( "SHOW TABLES LIKE '" . $this->sync_table_name . "'" ) === $this->sync_table_name ) { 930 $this->sync_table = true; 931 } else { 932 $this->sync_table = false; 933 } 934 935 // Set some defaults 936 $has_insert = false; 937 $from_tablename = ''; 938 $field_list = $from_tables = $tablefield_array = array(); 939 940 // Toggle Table Name based on $to_type (destination) 941 switch ( $to_type ) { 942 case 'user' : 943 $tablename = $this->wpdb->users; 944 break; 945 946 case 'tags' : 947 $tablename = ''; 948 break; 949 950 case 'forum_subscriptions' : 951 $tablename = $this->wpdb->postmeta; 952 break; 953 954 case 'topic_subscriptions' : 955 $tablename = $this->wpdb->postmeta; 956 break; 957 958 case 'favorites' : 959 $tablename = $this->wpdb->postmeta; 960 break; 961 962 default : 963 $tablename = $this->wpdb->posts; 964 } 965 966 // Get the fields from the destination table 967 if ( ! empty( $tablename ) ) { 968 $tablefield_array = $this->get_fields( $tablename ); 969 } 970 971 /** Step 1 ************************************************************/ 972 973 // Loop through the field maps, and look for to_type matches 974 foreach ( $this->field_map as $item ) { 975 976 // Yay a match, and we have a from table, too 977 if ( ( $item['to_type'] === $to_type ) && ! empty( $item['from_tablename'] ) ) { 978 979 // $from_tablename was set from a previous loop iteration 980 if ( ! empty( $from_tablename ) ) { 981 982 // Doing some joining 983 if ( ! in_array( $item['from_tablename'], $from_tables, true ) && in_array( $item['join_tablename'], $from_tables, true ) ) { 984 $from_tablename .= ' ' . $item['join_type'] . ' JOIN ' . $this->opdb->prefix . $item['from_tablename'] . ' AS ' . $item['from_tablename'] . ' ' . $item['join_expression']; 985 } 986 987 // $from_tablename needs to be set 988 } else { 989 $from_tablename = $item['from_tablename'] . ' AS ' . $item['from_tablename']; 990 } 991 992 // Specific FROM expression data used 993 if ( ! empty( $item['from_expression'] ) ) { 994 995 // No 'WHERE' in expression 996 if ( stripos( $from_tablename, "WHERE" ) === false ) { 997 $from_tablename .= ' ' . $item['from_expression']; 998 999 // 'WHERE' in expression, so replace with 'AND' 1000 } else { 1001 $from_tablename .= ' ' . str_replace( "WHERE", "AND", $item['from_expression'] ); 1002 } 1003 } 1004 1005 // Add tablename and fieldname to arrays, formatted for querying 1006 $from_tables[] = $item['from_tablename']; 1007 $field_list[] = 'convert(' . $item['from_tablename'] . '.' . $item['from_fieldname'] . ' USING "' . $this->charset . '") AS ' . $item['from_fieldname']; 1008 } 1009 } 1010 1011 /** Step 2 ************************************************************/ 1012 1013 // We have a $from_tablename, so we want to get some data to convert 1014 if ( ! empty( $from_tablename ) ) { 1015 1016 // Get some data from the old forums 1017 $field_list = array_unique( $field_list ); 1018 $fields = implode( ',', $field_list ); 1019 $forum_query = "SELECT {$fields} FROM {$this->opdb->prefix}{$from_tablename} LIMIT {$start}, {$this->max_rows}"; 1020 $forum_array = $this->opdb->get_results( $forum_query, ARRAY_A ); 1021 1022 // Set this query as the last one ran 1023 update_option( '_bbp_converter_query', $forum_query ); 1024 1025 // Query returned some results 1026 if ( ! empty( $forum_array ) ) { 1027 1028 // Loop through results 1029 foreach ( (array) $forum_array as $forum ) { 1030 1031 // Reset some defaults 1032 $insert_post = $insert_postmeta = $insert_data = array(); 1033 1034 // Loop through field map, again... 1035 foreach ( $this->field_map as $row ) { 1036 1037 // Types match and to_fieldname is present. This means 1038 // we have some work to do here. 1039 if ( ( $row['to_type'] === $to_type ) && isset( $row['to_fieldname'] ) ) { 1040 1041 // This row has a destination that matches one of the 1042 // columns in this table. 1043 if ( in_array( $row['to_fieldname'], $tablefield_array, true ) ) { 1044 1045 // Allows us to set default fields. 1046 if ( isset( $row['default'] ) ) { 1047 $insert_post[ $row['to_fieldname'] ] = $row['default']; 1048 1049 // Translates a field from the old forum. 1050 } elseif ( isset( $row['callback_method'] ) ) { 1051 if ( ( 'callback_userid' === $row['callback_method'] ) && empty( $_POST['_bbp_converter_convert_users'] ) ) { 1052 $insert_post[ $row['to_fieldname'] ] = $forum[ $row['from_fieldname'] ]; 1053 } else { 1054 $insert_post[ $row['to_fieldname'] ] = call_user_func_array( array( $this, $row['callback_method'] ), array( $forum[ $row['from_fieldname'] ], $forum ) ); 1055 } 1056 1057 // Maps the field from the old forum. 1058 } else { 1059 $insert_post[ $row['to_fieldname'] ] = $forum[ $row['from_fieldname'] ]; 1060 } 1061 1062 // Destination field is not empty, so we might need 1063 // to do some extra work or set a default. 1064 } elseif ( ! empty( $row['to_fieldname'] ) ) { 1065 1066 // Allows us to set default fields. 1067 if ( isset( $row['default'] ) ) { 1068 $insert_postmeta[ $row['to_fieldname'] ] = $row['default']; 1069 1070 // Translates a field from the old forum. 1071 } elseif ( isset( $row['callback_method'] ) ) { 1072 if ( ( $row['callback_method'] === 'callback_userid' ) && ( 0 == $_POST['_bbp_converter_convert_users'] ) ) { 1073 $insert_postmeta[ $row['to_fieldname'] ] = $forum[ $row['from_fieldname'] ]; 1074 } else { 1075 $insert_postmeta[ $row['to_fieldname'] ] = call_user_func_array( array( $this, $row['callback_method'] ), array( $forum[ $row['from_fieldname'] ], $forum ) ); 1076 } 1077 1078 // Maps the field from the old forum. 1079 } else { 1080 $insert_postmeta[ $row['to_fieldname'] ] = $forum[ $row['from_fieldname'] ]; 1081 } 1082 } 1083 } 1084 } 1085 1086 /** Step 3 ************************************************/ 1087 1088 // Something to insert into the destination field 1089 if ( count( $insert_post ) > 0 || ( $to_type == 'tags' && count( $insert_postmeta ) > 0 ) ) { 1090 1091 switch ( $to_type ) { 1092 1093 /** New user **************************************/ 1094 1095 case 'user': 1096 if ( username_exists( $insert_post['user_login'] ) ) { 1097 $insert_post['user_login'] = 'imported_' . $insert_post['user_login']; 1098 } 1099 1100 if ( email_exists( $insert_post['user_email'] ) ) { 1101 $insert_post['user_email'] = 'imported_' . $insert_post['user_email']; 1102 } 1103 1104 $post_id = wp_insert_user( $insert_post ); 1105 1106 if ( is_numeric( $post_id ) ) { 1107 1108 foreach ( $insert_postmeta as $key => $value ) { 1109 1110 add_user_meta( $post_id, $key, $value, true ); 1111 1112 if ( '_id' == substr( $key, -3 ) && ( true === $this->sync_table ) ) { 1113 $this->wpdb->insert( $this->sync_table_name, array( 'value_type' => 'user', 'value_id' => $post_id, 'meta_key' => $key, 'meta_value' => $value ) ); 1114 } 1115 } 1116 } 1117 break; 1118 1119 /** New Topic-Tag *********************************/ 1120 1121 case 'tags': 1122 $post_id = wp_set_object_terms( $insert_postmeta['objectid'], $insert_postmeta['name'], 'topic-tag', true ); 1123 $term = get_term_by( 'name', $insert_postmeta['name'], 'topic-tag'); 1124 if ( false !== $term ) { 1125 wp_update_term( $term->term_id, 'topic-tag', array( 1126 'description' => $insert_postmeta['description'], 1127 'slug' => $insert_postmeta['slug'] 1128 ) ); 1129 } 1130 break; 1131 1132 /** Forum Subscriptions ***************************/ 1133 1134 case 'forum_subscriptions': 1135 $user_id = $insert_post['user_id']; 1136 $items = wp_list_pluck( $insert_postmeta, '_bbp_forum_subscriptions' ); 1137 if ( is_numeric( $user_id ) && ! empty( $items ) ) { 1138 foreach ( $items as $value ) { 1139 1140 // Maybe string with commas 1141 $value = is_string( $value ) 1142 ? explode( ',', $value ) 1143 : (array) $value; 1144 1145 // Add user ID to forums subscribed users 1146 foreach ( $value as $fav ) { 1147 bbp_add_user_forum_subscription( $user_id, $this->callback_forumid( $fav ) ); 1148 } 1149 } 1150 } 1151 break; 1152 1153 /** Subscriptions *********************************/ 1154 1155 case 'topic_subscriptions': 1156 $user_id = $insert_post['user_id']; 1157 $items = wp_list_pluck( $insert_postmeta, '_bbp_subscriptions' ); 1158 if ( is_numeric( $user_id ) && ! empty( $items ) ) { 1159 foreach ( $items as $value ) { 1160 1161 // Maybe string with commas 1162 $value = is_string( $value ) 1163 ? explode( ',', $value ) 1164 : (array) $value; 1165 1166 // Add user ID to topics subscribed users 1167 foreach ( $value as $fav ) { 1168 bbp_add_user_topic_subscription( $user_id, $this->callback_topicid( $fav ) ); 1169 } 1170 } 1171 } 1172 break; 1173 1174 /** Favorites *************************************/ 1175 1176 case 'favorites': 1177 $user_id = $insert_post['user_id']; 1178 $items = wp_list_pluck( $insert_postmeta, '_bbp_favorites' ); 1179 if ( is_numeric( $user_id ) && ! empty( $items ) ) { 1180 foreach ( $items as $value ) { 1181 1182 // Maybe string with commas 1183 $value = is_string( $value ) 1184 ? explode( ',', $value ) 1185 : (array) $value; 1186 1187 // Add user ID to topics favorited users 1188 foreach ( $value as $fav ) { 1189 bbp_add_user_favorite( $user_id, $this->callback_topicid( $fav ) ); 1190 } 1191 } 1192 } 1193 break; 1194 1195 /** Forum, Topic, Reply ***************************/ 1196 1197 default: 1198 $post_id = wp_insert_post( $insert_post ); 1199 1200 if ( is_numeric( $post_id ) ) { 1201 1202 foreach ( $insert_postmeta as $key => $value ) { 1203 1204 add_post_meta( $post_id, $key, $value, true ); 1205 1206 /** 1207 * If we are using the sync_table add 1208 * the meta '_id' keys to the table 1209 * 1210 * Forums: _bbp_old_forum_id // The old forum ID 1211 * _bbp_old_forum_parent_id // The old forum parent ID 1212 * 1213 * Topics: _bbp_forum_id // The new forum ID 1214 * _bbp_old_topic_id // The old topic ID 1215 * _bbp_old_closed_status_id // The old topic open/closed status 1216 * _bbp_old_sticky_status_id // The old topic sticky status 1217 * 1218 * Replies: _bbp_forum_id // The new forum ID 1219 * _bbp_topic_id // The new topic ID 1220 * _bbp_old_reply_id // The old reply ID 1221 * _bbp_old_reply_to_id // The old reply to ID 1222 */ 1223 if ( '_id' === substr( $key, -3 ) && ( true === $this->sync_table ) ) { 1224 $this->wpdb->insert( $this->sync_table_name, array( 'value_type' => 'post', 'value_id' => $post_id, 'meta_key' => $key, 'meta_value' => $value ) ); 1225 } 1226 1227 /** 1228 * Replies need to save their old reply_to ID for 1229 * hierarchical replies association. Later we update 1230 * the _bbp_reply_to value with the new bbPress 1231 * value using convert_reply_to_parents() 1232 */ 1233 if ( ( 'reply' === $to_type ) && ( '_bbp_old_reply_to_id' === $key ) ) { 1234 add_post_meta( $post_id, '_bbp_reply_to', $value ); 1235 } 1236 } 1237 } 1238 break; 1239 } 1240 $has_insert = true; 1241 } 1242 } 1243 } 1244 } 1245 1246 return ! $has_insert; 1247 } 1248 1249 /** 1250 * This method converts old forum heirarchy to new bbPress heirarchy. 1251 */ 1252 public function convert_forum_parents( $start ) { 1253 1254 $has_update = false; 1255 1256 if ( ! empty( $this->sync_table ) ) { 1257 $query = $this->wpdb->prepare( "SELECT value_id, meta_value FROM {$this->sync_table_name} WHERE meta_key = %s AND meta_value > 0 LIMIT {$start}, {$this->max_rows}", '_bbp_old_forum_parent_id' ); 1258 } else { 1259 $query = $this->wpdb->prepare( "SELECT post_id AS value_id, meta_value FROM {$this->wpdb->postmeta} WHERE meta_key = %s AND meta_value > 0 LIMIT {$start}, {$this->max_rows}", '_bbp_old_forum_parent_id' ); 1260 } 1261 1262 update_option( '_bbp_converter_query', $query ); 1263 1264 $forum_array = $this->wpdb->get_results( $query ); 1265 1266 foreach ( (array) $forum_array as $row ) { 1267 $parent_id = $this->callback_forumid( $row->meta_value ); 1268 $this->wpdb->query( $this->wpdb->prepare( "UPDATE {$this->wpdb->posts} SET post_parent = %d WHERE ID = %d LIMIT 1", $parent_id, $row->value_id ) ); 1269 $has_update = true; 1270 } 1271 1272 return ! $has_update; 1273 } 1274 1275 /** 1276 * This method converts old topic stickies to new bbPress stickies. 1277 * 1278 * @since 2.5.0 bbPress (r5170) 1279 * 1280 * @uses WPDB $wpdb 1281 * @uses bbp_stick_topic() to set the imported topic as sticky 1282 * 1283 */ 1284 public function convert_topic_stickies( $start ) { 1285 1286 $has_update = false; 1287 1288 if ( ! empty( $this->sync_table ) ) { 1289 $query = $this->wpdb->prepare( "SELECT value_id, meta_value FROM {$this->sync_table_name} WHERE meta_key = %s AND meta_value = %s LIMIT {$start}, {$this->max_rows}", '_bbp_old_sticky_status_id', 'sticky' ); 1290 } else { 1291 $query = $this->wpdb->prepare( "SELECT post_id AS value_id, meta_value FROM {$this->wpdb->postmeta} WHERE meta_key = %s AND meta_value = %s LIMIT {$start}, {$this->max_rows}", '_bbp_old_sticky_status_id', 'sticky' ); 1292 } 1293 1294 update_option( '_bbp_converter_query', $query ); 1295 1296 $sticky_array = $this->wpdb->get_results( $query ); 1297 1298 foreach ( (array) $sticky_array as $row ) { 1299 bbp_stick_topic( $row->value_id ); 1300 $has_update = true; 1301 } 1302 1303 return ! $has_update; 1304 } 1305 1306 /** 1307 * This method converts old topic super stickies to new bbPress super stickies. 1308 * 1309 * @since 2.5.0 bbPress (r5170) 1310 * 1311 * @uses WPDB $wpdb 1312 * @uses bbp_stick_topic() to set the imported topic as super sticky 1313 * 1314 */ 1315 public function convert_topic_super_stickies( $start ) { 1316 1317 $has_update = false; 1318 1319 if ( ! empty( $this->sync_table ) ) { 1320 $query = $this->wpdb->prepare( "SELECT value_id, meta_value FROM {$this->sync_table_name} WHERE meta_key = %s AND meta_value = %s LIMIT {$start}, {$this->max_rows}", '_bbp_old_sticky_status_id', 'super-sticky' ); 1321 } else { 1322 $query = $this->wpdb->prepare( "SELECT post_id AS value_id, meta_value FROM {$this->wpdb->postmeta} WHERE meta_key = %s AND meta_value = %s LIMIT {$start}, {$this->max_rows}", '_bbp_old_sticky_status_id', 'super-sticky' ); 1323 } 1324 1325 update_option( '_bbp_converter_query', $query ); 1326 1327 $sticky_array = $this->wpdb->get_results( $query ); 1328 1329 foreach ( (array) $sticky_array as $row ) { 1330 $super = true; 1331 bbp_stick_topic( $row->value_id, $super ); 1332 $has_update = true; 1333 } 1334 1335 return ! $has_update; 1336 } 1337 1338 /** 1339 * This method converts old closed topics to bbPress closed topics. 1340 * 1341 * @since 2.6.0 bbPress (r5425) 1342 * 1343 * @uses bbp_close_topic() to close topics properly 1344 * 1345 */ 1346 public function convert_topic_closed_topics( $start ) { 1347 1348 $has_update = false; 1349 1350 if ( ! empty( $this->sync_table ) ) { 1351 $query = $this->wpdb->prepare( "SELECT value_id, meta_value FROM {$this->sync_table_name} WHERE meta_key = %s AND meta_value = %s LIMIT {$start}, {$this->max_rows}", '_bbp_old_closed_status_id', 'closed' ); 1352 } else { 1353 $query = $this->wpdb->prepare( "SELECT post_id AS value_id, meta_value FROM {$this->wpdb->postmeta} WHERE meta_key = %s AND meta_value = %s LIMIT {$start}, {$this->max_rows}", '_bbp_old_closed_status_id', 'closed' ); 1354 } 1355 1356 update_option( '_bbp_converter_query', $query ); 1357 1358 $closed_topic = $this->wpdb->get_results( $query ); 1359 1360 foreach ( (array) $closed_topic as $row ) { 1361 bbp_close_topic( $row->value_id ); 1362 $has_update = true; 1363 } 1364 1365 return ! $has_update; 1366 } 1367 1368 /** 1369 * This method converts old reply_to post id to new bbPress reply_to post id. 1370 * 1371 * @since 2.4.0 bbPress (r5093) 1372 */ 1373 public function convert_reply_to_parents( $start ) { 1374 1375 $has_update = false; 1376 1377 if ( ! empty( $this->sync_table ) ) { 1378 $query = $this->wpdb->prepare( "SELECT value_id, meta_value FROM {$this->sync_table_name} WHERE meta_key = %s AND meta_value > 0 LIMIT {$start}, {$this->max_rows}", '_bbp_old_reply_to_id' ); 1379 } else { 1380 $query = $this->wpdb->prepare( "SELECT post_id AS value_id, meta_value FROM {$this->wpdb->postmeta} WHERE meta_key = %s AND meta_value > 0 LIMIT {$start}, {$this->max_rows}", '_bbp_old_reply_to_id' ); 1381 } 1382 1383 update_option( '_bbp_converter_query', $query ); 1384 1385 $reply_to_array = $this->wpdb->get_results( $query ); 1386 1387 foreach ( (array) $reply_to_array as $row ) { 1388 $reply_to = $this->callback_reply_to( $row->meta_value ); 1389 $this->wpdb->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 ) ); 1390 $has_update = true; 1391 } 1392 1393 return ! $has_update; 1394 } 1395 1396 /** 1397 * This method converts anonymous topics. 1398 * 1399 * @since 2.6.0 bbPress (r5538) 1400 * 1401 * @uses add_post_meta() To add _bbp_anonymous_name topic meta key 1402 */ 1403 public function convert_anonymous_topic_authors( $start ) { 1404 1405 $has_update = false; 1406 1407 if ( ! empty( $this->sync_table ) ) { 1408 $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 1409 FROM {$this->sync_table_name} AS sync_table1 1410 INNER JOIN {$this->sync_table_name} AS sync_table2 1411 ON ( sync_table1.value_id = sync_table2.value_id ) 1412 WHERE sync_table1.meta_value = %s 1413 AND sync_table2.meta_key = %s 1414 LIMIT {$start}, {$this->max_rows}", 'true', '_bbp_old_topic_author_name_id' ); 1415 } else { 1416 $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 1417 FROM {$this->wpdb->postmeta} AS wp_postmeta1 1418 INNER JOIN {$this->wpdb->postmeta} AS wp_postmeta2 1419 ON ( wp_postmeta1.post_id = wp_postmeta2.post_id ) 1420 WHERE wp_postmeta1.meta_value = %s 1421 AND wp_postmeta2.meta_key = %s 1422 LIMIT {$start}, {$this->max_rows}", 'true', '_bbp_old_topic_author_name_id' ); 1423 1424 } 1425 1426 update_option( '_bbp_converter_query', $query ); 1427 1428 $anonymous_topics = $this->wpdb->get_results( $query ); 1429 1430 foreach ( (array) $anonymous_topics as $row ) { 1431 $anonymous_topic_author_id = 0; 1432 $this->wpdb->query( $this->wpdb->prepare( "UPDATE {$this->wpdb->posts} SET post_author = %d WHERE ID = %d LIMIT 1", $anonymous_topic_author_id, $row->topic_id ) ); 1433 1434 add_post_meta( $row->topic_id, '_bbp_anonymous_name', $row->topic_author ); 1435 1436 $has_update = true; 1437 } 1438 1439 return ! $has_update; 1440 } 1441 1442 /** 1443 * This method converts anonymous replies. 1444 * 1445 * @since 2.6.0 bbPress (r5538) 1446 * 1447 * @uses add_post_meta() To add _bbp_anonymous_name reply meta key 1448 */ 1449 public function convert_anonymous_reply_authors( $start ) { 1450 1451 $has_update = false; 1452 1453 if ( ! empty( $this->sync_table ) ) { 1454 $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 1455 FROM {$this->sync_table_name} AS sync_table1 1456 INNER JOIN {$this->sync_table_name} AS sync_table2 1457 ON ( sync_table1.value_id = sync_table2.value_id ) 1458 WHERE sync_table1.meta_value = %s 1459 AND sync_table2.meta_key = %s 1460 LIMIT {$start}, {$this->max_rows}", 'true', '_bbp_old_reply_author_name_id' ); 1461 } else { 1462 $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 1463 FROM {$this->wpdb->postmeta} AS wp_postmeta1 1464 INNER JOIN {$this->wpdb->postmeta} AS wp_postmeta2 1465 ON ( wp_postmeta1.post_id = wp_postmeta2.post_id ) 1466 WHERE wp_postmeta1.meta_value = %s 1467 AND wp_postmeta2.meta_key = %s 1468 LIMIT {$start}, {$this->max_rows}", 'true', '_bbp_old_reply_author_name_id' ); 1469 1470 } 1471 1472 update_option( '_bbp_converter_query', $query ); 1473 1474 $anonymous_replies = $this->wpdb->get_results( $query ); 1475 1476 foreach ( (array) $anonymous_replies as $row ) { 1477 $anonymous_reply_author_id = 0; 1478 $this->wpdb->query( $this->wpdb->prepare( "UPDATE {$this->wpdb->posts} SET post_author = %d WHERE ID = %d LIMIT 1", $anonymous_reply_author_id, $row->reply_id ) ); 1479 1480 add_post_meta( $row->reply_id, '_bbp_anonymous_name', $row->reply_author ); 1481 1482 $has_update = true; 1483 } 1484 1485 return ! $has_update; 1486 } 1487 1488 /** 1489 * This method deletes data from the wp database. 1490 */ 1491 public function clean( $start ) { 1492 1493 $start = 0; 1494 $has_delete = false; 1495 1496 /** Delete bbconverter topics/forums/posts ****************************/ 1497 1498 if ( true === $this->sync_table ) { 1499 $query = $this->wpdb->prepare( "SELECT value_id FROM {$this->sync_table_name} INNER JOIN {$this->wpdb->posts} ON(value_id = ID) WHERE meta_key LIKE '_bbp_%' AND value_type = %s GROUP BY value_id ORDER BY value_id DESC LIMIT {$this->max_rows}", 'post' ); 1500 } else { 1501 $query = $this->wpdb->prepare( "SELECT post_id AS value_id FROM {$this->wpdb->postmeta} WHERE meta_key LIKE '_bbp_%' GROUP BY post_id ORDER BY post_id DESC LIMIT {$this->max_rows}" ); 1502 } 1503 1504 update_option( '_bbp_converter_query', $query ); 1505 1506 $posts = $this->wpdb->get_results( $query, ARRAY_A ); 1507 1508 if ( isset( $posts[0] ) && ! empty( $posts[0]['value_id'] ) ) { 1509 foreach ( (array) $posts as $value ) { 1510 wp_delete_post( $value['value_id'], true ); 1511 } 1512 $has_delete = true; 1513 } 1514 1515 /** Delete bbconverter users ******************************************/ 1516 1517 if ( true === $this->sync_table ) { 1518 $query = $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' ); 1519 } else { 1520 $query = $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' ); 1521 } 1522 1523 update_option( '_bbp_converter_query', $query ); 1524 1525 $users = $this->wpdb->get_results( $query, ARRAY_A ); 1526 1527 if ( ! empty( $users ) ) { 1528 foreach ( $users as $value ) { 1529 wp_delete_user( $value['value_id'] ); 1530 } 1531 $has_delete = true; 1532 } 1533 1534 unset( $posts ); 1535 unset( $users ); 1536 1537 return ! $has_delete; 1538 } 1539 1540 /** 1541 * This method deletes passwords from the wp database. 1542 * 1543 * @param int Start row 1544 */ 1545 public function clean_passwords( $start ) { 1546 1547 $has_delete = false; 1548 1549 /** Delete bbconverter passwords **************************************/ 1550 1551 $query = $this->wpdb->prepare( "SELECT user_id, meta_value FROM {$this->wpdb->usermeta} WHERE meta_key = %s LIMIT {$start}, {$this->max_rows}", '_bbp_password' ); 1552 update_option( '_bbp_converter_query', $query ); 1553 1554 $bbconverter = $this->wpdb->get_results( $query, ARRAY_A ); 1555 1556 if ( ! empty( $bbconverter ) ) { 1557 1558 foreach ( $bbconverter as $value ) { 1559 if ( is_serialized( $value['meta_value'] ) ) { 1560 $this->wpdb->query( $this->wpdb->prepare( "UPDATE {$this->wpdb->users} SET user_pass = '' WHERE ID = %d", $value['user_id'] ) ); 1561 } else { 1562 $this->wpdb->query( $this->wpdb->prepare( "UPDATE {$this->wpdb->users} SET user_pass = %s WHERE ID = %d", $value['meta_value'], $value['user_id'] ) ); 1563 $this->wpdb->query( $this->wpdb->prepare( "DELETE FROM {$this->wpdb->usermeta} WHERE meta_key = %s AND user_id = %d", '_bbp_password', $value['user_id'] ) ); 1564 } 1565 } 1566 $has_delete = true; 1567 } 1568 1569 return ! $has_delete; 1570 } 1571 1572 /** 1573 * This method implements the authentication for the different forums. 1574 * 1575 * @param string Unencoded password. 1576 */ 1577 abstract protected function authenticate_pass( $password, $hash ); 1578 1579 /** 1580 * Info 1581 */ 1582 abstract protected function info(); 1583 1584 /** 1585 * This method grabs appropriate fields from the table specified 1586 * 1587 * @param string The table name to grab fields from 1588 */ 1589 private function get_fields( $tablename ) { 1590 $rval = array(); 1591 $field_array = $this->wpdb->get_results( 'DESCRIBE ' . $tablename, ARRAY_A ); 1592 1593 foreach ( $field_array as $field ) { 1594 $rval[] = $field['Field']; 1595 } 1596 1597 if ( $tablename === $this->wpdb->users ) { 1598 $rval[] = 'role'; 1599 $rval[] = 'yim'; 1600 $rval[] = 'aim'; 1601 $rval[] = 'jabber'; 1602 } 1603 1604 return $rval; 1605 } 1606 1607 /** Callbacks *************************************************************/ 1608 1609 /** 1610 * Run password through wp_hash_password() 1611 * 1612 * @param string $username 1613 * @param string $password 1614 */ 1615 public function callback_pass( $username, $password ) { 1616 $user = $this->wpdb->get_row( $this->wpdb->prepare( "SELECT * FROM {$this->wpdb->users} WHERE user_login = %s AND user_pass = '' LIMIT 1", $username ) ); 1617 if ( ! empty( $user ) ) { 1618 $usermeta = $this->wpdb->get_row( $this->wpdb->prepare( "SELECT * FROM {$this->wpdb->usermeta} WHERE meta_key = %s AND user_id = %d LIMIT 1", '_bbp_password', $user->ID ) ); 1619 1620 if ( ! empty( $usermeta ) ) { 1621 if ( $this->authenticate_pass( $password, $usermeta->meta_value ) ) { 1622 $this->wpdb->query( $this->wpdb->prepare( "UPDATE {$this->wpdb->users} SET user_pass = %s WHERE ID = %d", wp_hash_password( $password ), $user->ID ) ); 1623 $this->wpdb->query( $this->wpdb->prepare( "DELETE FROM {$this->wpdb->usermeta} WHERE meta_key = %s AND user_id = %d", '_bbp_password', $user->ID ) ); 29 // Look for the converter file in the converters directory 30 if ( false !== $curdir ) { 31 while ( $file = readdir( $curdir ) ) { 32 if ( stristr( $file, '.php' ) && stristr( $file, 'index' ) === false ) { 33 $name = preg_replace( '/.php/', '', $file ); 34 if ( 'Example' !== $name ) { 35 $files[ $name ] = $path . $file; 1624 36 } 1625 37 } … … 1627 39 } 1628 40 1629 /** 1630 * A mini cache system to reduce database calls to forum ID's 1631 * 1632 * @param string $field 1633 * @return string 1634 */ 1635 private function callback_forumid( $field ) { 1636 if ( ! isset( $this->map_forumid[ $field ] ) ) { 1637 if ( ! empty( $this->sync_table ) ) { 1638 $row = $this->wpdb->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 ) ); 1639 } else { 1640 $row = $this->wpdb->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 ) ); 1641 } 41 // Close the directory 42 closedir( $curdir ); 1642 43 1643 if ( ! is_null( $row ) ) { 1644 $this->map_forumid[ $field ] = $row->value_id; 1645 } else { 1646 $this->map_forumid[ $field ] = 0; 1647 } 1648 } 1649 return $this->map_forumid[ $field ]; 44 // Sort keys alphabetically, ignoring upper/lower casing 45 if ( ! empty( $files ) ) { 46 natcasesort( $files ); 1650 47 } 1651 48 1652 /** 1653 * A mini cache system to reduce database calls to topic ID's 1654 * 1655 * @param string $field 1656 * @return string 1657 */ 1658 private function callback_topicid( $field ) { 1659 if ( ! isset( $this->map_topicid[ $field ] ) ) { 1660 if ( ! empty( $this->sync_table ) ) { 1661 $row = $this->wpdb->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 ) ); 1662 } else { 1663 $row = $this->wpdb->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 ) ); 1664 } 1665 1666 if ( ! is_null( $row ) ) { 1667 $this->map_topicid[ $field ] = $row->value_id; 1668 } else { 1669 $this->map_topicid[ $field ] = 0; 1670 } 1671 } 1672 return $this->map_topicid[ $field ]; 1673 } 1674 1675 /** 1676 * A mini cache system to reduce database calls to reply_to post id. 1677 * 1678 * @since 2.4.0 bbPress (r5093) 1679 * 1680 * @param string $field 1681 * @return string 1682 */ 1683 private function callback_reply_to( $field ) { 1684 if ( ! isset( $this->map_reply_to[ $field ] ) ) { 1685 if ( ! empty( $this->sync_table ) ) { 1686 $row = $this->wpdb->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 ) ); 1687 } else { 1688 $row = $this->wpdb->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 ) ); 1689 } 1690 1691 if ( ! is_null( $row ) ) { 1692 $this->map_reply_to[ $field ] = $row->value_id; 1693 } else { 1694 $this->map_reply_to[ $field ] = 0; 1695 } 1696 } 1697 return $this->map_reply_to[ $field ]; 1698 } 1699 1700 /** 1701 * A mini cache system to reduce database calls to user ID's 1702 * 1703 * @param string $field 1704 * @return string 1705 */ 1706 private function callback_userid( $field ) { 1707 if ( ! isset( $this->map_userid[ $field ] ) ) { 1708 if ( ! empty( $this->sync_table ) ) { 1709 $row = $this->wpdb->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 ) ); 1710 } else { 1711 $row = $this->wpdb->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 ) ); 1712 } 1713 1714 if ( ! is_null( $row ) ) { 1715 $this->map_userid[ $field ] = $row->value_id; 1716 } else { 1717 if ( ! empty( $_POST['_bbp_converter_convert_users'] ) && ( (int) $_POST['_bbp_converter_convert_users'] === 1 ) ) { 1718 $this->map_userid[ $field ] = 0; 1719 } else { 1720 $this->map_userid[ $field ] = $field; 1721 } 1722 } 1723 } 1724 return $this->map_userid[ $field ]; 1725 } 1726 1727 /** 1728 * Check if the topic or reply author is anonymous 1729 * 1730 * @since 2.6.0 bbPress (r5544) 1731 * 1732 * @param string $field 1733 * @return string 1734 */ 1735 private function callback_check_anonymous( $field ) { 1736 1737 if ( $this->callback_userid( $field ) == 0 ) { 1738 $field = 'true'; 1739 } else { 1740 $field = 'false'; 1741 } 1742 1743 return $field; 1744 } 1745 1746 /** 1747 * A mini cache system to reduce database calls map topics ID's to forum ID's 1748 * 1749 * @param string $field 1750 * @return string 1751 */ 1752 private function callback_topicid_to_forumid( $field ) { 1753 $topicid = $this->callback_topicid( $field ); 1754 if ( empty( $topicid ) ) { 1755 $this->map_topicid_to_forumid[ $topicid ] = 0; 1756 } elseif ( ! isset( $this->map_topicid_to_forumid[ $topicid ] ) ) { 1757 $row = $this->wpdb->get_row( $this->wpdb->prepare( "SELECT post_parent FROM {$this->wpdb->posts} WHERE ID = %d LIMIT 1", $topicid ) ); 1758 1759 if ( ! is_null( $row ) ) { 1760 $this->map_topicid_to_forumid[ $topicid ] = $row->post_parent; 1761 } else { 1762 $this->map_topicid_to_forumid[ $topicid ] = 0; 1763 } 1764 } 1765 1766 return $this->map_topicid_to_forumid[ $topicid ]; 1767 } 1768 1769 protected function callback_slug( $field ) { 1770 return sanitize_title( $field ); 1771 } 1772 1773 protected function callback_negative( $field ) { 1774 if ( $field < 0 ) { 1775 return 0; 1776 } else { 1777 return $field; 1778 } 1779 } 1780 1781 protected function callback_html( $field ) { 1782 require_once bbpress()->admin->admin_dir . 'parser.php'; 1783 $bbcode = BBCode::getInstance(); 1784 return html_entity_decode( $bbcode->Parse( $field ) ); 1785 } 1786 1787 protected function callback_null( $field ) { 1788 if ( is_null( $field ) ) { 1789 return ''; 1790 } else { 1791 return $field; 1792 } 1793 } 1794 1795 protected function callback_datetime( $field ) { 1796 if ( is_numeric( $field ) ) { 1797 return date( 'Y-m-d H:i:s', $field ); 1798 } else { 1799 return date( 'Y-m-d H:i:s', strtotime( $field ) ); 1800 } 1801 } 49 // Filter & return 50 return (array) apply_filters( 'bbp_get_converters', $files ); 1802 51 } 1803 52 … … 1807 56 * of your choice. 1808 57 * 58 * @since 2.0.0 59 * 1809 60 * @param string $platform Name of valid platform class. 1810 61 */ 1811 62 function bbp_new_converter( $platform ) { 1812 $found = false;1813 63 1814 if ( $curdir = opendir( bbpress()->admin->admin_dir . 'converters/' ) ) { 1815 while ( $file = readdir( $curdir ) ) { 1816 if ( stristr( $file, '.php' ) && stristr( $file, 'index' ) === FALSE ) { 1817 $file = preg_replace( '/.php/', '', $file ); 1818 if ( $platform === $file ) { 1819 $found = true; 1820 continue; 1821 } 1822 } 1823 } 1824 closedir( $curdir ); 64 // Default value 65 $converters = bbp_get_converters(); 66 67 // Create a new converter object if it's found 68 if ( isset( $converters[ $platform ] ) ) { 69 require_once $converters[ $platform ]; 70 return new $platform; 1825 71 } 1826 72 1827 if ( true === $found ) { 1828 require_once bbpress()->admin->admin_dir . 'converters/' . $platform . '.php'; 1829 return new $platform; 1830 } else { 1831 return null; 1832 } 73 // Return null if no converter was found 74 return null; 1833 75 }
Note: See TracChangeset
for help on using the changeset viewer.