PluginProbe
bbPress / 2.1-beta-1
bbPress v2.1-beta-1
2.6.17 trunk 2.0 2.0-beta-1 2.0-beta-2b 2.0-beta-3 2.0-beta-3b 2.0-rc-2 2.0-rc-3 2.0-rc-4 2.0-rc-5 2.0.1 2.0.2 2.0.3 2.1 2.1-beta-1 2.1-rc1 2.1-rc2 2.1-rc3 2.1-rc4 2.1.1 2.1.2 2.1.3 2.2 2.2.1 All 72 releases
bbpress / bbp-admin / bbp-converter.php

bbp-converter.php in bbPress 2.1-beta-1, at bbp-admin/bbp-converter.php

1,273 lines 39.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * bbPress Converter
5 *
6 * Based on the hard work of Adam Ellis at http://bbconverter.com
7 *
8 * @package bbPress
9 * @subpackage Administration
10 */
11
12 // Exit if accessed directly
13 if ( !defined( 'ABSPATH' ) ) exit;
14
15 /**
16 * Main BBP_Converter Class
17 */
18 class BBP_Converter {
19
20 /**
21 * The main bbPress Converter loader
22 *
23 * @since bbPress (r3813)
24 * @uses BBP_Converter::includes() Include the required files
25 * @uses BBP_Converter::setup_actions() Setup the actions
26 */
27 public function __construct() {
28 $this->setup_actions();
29 }
30
31 /**
32 * Setup the default actions
33 *
34 * @since bbPress (r3813)
35 * @uses add_action() To add various actions
36 */
37 private function setup_actions() {
38
39 // Attach to the admin head with our ajax requests cycle and css
40 add_action( 'bbp_admin_head', array( $this, 'admin_head' ) );
41
42 // Attach the bbConverter admin settings action to the WordPress admin init action.
43 add_action( 'bbp_register_admin_settings', array( $this, 'register_admin_settings' ) );
44
45 // Attach to the login process to aid in converting passwords to wordpress.
46 add_action( 'login_form_login', array( $this, 'convert_pass' ) );
47
48 // Attach to the admin ajax request to process cycles
49 add_action( 'wp_ajax_bbconverter_process', array( $this, 'process_callback' ) );
50 }
51
52 /**
53 * Register the settings
54 *
55 * @since bbPress (r3813)
56 * @uses add_settings_section() To add our own settings section
57 * @uses add_settings_field() To add various settings fields
58 * @uses register_setting() To register various settings
59 */
60 public function register_admin_settings() {
61
62 // Add the main section
63 add_settings_section( 'bbpress_converter_main', __( 'Main Settings', 'bbpress' ), 'bbp_converter_setting_callback_main_section', 'bbpress_converter' );
64
65 // System Select
66 add_settings_field( '_bbp_converter_platform', __( 'Select Platform', 'bbpress' ), 'bbp_converter_setting_callback_platform', 'bbpress_converter', 'bbpress_converter_main' );
67 register_setting ( 'bbpress_converter_main', '_bbp_converter_platform', 'sanitize_title' );
68
69 // Database Server
70 add_settings_field( '_bbp_converter_db_server', __( 'Database Server', 'bbpress' ), 'bbp_converter_setting_callback_dbserver', 'bbpress_converter', 'bbpress_converter_main' );
71 register_setting ( 'bbpress_converter_main', '_bbp_converter_db_server', 'sanitize_title' );
72
73 // Database Server Port
74 add_settings_field( '_bbp_converter_db_port', __( 'Database Port', 'bbpress' ), 'bbp_converter_setting_callback_dbport', 'bbpress_converter', 'bbpress_converter_main' );
75 register_setting ( 'bbpress_converter_main', '_bbp_converter_db_port', 'sanitize_title' );
76
77 // Database Name
78 add_settings_field( '_bbp_converter_db_name', __( 'Database Name', 'bbpress' ), 'bbp_converter_setting_callback_dbname', 'bbpress_converter', 'bbpress_converter_main' );
79 register_setting ( 'bbpress_converter_main', '_bbp_converter_db_name', 'sanitize_title' );
80
81 // Database User
82 add_settings_field( '_bbp_converter_db_user', __( 'Database User', 'bbpress' ), 'bbp_converter_setting_callback_dbuser', 'bbpress_converter', 'bbpress_converter_main' );
83 register_setting ( 'bbpress_converter_main', '_bbp_converter_db_user', 'sanitize_title' );
84
85 // Database Pass
86 add_settings_field( '_bbp_converter_db_pass', __( 'Database Password', 'bbpress' ), 'bbp_converter_setting_callback_dbpass', 'bbpress_converter', 'bbpress_converter_main' );
87 register_setting ( 'bbpress_converter_main', '_bbp_converter_db_pass', 'sanitize_title' );
88
89 // Database Prefix
90 add_settings_field( '_bbp_converter_db_prefix', __( 'Table Prefix', 'bbpress' ), 'bbp_converter_setting_callback_dbprefix', 'bbpress_converter', 'bbpress_converter_main' );
91 register_setting ( 'bbpress_converter_main', '_bbp_converter_db_prefix', 'sanitize_title' );
92
93 // Add the options section
94 add_settings_section( 'bbpress_converter_opt', __( 'Options', 'bbpress' ), 'bbp_converter_setting_callback_options_section', 'bbpress_converter' );
95
96 // Rows Limit
97 add_settings_field( '_bbp_converter_rows', __( 'Rows Limit', 'bbpress' ), 'bbp_converter_setting_callback_rows', 'bbpress_converter', 'bbpress_converter_opt' );
98 register_setting ( 'bbpress_converter_opt', '_bbp_converter_rows', 'intval' );
99
100 // Delay Time
101 add_settings_field( '_bbp_converter_delay_time', __( 'Delay Time', 'bbpress' ), 'bbp_converter_setting_callback_delay_time', 'bbpress_converter', 'bbpress_converter_opt' );
102 register_setting ( 'bbpress_converter_opt', '_bbp_converter_delay_time', 'intval' );
103
104 // Convert Users ?
105 add_settings_field( '_bbp_converter_convert_users', __( 'Convert Users', 'bbpress' ), 'bbp_converter_setting_callback_convert_users', 'bbpress_converter', 'bbpress_converter_opt' );
106 register_setting ( 'bbpress_converter_opt', '_bbp_converter_convert_users', 'intval' );
107
108 // Clean
109 add_settings_field( '_bbp_converter_clean', __( 'Clean', 'bbpress' ), 'bbp_converter_setting_callback_clean', 'bbpress_converter', 'bbpress_converter_opt' );
110 register_setting ( 'bbpress_converter_opt', '_bbp_converter_clean', 'intval' );
111
112 // Restart
113 add_settings_field( '_bbp_converter_restart', __( 'Restart', 'bbpress' ), 'bbp_converter_setting_callback_restart', 'bbpress_converter', 'bbpress_converter_opt' );
114 register_setting ( 'bbpress_converter_opt', '_bbp_converter_restart', 'intval' );
115 }
116
117 /**
118 * Admin scripts
119 *
120 * @since bbPress (r3813)
121 */
122 public function admin_head() { ?>
123
124 <style type="text/css" media="screen">
125 /*<![CDATA[*/
126
127 div.bbp-converter-updated,
128 div.bbp-converter-warning {
129 border-radius: 3px 3px 3px 3px;
130 border-style: solid;
131 border-width: 1px;
132 padding: 5px 5px 5px 5px;
133 }
134
135 div.bbp-converter-updated {
136 height: 300px;
137 overflow: auto;
138 display: none;
139 background-color: #FFFFE0;
140 border-color: #E6DB55;
141 font-family: monospace;
142 }
143
144 div.bbp-converter-updated p {
145 margin: 0.5em 0;
146 padding: 2px;
147 }
148
149 div.bbp-converter-updated p strong.loading {
150 padding: 2px 20px 2px 0;
151 background-image: url('<?php echo admin_url(); ?>images/wpspin_light.gif');
152 background-repeat: no-repeat;
153 background-position: center right;
154 }
155
156 #bbp-converter-stop {
157 display:none;
158 }
159
160 #bbp-converter-progress {
161 display:none;
162 }
163
164 /*]]>*/
165 </style>
166
167 <script language="javascript">
168
169 var bbconverter_is_running = false;
170 var bbconverter_run_timer;
171 var bbconverter_delay_time = 0;
172
173 function bbconverter_grab_data() {
174 var values = {};
175 jQuery.each(jQuery('#bbp-converter-settings').serializeArray(), function(i, field) {
176 values[field.name] = field.value;
177 });
178
179 if( values['_bbp_converter_restart'] ) {
180 jQuery('#_bbp_converter_restart').removeAttr("checked");
181 }
182
183 if( values['_bbp_converter_delay_time'] ) {
184 bbconverter_delay_time = values['_bbp_converter_delay_time'] * 1000;
185 }
186
187 values['action'] = 'bbconverter_process';
188 return values;
189 }
190
191 function bbconverter_start() {
192 if( false == bbconverter_is_running ) {
193 bbconverter_is_running = true;
194 jQuery('#bbp-converter-start').hide();
195 jQuery('#bbp-converter-stop').show();
196 jQuery('#bbp-converter-progress').show();
197 bbconverter_log( "Starting Conversion..." );
198 jQuery.post(ajaxurl, bbconverter_grab_data(), function(response) {
199 var response_length = response.length - 1;
200 response = response.substring(0,response_length);
201 bbconverter_success(response);
202 });
203 }
204 }
205
206 function bbconverter_run() {
207 jQuery.post(ajaxurl, bbconverter_grab_data(), function(response) {
208 var response_length = response.length - 1;
209 response = response.substring(0,response_length);
210 bbconverter_success(response);
211 });
212 }
213
214 function bbconverter_stop() {
215 bbconverter_is_running = false;
216 jQuery('#bbp-converter-message strong').removeClass( 'loading' );
217 }
218
219 function bbconverter_success(response) {
220 bbconverter_log(response);
221
222 if ( response == 'Conversion Complete' || response.indexOf('error') > -1 ) {
223 bbconverter_log('<b>Repair any missing information: <a href="<?php echo admin_url(); ?>tools.php?page=bbp-repair">Continue</a></b>');
224 jQuery('#bbp-converter-start').show();
225 jQuery('#bbp-converter-stop').hide();
226 jQuery('#bbp-converter-progress').hide();
227 bbconverter_stop();
228 clearTimeout( bbconverter_run_timer );
229 } else if( bbconverter_is_running ) { // keep going
230 jQuery('#bbp-converter-progress').show();
231 clearTimeout( bbconverter_run_timer );
232 bbconverter_run_timer = setTimeout( 'bbconverter_run()', bbconverter_delay_time );
233 } else {
234 jQuery('#bbp-converter-start').show();
235 jQuery('#bbp-converter-stop').hide();
236 jQuery('#bbp-converter-progress').hide();
237 clearTimeout( bbconverter_run_timer );
238 }
239 }
240
241 function bbconverter_log(text) {
242 if ( jQuery('#bbp-converter-message').css('display') == 'none' ) {
243 jQuery('#bbp-converter-message').show();
244 }
245 if ( text ) {
246 jQuery('#bbp-converter-message strong').removeClass( 'loading' );
247 jQuery('#bbp-converter-message').prepend('<p><strong class="loading">' + text + '</strong></p>');
248 }
249 }
250
251 </script>
252
253 <?php
254 }
255
256 /**
257 * Callback processor
258 *
259 * @since bbPress (r3813)
260 */
261 public function process_callback() {
262
263 if ( ! ini_get( 'safe_mode' ) ) {
264 set_time_limit( 0 );
265 ini_set( 'memory_limit', '256M' );
266 ini_set( 'implicit_flush', '1' );
267 ignore_user_abort( true );
268 }
269
270 // Save step and count so that it can be restarted.
271 if ( ! get_option( '_bbp_converter_step' ) || ( !empty( $_POST['_bbp_converter_restart'] ) ) ) {
272 update_option( '_bbp_converter_step', 1 );
273 update_option( '_bbp_converter_start', 0 );
274 }
275
276 $step = (int) get_option( '_bbp_converter_step', 1 );
277 $min = (int) get_option( '_bbp_converter_start', 0 );
278 $max = $min + (int) get_option( '_bbp_converter_rows', !empty( $_POST['_bbp_converter_rows'] ) ? (int) $_POST['_bbp_converter_rows'] : 100 ) - 1;
279 $start = $min;
280
281 // Bail if platform did not get saved
282 $platform = !empty( $_POST['_bbp_converter_platform' ] ) ? $_POST['_bbp_converter_platform' ] : get_option( '_bbp_converter_platform' );
283 if ( empty( $platform ) )
284 return;
285
286 // Include the appropriate converter.
287 $converter = bbp_new_converter( $platform );
288
289 switch ( $step ) {
290
291 // STEP 1. Clean all tables.
292 case 1 :
293 if ( !empty( $_POST['_bbp_converter_clean'] ) ) {
294 if ( $converter->clean( $start ) ) {
295 update_option( '_bbp_converter_step', $step + 1 );
296 update_option( '_bbp_converter_start', 0 );
297 $this->sync_table();
298
299 if ( empty( $start ) ) {
300 _e( 'No data to clean', 'bbpress' );
301 }
302 } else {
303 update_option( '_bbp_converter_start', $max + 1 );
304
305 _e( 'Deleting previously converted data (' . $min . ' - ' . $max . ')', 'bbpress' );
306 }
307 } else {
308 update_option( '_bbp_converter_step', $step + 1 );
309 update_option( '_bbp_converter_start', 0 );
310 }
311
312 break;
313
314 // STEP 2. Convert users.
315 case 2 :
316 if ( !empty( $_POST['_bbp_converter_convert_users'] ) ) {
317 if ( $converter->convert_users( $start ) ) {
318 update_option( '_bbp_converter_step', $step + 1 );
319 update_option( '_bbp_converter_start', 0 );
320
321 if ( empty( $start ) ) {
322 _e( 'No users to convert', 'bbpress' );
323 }
324 } else {
325 update_option( '_bbp_converter_start', $max + 1 );
326
327 _e( 'Converting users (' . $min . ' - ' . $max . ')', 'bbpress' );
328 }
329 } else {
330 update_option( '_bbp_converter_step', $step + 1 );
331 update_option( '_bbp_converter_start', 0 );
332 }
333
334 break;
335
336 // STEP 3. Clean passwords.
337 case 3 :
338 if ( !empty( $_POST['_bbp_converter_convert_users'] ) ) {
339 if ( $converter->clean_passwords( $start ) ) {
340 update_option( '_bbp_converter_step', $step + 1 );
341 update_option( '_bbp_converter_start', 0 );
342
343 if ( empty( $start ) ) {
344 _e( 'No passwords to clear', 'bbpress' );
345 }
346 } else {
347 update_option( '_bbp_converter_start', $max + 1 );
348
349 _e( 'Delete users wordpress default passwords (' . $min . ' - ' . $max . ')', 'bbpress' );
350 }
351 } else {
352 update_option( '_bbp_converter_step', $step + 1 );
353 update_option( '_bbp_converter_start', 0 );
354 }
355
356 break;
357
358 // STEP 4. Convert forums.
359 case 4 :
360 if ( $converter->convert_forums( $start ) ) {
361 update_option( '_bbp_converter_step', $step + 1 );
362 update_option( '_bbp_converter_start', 0 );
363
364 if ( empty( $start ) ) {
365 _e( 'No forums to convert', 'bbpress' );
366 }
367 } else {
368 update_option( '_bbp_converter_start', $max + 1 );
369
370 _e( 'Converting forums (' . $min . ' - ' . $max . ')', 'bbpress' );
371 }
372
373 break;
374
375 // STEP 5. Convert forum parents.
376 case 5 :
377
378 if ( $converter->convert_forum_parents( $start ) ) {
379 update_option( '_bbp_converter_step', $step + 1 );
380 update_option( '_bbp_converter_start', 0 );
381
382 if ( empty( $start ) ) {
383 _e( 'No forum parents to convert', 'bbpress' );
384 }
385 } else {
386 update_option( '_bbp_converter_start', $max + 1 );
387
388 _e( 'Converting forum parents (' . $min . ' - ' . $max . ')', 'bbpress' );
389 }
390
391 break;
392
393 // STEP 6. Convert topics.
394 case 6 :
395
396 if ( $converter->convert_topics( $start ) ) {
397 update_option( '_bbp_converter_step', $step + 1 );
398 update_option( '_bbp_converter_start', 0 );
399
400 if ( !$start ) {
401 _e( 'No topics to convert', 'bbpress' );
402 }
403 } else {
404 update_option( '_bbp_converter_start', $max + 1 );
405
406 _e( 'Converting topics (' . $min . ' - ' . $max . ')', 'bbpress' );
407 }
408
409 break;
410
411 // STEP 7. Convert tags.
412 case 7 :
413
414 if ( $converter->convert_tags( $start ) ) {
415 update_option( '_bbp_converter_step', $step + 1 );
416 update_option( '_bbp_converter_start', 0 );
417
418 if ( empty( $start ) ) {
419 _e( 'No tags to convert', 'bbpress' );
420 }
421 } else {
422 update_option( '_bbp_converter_start', $max + 1 );
423
424 _e( 'Converting tags (' . $min . ' - ' . $max . ')', 'bbpress' );
425 }
426
427 break;
428
429 // STEP 8. Convert replies.
430 case 8 :
431 if ( $converter->convert_replies( $start ) ) {
432 update_option( '_bbp_converter_step', $step + 1 );
433 update_option( '_bbp_converter_start', 0 );
434 if ( empty( $start ) ) {
435 _e( 'No replies to convert', 'bbpress' );
436 }
437 } else {
438 update_option( '_bbp_converter_start', $max + 1 );
439
440 _e( 'Converting replies (' . $min . ' - ' . $max . ')', 'bbpress' );
441 }
442
443 break;
444
445 default :
446 delete_option( '_bbp_converter_step' );
447 delete_option( '_bbp_converter_start' );
448
449 _e( 'Conversion Complete', 'bbpress' );
450
451 break;
452
453 }
454 }
455
456 /**
457 * Convert passwords from previous forum to wordpress.
458 *
459 * @since bbPress (r3813)
460 * @global WPDB $wpdb
461 */
462 public function convert_pass() {
463
464 $username = !empty( $_POST['log'] ) ? $_POST['log'] : '';
465
466 if ( !empty( $username ) ) {
467
468 global $wpdb;
469
470 $row = $wpdb->get_row( "SELECT * FROM {$wpdb->users} INNER JOIN {$wpdb->usermeta} ON user_id = ID WHERE meta_key = '_bbp_converter_class' AND user_login = '{$username}' LIMIT 1" );
471
472 if ( !empty( $row ) ) {
473 $converter = bbp_new_converter( $row->meta_value );
474 $converter->callback_pass( $username, $_POST['pwd'] );
475 }
476 }
477 }
478
479 /**
480 * Create Tables for fast syncing
481 *
482 * @since bbPress (r3813)
483 */
484 public function sync_table( $drop = false ) {
485 global $wpdb;
486
487 $table_name = $wpdb->prefix . 'bbp_converter_translator';
488 if ( $wpdb->get_var( "SHOW TABLES LIKE '{$table_name}'" ) == $table_name ) {
489 $wpdb->query( "DROP TABLE {$table_name}" );
490 }
491
492 if ( empty( $drop ) ) {
493 require_once( ABSPATH . '/wp-admin/includes/upgrade.php' );
494
495 if ( !empty( $wpdb->charset ) ) {
496 $charset_collate = "DEFAULT CHARACTER SET $wpdb->charset";
497 }
498
499 if ( !empty( $wpdb->collate ) ) {
500 $charset_collate .= " COLLATE $wpdb->collate";
501 }
502
503 /** Translator ****************************************************/
504
505 $sql = "CREATE TABLE {$table_name} (
506 meta_id mediumint(8) unsigned not null auto_increment,
507 value_type varchar(25) null,
508 value_id bigint(20) unsigned not null default '0',
509 meta_key varchar(25) null,
510 meta_value varchar(25) null,
511 PRIMARY KEY (meta_id),
512 KEY value_id (value_id),
513 KEY meta_join (meta_key, meta_value) ) {$charset_collate};";
514
515 dbDelta( $sql );
516 }
517 }
518 }
519
520 /**
521 * Base class to be extended by specific individual importers
522 *
523 * @since bbPress (r3813)
524 */
525 abstract class BBP_Converter_Base {
526
527 /**
528 * @var array() This is the field mapping array to process.
529 */
530 protected $field_map = array();
531
532 /**
533 * @var object This is the connection to the wordpress datbase.
534 */
535 protected $wpdb;
536
537 /**
538 * @var object This is the connection to the other platforms database.
539 */
540 protected $opdb;
541
542 /**
543 * @var int This is the max rows to process at a time.
544 */
545 public $max_rows;
546
547 /**
548 * @var array() Map of topic to forum. It is for optimization.
549 */
550 private $map_topicid_to_forumid = array();
551
552 /**
553 * @var array() Map of from old forum ids to new forum ids. It is for optimization.
554 */
555 private $map_forumid = array();
556
557 /**
558 * @var array() Map of from old topic ids to new topic ids. It is for optimization.
559 */
560 private $map_topicid = array();
561
562 /**
563 * @var array() Map of from old user ids to new user ids. It is for optimization.
564 */
565 private $map_userid = array();
566
567 /**
568 * @var str This is the charset for your wp database.
569 */
570 public $charset;
571
572 /**
573 * @var boolean Sync table available.
574 */
575 public $sync_table = false;
576
577 /**
578 * @var str Sync table name.
579 */
580 public $sync_table_name;
581
582 /** Methods ***************************************************************/
583
584 /**
585 * This is the constructor and it connects to the platform databases.
586 */
587 public function __construct() {
588 $this->setup_globals();
589 }
590
591 private function setup_globals() {
592 global $wpdb;
593
594 /** Get database connections ******************************************/
595
596 $this->wpdb = $wpdb;
597 $this->max_rows = $_POST['_bbp_converter_rows'];
598 $this->opdb = new wpdb( $_POST['_bbp_converter_db_user'], $_POST['_bbp_converter_db_pass'], $_POST['_bbp_converter_db_name'], $_POST['_bbp_converter_db_server'] );
599 $this->opdb->prefix = $_POST['_bbp_converter_db_prefix'];
600
601 /**
602 * Error Reporting
603 */
604 $this->wpdb->show_errors();
605 $this->opdb->show_errors();
606
607 /**
608 * Syncing
609 */
610 $this->sync_table_name = $this->wpdb->prefix . 'bbp_converter_translator';
611 if ( $this->wpdb->get_var( "SHOW TABLES LIKE '" . $this->sync_table_name . "'" ) == $this->sync_table_name ) {
612 $this->sync_table = true;
613 } else {
614 $this->sync_table = false;
615 }
616
617 /**
618 * Charset
619 */
620 if ( empty( $this->wpdb->charset ) ) {
621 $this->charset = "UTF8";
622 } else {
623 $this->charset = $this->wpdb->charset;
624 }
625
626 /**
627 * Default mapping.
628 */
629
630 /** Forum Section *****************************************************/
631
632 $this->field_map[] = array(
633 'to_type' => 'forum',
634 'to_fieldname' => 'post_status',
635 'default' => 'publish'
636 );
637 $this->field_map[] = array(
638 'to_type' => 'forum',
639 'to_fieldname' => 'comment_status',
640 'default' => 'closed'
641 );
642 $this->field_map[] = array(
643 'to_type' => 'forum',
644 'to_fieldname' => 'ping_status',
645 'default' => 'closed'
646 );
647 $this->field_map[] = array(
648 'to_type' => 'forum',
649 'to_fieldname' => 'post_type',
650 'default' => 'forum'
651 );
652
653 /** Topic Section *****************************************************/
654
655 $this->field_map[] = array(
656 'to_type' => 'topic',
657 'to_fieldname' => 'post_status',
658 'default' => 'publish'
659 );
660 $this->field_map[] = array(
661 'to_type' => 'topic',
662 'to_fieldname' => 'comment_status',
663 'default' => 'closed'
664 );
665 $this->field_map[] = array(
666 'to_type' => 'topic',
667 'to_fieldname' => 'ping_status',
668 'default' => 'closed'
669 );
670 $this->field_map[] = array(
671 'to_type' => 'topic',
672 'to_fieldname' => 'post_type',
673 'default' => 'topic'
674 );
675
676 /** Post Section ******************************************************/
677
678 $this->field_map[] = array(
679 'to_type' => 'reply',
680 'to_fieldname' => 'post_status',
681 'default' => 'publish'
682 );
683 $this->field_map[] = array(
684 'to_type' => 'reply',
685 'to_fieldname' => 'comment_status',
686 'default' => 'closed'
687 );
688 $this->field_map[] = array(
689 'to_type' => 'reply',
690 'to_fieldname' => 'ping_status',
691 'default' => 'closed'
692 );
693 $this->field_map[] = array(
694 'to_type' => 'reply',
695 'to_fieldname' => 'post_type',
696 'default' => 'reply'
697 );
698
699 /** User Section ******************************************************/
700
701 $default_role = ( is_multisite() && get_option( '_bbp_allow_global_access' ) ) ? bbp_get_participant_role() : get_option( 'default_role' );
702 $this->field_map[] = array(
703 'to_type' => 'user',
704 'to_fieldname' => 'role',
705 'default' => $default_role
706 );
707 }
708
709 /**
710 * Convert Forums
711 */
712 public function convert_forums( $start = 1 ) {
713 return $this->convert_table( 'forum', $start );
714 }
715
716 /**
717 * Convert Topics / Threads
718 */
719 public function convert_topics( $start = 1 ) {
720 return $this->convert_table( 'topic', $start );
721 }
722
723 /**
724 * Convert Posts
725 */
726 public function convert_replies( $start = 1 ) {
727 return $this->convert_table( 'reply', $start );
728 }
729
730 /**
731 * Convert Users
732 */
733 public function convert_users( $start = 1 ) {
734 return $this->convert_table( 'user', $start );
735 }
736
737 /**
738 * Convert Tags
739 */
740 public function convert_tags( $start = 1 ) {
741 return $this->convert_table( 'tags', $start );
742 }
743
744 /**
745 * Convert Table
746 *
747 * @param string to type
748 * @param int Start row
749 */
750 public function convert_table( $to_type, $start ) {
751
752 // Are we usig a sync table, or postmeta?
753 if ( $this->wpdb->get_var( "SHOW TABLES LIKE '" . $this->sync_table_name . "'" ) == $this->sync_table_name ) {
754 $this->sync_table = true;
755 } else {
756 $this->sync_table = false;
757 }
758
759 // Set some defaults
760 $has_insert = false;
761 $from_tablename = '';
762 $field_list = $from_tables = $tablefield_array = array();
763
764 // Toggle Table Name based on $to_type (destination)
765 switch ( $to_type ) {
766 case 'user' :
767 $tablename = $this->wpdb->users;
768 break;
769
770 case 'tags' :
771 $tablename = '';
772 break;
773
774 default :
775 $tablename = $this->wpdb->posts;
776 }
777
778 // Get the fields from the destination table
779 if ( !empty( $tablename ) ) {
780 $tablefield_array = $this->get_fields( $tablename );
781 }
782
783 /** Step 1 ************************************************************/
784
785 // Loop through the field maps, and look for to_type matches
786 foreach ( $this->field_map as $item ) {
787
788 // Yay a match, and we have a from table, too
789 if ( ( $item['to_type'] == $to_type ) && !empty( $item['from_tablename'] ) ) {
790
791 // $from_tablename was set from a previous loop iteration
792 if ( ! empty( $from_tablename ) ) {
793
794 // Doing some joining
795 if ( !in_array( $item['from_tablename'], $from_tables ) && in_array( $item['join_tablename'], $from_tables ) ) {
796 $from_tablename .= ' ' . $item['join_type'] . ' JOIN ' . $this->opdb->prefix . $item['from_tablename'] . ' AS ' . $item['from_tablename'] . ' ' . $item['join_expression'];
797 }
798
799 // $from_tablename needs to be set
800 } else {
801 $from_tablename = $item['from_tablename'] . ' AS ' . $item['from_tablename'];
802 }
803
804 // Specific FROM expression data used
805 if ( !empty( $item['from_expression'] ) ) {
806
807 // No 'WHERE' in expression
808 if ( stripos( $from_tablename, "WHERE" ) === false ) {
809 $from_tablename .= ' ' . $item['from_expression'];
810
811 // 'WHERE' in expression, so replace with 'AND'
812 } else {
813 $from_tablename .= ' ' . str_replace( "WHERE", "AND", $item['from_expression'] );
814 }
815 }
816
817 // Add tablename and fieldname to arrays, formatted for querying
818 $from_tables[] = $item['from_tablename'];
819 $field_list[] = 'convert(' . $item['from_tablename'] . '.' . $item['from_fieldname'] . ' USING "' . $this->charset . '") AS ' . $item['from_fieldname'];
820 }
821 }
822
823 /** Step 2 ************************************************************/
824
825 // We have a $from_tablename, so we want to get some data to convert
826 if ( !empty( $from_tablename ) ) {
827
828 // Get some data from the old forums
829 $forum_array = $this->opdb->get_results( 'SELECT ' . implode( ',', $field_list ) . ' FROM ' . $this->opdb->prefix . $from_tablename . ' LIMIT ' . $start . ', ' . $this->max_rows, ARRAY_A );
830
831 // Query returned some results
832 if ( !empty( $forum_array ) ) {
833
834 // Loop through results
835 foreach ( (array) $forum_array as $forum ) {
836
837 // Reset some defaults
838 $insert_post = $insert_postmeta = $insert_data = array();
839
840 // Loop through field map, again...
841 foreach ( $this->field_map as $row ) {
842
843 // Types matchand to_fieldname is present. This means
844 // we have some work to do here.
845 if ( ( $row['to_type'] == $to_type ) && ! is_null( $row['to_fieldname'] ) ) {
846
847 // This row has a destination that matches one of the
848 // columns in this table.
849 if ( in_array( $row['to_fieldname'], $tablefield_array ) ) {
850
851 // Allows us to set default fields.
852 if ( isset( $row['default'] ) ) {
853 $insert_post[$row['to_fieldname']] = $row['default'];
854
855 // Translates a field from the old forum.
856 } elseif ( isset( $row['callback_method'] ) ) {
857 if ( ( 'callback_userid' == $row['callback_method'] ) && empty( $_POST['_bbp_converter_convert_users'] ) ) {
858 $insert_post[$row['to_fieldname']] = $forum[$row['from_fieldname']];
859 } else {
860 $insert_post[$row['to_fieldname']] = call_user_func_array( array( $this, $row['callback_method'] ), array( $forum[$row['from_fieldname']], $forum ) );
861 }
862
863 // Maps the field from the old forum.
864 } else {
865 $insert_post[$row['to_fieldname']] = $forum[$row['from_fieldname']];
866 }
867
868 // Destination field is not empty, so we might need
869 // to do some extra work or set a default.
870 } elseif ( !empty( $row['to_fieldname'] ) ) {
871
872 // Allows us to set default fields.
873 if ( isset( $row['default'] ) ) {
874 $insert_postmeta[$row['to_fieldname']] = $row['default'];
875
876 // Translates a field from the old forum.
877 } elseif ( isset( $row['callback_method'] ) ) {
878 if ( ( $row['callback_method'] == 'callback_userid' ) && ( 0 == $_POST['_bbp_converter_convert_users'] ) ) {
879 $insert_postmeta[$row['to_fieldname']] = $forum[$row['from_fieldname']];
880 } else {
881 $insert_postmeta[$row['to_fieldname']] = call_user_func_array( array( $this, $row['callback_method'] ), array( $forum[$row['from_fieldname']], $forum ) );
882 }
883
884 // Maps the field from the old forum.
885 } else {
886 $insert_postmeta[$row['to_fieldname']] = $forum[$row['from_fieldname']];
887 }
888 }
889 }
890 }
891
892 /** Step 3 ************************************************/
893
894 // Something to insert into the destination field
895 if ( count( $insert_post ) > 0 || ( $to_type == 'tags' && count( $insert_postmeta ) > 0 ) ) {
896
897 switch ( $to_type ) {
898
899 /** New user **************************************/
900
901 case 'user':
902 if ( username_exists( $insert_post['user_login'] ) ) {
903 $insert_post['user_login'] = 'imported_' . $insert_post['user_login'];
904 }
905
906 if ( email_exists( $insert_post['user_email'] ) ) {
907 $insert_post['user_email'] = 'imported_' . $insert_post['user_email'];
908 }
909
910 $post_id = wp_insert_user( $insert_post );
911
912 if ( is_numeric( $post_id ) ) {
913
914 foreach ( $insert_postmeta as $key => $value ) {
915
916 add_user_meta( $post_id, $key, $value, true );
917
918 if ( '_id' == substr( $key, -3 ) && ( true === $this->sync_table ) ) {
919 $this->wpdb->insert( $this->sync_table_name, array( 'value_type' => 'user', 'value_id' => $post_id, 'meta_key' => $key, 'meta_value' => $value ) );
920 }
921 }
922 }
923 break;
924
925 /** New Topic-Tag *********************************/
926
927 case 'tags':
928 $post_id = wp_set_object_terms( $insert_postmeta['objectid'], $insert_postmeta['name'], 'topic-tag', true );
929 break;
930
931 /** Forum, Topic, Reply ***************************/
932
933 default:
934 $post_id = wp_insert_post( $insert_post );
935
936 if ( is_numeric( $post_id ) ) {
937
938 foreach ( $insert_postmeta as $key => $value ) {
939
940 add_post_meta( $post_id, $key, $value, true );
941
942 // Topics need an extra bit of metadata
943 // to be keyed to the new post_id
944 if ( ( 'topic' == $to_type ) && ( '_bbp_topic_id' == $key ) ) {
945
946 // Update the live topic ID
947 update_post_meta( $post_id, $key, $post_id );
948
949 // Save the old topic ID
950 add_post_meta( $post_id, '_bbp_old_topic_id', $value );
951 if ( '_id' == substr( $key, -3 ) && ( true === $this->sync_table ) ) {
952 $this->wpdb->insert( $this->sync_table_name, array( 'value_type' => 'post', 'value_id' => $post_id, 'meta_key' => '_bbp_topic_id', 'meta_value' => $post_id ) );
953 $this->wpdb->insert( $this->sync_table_name, array( 'value_type' => 'post', 'value_id' => $post_id, 'meta_key' => '_bbp_old_topic_id', 'meta_value' => $value ) );
954 }
955
956 } elseif ( '_id' == substr( $key, -3 ) && ( true === $this->sync_table ) ) {
957 $this->wpdb->insert( $this->sync_table_name, array( 'value_type' => 'post', 'value_id' => $post_id, 'meta_key' => $key, 'meta_value' => $value ) );
958 }
959 }
960 }
961 break;
962 }
963 $has_insert = true;
964 }
965 }
966 }
967 }
968
969 return ! $has_insert;
970 }
971
972 public function convert_forum_parents( $start ) {
973 $has_update = false;
974
975 if ( !empty( $this->sync_table ) ) {
976 $forum_array = $this->wpdb->get_results( 'SELECT value_id, meta_value FROM ' . $this->sync_table_name . ' WHERE meta_key = "_bbp_forum_parent_id" AND meta_value > 0 LIMIT ' . $start . ', ' . $this->max_rows );
977 } else {
978 $forum_array = $this->wpdb->get_results( 'SELECT post_id AS value_id, meta_value FROM ' . $this->wpdb->postmeta . ' WHERE meta_key = "_bbp_forum_parent_id" AND meta_value > 0 LIMIT ' . $start . ', ' . $this->max_rows );
979 }
980 foreach ( (array) $forum_array as $row ) {
981 $parent_id = $this->callback_forumid( $row->meta_value );
982 $this->wpdb->query( 'UPDATE ' . $this->wpdb->posts . ' SET post_parent = "' . $parent_id . '" WHERE ID = "' . $row->value_id . '" LIMIT 1' );
983 $has_update = true;
984 }
985
986 return ! $has_update;
987 }
988
989 /**
990 * This method deletes data from the wp database.
991 */
992 public function clean( $start ) {
993 $start = 0;
994 $has_delete = false;
995
996 /** Delete bbconverter topics/forums/posts ****************************/
997
998 if ( true === $this->sync_table ) {
999 $bbconverter = $this->wpdb->get_results( '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 = "post" GROUP BY value_id ORDER BY value_id DESC LIMIT ' . $this->max_rows, ARRAY_A );
1000 } else {
1001 $bbconverter = $this->wpdb->get_results( '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, ARRAY_A );
1002 }
1003
1004 if ( !empty( $bbconverter ) ) {
1005 foreach ( (array) $bbconverter as $value ) {
1006 wp_delete_post( $value['value_id'], true );
1007 }
1008 $has_delete = true;
1009 }
1010
1011 /** Delete bbconverter users ******************************************/
1012
1013 if ( true === $this->sync_table ) {
1014 $bbconverter = $this->wpdb->get_results( 'SELECT value_id FROM ' . $this->sync_table_name . ' INNER JOIN ' . $this->wpdb->users . ' ON(value_id = ID) WHERE meta_key = "_bbp_user_id" AND value_type = "user" LIMIT ' . $this->max_rows, ARRAY_A );
1015 } else {
1016 $bbconverter = $this->wpdb->get_results( 'SELECT user_id AS value_id FROM ' . $this->wpdb->usermeta . ' WHERE meta_key = "_bbp_user_id" LIMIT ' . $this->max_rows, ARRAY_A );
1017 }
1018
1019 if ( !empty( $bbconverter ) ) {
1020 foreach ( $bbconverter as $value ) {
1021 wp_delete_user( $value['value_id'] );
1022 }
1023 $has_delete = true;
1024 }
1025
1026 return ! $has_delete;
1027 }
1028
1029 /**
1030 * This method deletes passwords from the wp database.
1031 *
1032 * @param int Start row
1033 */
1034 public function clean_passwords( $start ) {
1035 $has_delete = false;
1036
1037 /** Delete bbconverter passwords **************************************/
1038
1039 $bbconverter = $this->wpdb->get_results( 'SELECT user_id, meta_value FROM ' . $this->wpdb->usermeta . ' WHERE meta_key = "_bbp_password" LIMIT ' . $start . ', ' . $this->max_rows, ARRAY_A );
1040 if ( !empty( $bbconverter ) ) {
1041
1042 foreach ( $bbconverter as $value ) {
1043 if ( is_serialized( $value['meta_value'] ) ) {
1044 $this->wpdb->query( 'UPDATE ' . $this->wpdb->users . ' ' . 'SET user_pass = "" ' . 'WHERE ID = "' . $value['user_id'] . '"' );
1045 } else {
1046 $this->wpdb->query( 'UPDATE ' . $this->wpdb->users . ' ' . 'SET user_pass = "' . $value['meta_value'] . '" ' . 'WHERE ID = "' . $value['user_id'] . '"' );
1047 $this->wpdb->query( 'DELETE FROM ' . $this->wpdb->usermeta . ' WHERE meta_key = "_bbp_password" AND user_id = "' . $value['user_id'] . '"' );
1048 }
1049 }
1050 $has_delete = true;
1051 }
1052 return ! $has_delete;
1053 }
1054
1055 /**
1056 * This method implements the authentication for the different forums.
1057 *
1058 * @param string Unencoded password.
1059 */
1060 abstract protected function authenticate_pass( $password, $hash );
1061
1062 /**
1063 * Info
1064 */
1065 abstract protected function info();
1066
1067 /**
1068 * This method grabs appropriate fields from the table specified
1069 *
1070 * @param string The table name to grab fields from
1071 */
1072 private function get_fields( $tablename ) {
1073 $rval = array();
1074 $field_array = $this->wpdb->get_results( 'DESCRIBE ' . $tablename, ARRAY_A );
1075
1076 foreach ( $field_array as $field ) {
1077 $rval[] = $field['Field'];
1078 }
1079
1080 if ( $tablename == $this->wpdb->users ) {
1081 $rval[] = 'role';
1082 $rval[] = 'yim';
1083 $rval[] = 'aim';
1084 $rval[] = 'jabber';
1085 }
1086 return $rval;
1087 }
1088
1089 /** Callbacks *************************************************************/
1090
1091 /**
1092 * Run password through wp_hash_password()
1093 *
1094 * @param string $username
1095 * @param string $password
1096 */
1097 public function callback_pass( $username, $password ) {
1098 $user = $this->wpdb->get_row( 'SELECT * FROM ' . $this->wpdb->users . ' WHERE user_login = "' . $username . '" AND user_pass = "" LIMIT 1' );
1099 if ( !empty( $user ) ) {
1100 $usermeta = $this->wpdb->get_row( 'SELECT * FROM ' . $this->wpdb->usermeta . ' WHERE meta_key = "_bbp_password" AND user_id = "' . $user->ID . '" LIMIT 1' );
1101
1102 if ( !empty( $usermeta ) ) {
1103 if ( $this->authenticate_pass( $password, $usermeta->meta_value ) ) {
1104 $this->wpdb->query( 'UPDATE ' . $this->wpdb->users . ' ' . 'SET user_pass = "' . wp_hash_password( $password ) . '" ' . 'WHERE ID = "' . $user->ID . '"' );
1105 $this->wpdb->query( 'DELETE FROM ' . $this->wpdb->usermeta . ' WHERE meta_key = "_bbp_password" AND user_id = "' . $user->ID . '"' );
1106 }
1107 }
1108 }
1109 }
1110
1111 /**
1112 * A mini cache system to reduce database calls to forum ID's
1113 *
1114 * @param string $field
1115 * @return string
1116 */
1117 private function callback_forumid( $field ) {
1118 if ( !isset( $this->map_forumid[$field] ) ) {
1119 if ( !empty( $this->sync_table ) ) {
1120 $row = $this->wpdb->get_row( 'SELECT value_id, meta_value FROM ' . $this->sync_table_name . ' WHERE meta_key = "_bbp_forum_id" AND meta_value = "' . $field . '" LIMIT 1' );
1121 } else {
1122 $row = $this->wpdb->get_row( 'SELECT post_id AS value_id FROM ' . $this->wpdb->postmeta . ' WHERE meta_key = "_bbp_forum_id" AND meta_value = "' . $field . '" LIMIT 1' );
1123 }
1124
1125 if ( !is_null( $row ) ) {
1126 $this->map_forumid[$field] = $row->value_id;
1127 } else {
1128 $this->map_forumid[$field] = 0;
1129 }
1130 }
1131 return $this->map_forumid[$field];
1132 }
1133
1134 /**
1135 * A mini cache system to reduce database calls to topic ID's
1136 *
1137 * @param string $field
1138 * @return string
1139 */
1140 private function callback_topicid( $field ) {
1141 if ( !isset( $this->map_topicid[$field] ) ) {
1142 if ( !empty( $this->sync_table ) ) {
1143 $row = $this->wpdb->get_row( 'SELECT value_id, meta_value FROM ' . $this->sync_table_name . ' WHERE meta_key = "_bbp_old_topic_id" AND meta_value = "' . $field . '" LIMIT 1' );
1144 } else {
1145 $row = $this->wpdb->get_row( 'SELECT post_id AS value_id FROM ' . $this->wpdb->postmeta . ' WHERE meta_key = "_bbp_old_topic_id" AND meta_value = "' . $field . '" LIMIT 1' );
1146 }
1147
1148 if ( !is_null( $row ) ) {
1149 $this->map_topicid[$field] = $row->value_id;
1150 } else {
1151 $this->map_topicid[$field] = 0;
1152 }
1153 }
1154 return $this->map_topicid[$field];
1155 }
1156
1157 /**
1158 * A mini cache system to reduce database calls to user ID's
1159 *
1160 * @param string $field
1161 * @return string
1162 */
1163 private function callback_userid( $field ) {
1164 if ( !isset( $this->map_userid[$field] ) ) {
1165 if ( !empty( $this->sync_table ) ) {
1166 $row = $this->wpdb->get_row( 'SELECT value_id, meta_value FROM ' . $this->sync_table_name . ' WHERE meta_key = "_bbp_user_id" AND meta_value = "' . $field . '" LIMIT 1' );
1167 } else {
1168 $row = $this->wpdb->get_row( 'SELECT user_id AS value_id FROM ' . $this->wpdb->usermeta . ' WHERE meta_key = "_bbp_user_id" AND meta_value = "' . $field . '" LIMIT 1' );
1169 }
1170
1171 if ( !is_null( $row ) ) {
1172 $this->map_userid[$field] = $row->value_id;
1173 } else {
1174 if ( !empty( $_POST['_bbp_converter_convert_users'] ) && ( $_POST['_bbp_converter_convert_users'] == 1 ) ) {
1175 $this->map_userid[$field] = 0;
1176 } else {
1177 $this->map_userid[$field] = $field;
1178 }
1179 }
1180 }
1181 return $this->map_userid[$field];
1182 }
1183
1184 /**
1185 * A mini cache system to reduce database calls map topics ID's to forum ID's
1186 *
1187 * @param string $field
1188 * @return string
1189 */
1190 private function callback_topicid_to_forumid( $field ) {
1191 $topicid = $this->callback_topicid( $field );
1192 if ( empty( $topicid ) ) {
1193 $this->map_topicid_to_forumid[$topicid] = 0;
1194 } elseif ( ! isset( $this->map_topicid_to_forumid[$topicid] ) ) {
1195 $row = $this->wpdb->get_row( 'SELECT post_parent FROM ' . $this->wpdb->posts . ' WHERE ID = "' . $topicid . '" LIMIT 1' );
1196
1197 if ( !is_null( $row ) ) {
1198 $this->map_topicid_to_forumid[$topicid] = $row->post_parent;
1199 } else {
1200 $this->map_topicid_to_forumid[$topicid] = 0;
1201 }
1202 }
1203
1204 return $this->map_topicid_to_forumid[$topicid];
1205 }
1206
1207 protected function callback_slug( $field ) {
1208 return sanitize_title_with_dashes( $field );
1209 }
1210
1211 protected function callback_negative( $field ) {
1212 if ( $field < 0 ) {
1213 return 0;
1214 } else {
1215 return $field;
1216 }
1217 }
1218
1219 protected function callback_html( $field ) {
1220 require_once( bbpress()->admin->admin_dir . 'bbp-parser.php' );
1221 $bbcode = BBCode::getInstance();
1222 return html_entity_decode( $bbcode->Parse( $field ) );
1223 }
1224
1225 protected function callback_null( $field ) {
1226 if ( is_null( $field ) ) {
1227 return '';
1228 } else {
1229 return $field;
1230 }
1231 }
1232
1233 protected function callback_datetime( $field ) {
1234 if ( is_numeric( $field ) ) {
1235 return date( 'Y-m-d H:i:s', $field );
1236 } else {
1237 return date( 'Y-m-d H:i:s', strtotime( $field ) );
1238 }
1239 }
1240 }
1241
1242 /**
1243 * This is a function that is purposely written to look like a "new" statement.
1244 * It is basically a dynamic loader that will load in the platform conversion
1245 * of your choice.
1246 *
1247 * @param string $platform Name of valid platform class.
1248 */
1249 function bbp_new_converter( $platform ) {
1250 $found = false;
1251
1252 if ( $curdir = opendir( bbpress()->admin->admin_dir . 'converters/' ) ) {
1253 while ( $file = readdir( $curdir ) ) {
1254 if ( stristr( $file, '.php' ) && stristr( $file, 'index' ) === FALSE ) {
1255 $file = preg_replace( '/.php/', '', $file );
1256 if ( $platform == $file ) {
1257 $found = true;
1258 continue;
1259 }
1260 }
1261 }
1262 closedir( $curdir );
1263 }
1264
1265 if ( true === $found ) {
1266 require_once( bbpress()->admin->admin_dir . 'converters/' . $platform . '.php' );
1267 eval( '$obj = new ' . $platform . '();' );
1268 return $obj;
1269 } else {
1270 return null;
1271 }
1272 }
1273