Skip to:
Content

bbPress.org

Ticket #2440: converter-vb5.php

File converter-vb5.php, 45.2 KB (added by netweb, 11 years ago)

Fix copy pasta error

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