existing_plugins = $this->knowledge_base_plugins(); $this->migrated_plugins = $this->get_migrated_plugins(); add_filter( 'betterdocs_settings_tabs', [ $this, 'migration_settings' ], 10, 1 ); if ( ! $this->existing_plugins || ( $this->existing_plugins && in_array( $this->existing_plugins[0][0], $this->migrated_plugins )) ) { return; } $this->active = 'kb-migration'; add_filter( 'admin_notices', [ $this, 'migration_notice' ], 10, 1 ); add_filter( 'betterdocs_migration_tab_sections', [ $this, 'kb_migration_settings' ], 10, 1 ); } public function migration_notice() { $screen = get_current_screen()->id; if ( $screen === 'betterdocs_page_betterdocs-setup' ) { return; } ?>
%s%s

', __( sprintf( 'Whoops! You are already using %s on your website. To migrate your %s data to BetterDocs, click here ', ''. esc_html($this->existing_plugins[0][1]) .'', ''. esc_html($this->existing_plugins[0][1]) .'' ), 'betterdocs' ), esc_url(admin_url('admin.php?page=betterdocs-settings&tab=tab-migration')), esc_html__('Start Migration', 'betterdocs') ); ?>
'tab-migration', 'name' => 'tab-migration', 'classes' => 'tab-migration', 'label' => __( 'Migration', 'betterdocs' ), 'priority' => 80, 'fields' => [ 'sections-migration' => [ 'name' => 'sections-migration', 'type' => 'section', 'label' => __( 'Migration', 'betterdocs' ), 'priority' => 30, 'fields' => [ 'all-migration' => [ 'id' => 'all-tab-migration', 'name' => 'all-tab-migration', 'label' => __( 'Migration Settings', 'betterdocs' ), 'classes' => 'tab-layout', 'type' => "tab", 'active' => $this->active, 'completionTrack' => true, 'sidebar' => false, 'save' => false, 'title' => false, 'config' => [ 'active' => $this->active, 'sidebar' => false, 'title' => false ], 'submit' => [ 'show' => false ], 'step' => [ 'show' => false ], 'priority' => 20, 'fields' => apply_filters( 'betterdocs_migration_tab_sections', [ 'helpscout' => [ 'id' => 'helpscout', 'name' => 'helpscout', 'type' => 'section', 'label' => __( 'Help Scout', 'betterdocs' ), 'priority' => 2, 'fields' => [ 'helpscout_api_key' => [ 'name' => 'helpscout_api_key', 'type' => 'text', 'label' => __('Docs API Key', 'betterdocs'), 'label_subtitle' => __('Check out this documentation to retrieve your Help Scout Docs API Key', 'betterdocs'), 'default' => '', 'priority' => 1, ], 'helpscout_collection_id' => [ 'name' => 'helpscout_collection_id', 'type' => 'text', 'label' => __('Collection ID', 'betterdocs'), 'label_subtitle' => __('Check out this documentation to retrieve your Help Scout Collection ID', 'betterdocs'), 'default' => '', 'priority' => 2, ], 'helpscout_action' => [ 'name' => 'helpscout_action', 'text' => [ 'normal' => __('Migrate Help Scout Docs', 'betterdocs'), 'saved' => __('Migrated', 'betterdocs'), 'loading' => __('Migrating...', 'betterdocs'), ], 'type' => 'button', 'priority' => 3, 'ajax' => [ 'on' => 'click', 'api' => '/betterdocs/v1/helpscout-migration', 'data' => [ 'helpscout_api_key' => '@helpscout_api_key', 'helpscout_collection_id' => '@helpscout_collection_id' ], 'swal' => [ 'text' => __( 'Help Scout Docs are successfully migrated to your site.', 'betterdocs' ), 'icon' => 'success', 'autoClose' => 2000 ] ] ] ] ] ]) ] ] ] ] ] ); return $args; } public function kb_migration_settings( $args ) { /** * License Tab */ $args['kb-migration'] = [ 'id' => 'kb-migration', 'name' => 'kb-migration', 'type' => 'section', 'label' => $this->existing_plugins[0][1], 'priority' => 1, 'fields' => [ 'kb-migration-section' => [ 'name' => 'kb-migration-section', 'classes' => 'kb-migration-section', 'type' => 'section', 'priority' => 0, 'save' => false, 'fields' => apply_filters( 'betterdocs_migration_fields', [ 'migration_header' => [ 'name' => 'migration_header', 'type' => 'header', 'title' => __( 'Migration', 'betterdocs' ), 'direction' => 'column', 'description' => wp_sprintf( __( 'We found that there is another Knowledge Base plugin, %s, installed on this website. To migrate your knowledge base to BetterDocs from %s, click the "Start Migration" button and all the documentation will be migrated to BetterDocs.', 'betterdocs' ), $this->existing_plugins[0][1], $this->existing_plugins[0][1] ), 'icon' => '', 'priority' => 1, ], 'migration_action' => [ 'name' => 'migration_action', 'type' => 'button', 'text' => [ 'normal' => __('Start Migration', 'betterdocs'), 'saved' => __('Migrated', 'betterdocs'), 'loading' => __('Migrating...', 'betterdocs'), ], 'ajax' => [ 'on' => 'click', 'api' => '/betterdocs/v1/migrate', 'data' => [ 'existing_plugins' => $this->existing_plugins[0][1], ], 'swal' => [ 'text' => __('Migration completed successfully.', 'betterdocs'), 'icon' => 'success', 'autoClose' => 1000 ], 'reload' => admin_url('admin.php?page=betterdocs-settings'), ], 'priority' => 2, ] ]) ] ] ]; return $args; } public function migrate() { $existing_plugins = $this->knowledge_base_plugins(); $existing_plugins_data = $this->existing_plugins_data( $existing_plugins[0][0] ); if ( isset( $existing_plugins_data['name'] ) && isset( $existing_plugins_data['url'] ) ) { if ( $existing_plugins_data['name'] === 'echo-knowledge-base' ) { $this->eco_knowledgebase_migration(); } elseif ( $existing_plugins_data['name'] === 'pressapps-knowledge-base' ) { $this->pressapps_migration(); } elseif ( $existing_plugins_data['name'] === 'wedocs' ) { $this->wedocs_migration(); } $this->update_option( $existing_plugins_data['name'] ); deactivate_plugins( $existing_plugins_data['url'] ); } } public function knowledge_base_plugins() { $plugins = []; if ( Helper::is_plugin_active( 'wedocs/wedocs.php' ) ) { $plugins[] = ['wedocs', 'weDocs']; } if ( Helper::is_plugin_active( 'bsf-docs/bsf-docs.php' ) ) { $plugins[] = ['bsf-docs', 'BSF docs']; } if ( Helper::is_plugin_active( 'documentor-lite/documentor-lite.php' ) ) { $plugins[] = ['documentor-lite', 'Documentor']; } if ( Helper::is_plugin_active( 'echo-knowledge-base/echo-knowledge-base.php' ) ) { $plugins[] = ['echo-knowledge-base', 'Echo Knowledge Base']; } if ( Helper::is_plugin_active( 'pressapps-knowledge-base/pressapps-knowledge-base.php' ) ) { $plugins[] = ['pressapps-knowledge-base', 'PressApps Knowledge Base']; } return $plugins; } public function insert_terms_hierarchically( $existing_term, $new_term, $parentId = 0 ) { $into = []; $cats = get_terms( $existing_term, ['hide_empty' => false] ); if ( $cats ) { foreach ( $cats as $i => $cat ) { if ( $cat->parent == $parentId ) { $into[$cat->term_id] = $cat; unset( $cats[$i] ); $doc_parent_term = term_exists( $cat->name, $new_term ); wp_insert_term( $cat->name, $new_term, [ 'alias_of' => $cat->slug, 'description' => $cat->description, 'slug' => $cat->slug, 'parent' => $cat->parent ] ); } } if ( $cats ) { foreach ( $cats as $i => $cat ) { $get_existing_term = get_term_by( 'id', $cat->parent, $existing_term ); $doc_parent_term = term_exists( $get_existing_term->name, $new_term ); wp_insert_term( $cat->name, $new_term, [ 'alias_of' => $cat->slug, 'description' => $cat->description, 'slug' => $cat->slug, 'parent' => $doc_parent_term['term_id'] ] ); } } } } public function insert_posts( $existing_post, $existing_cat, $existing_tag ) { $args = [ 'post_type' => $existing_post, 'post_status' => 'any', 'posts_per_page' => -1 ]; $postslist = get_posts( $args ); if ( $postslist ) { foreach ( $postslist as $post ) { // Create post object if ( ! get_page_by_title( $post->post_title, 'OBJECT', 'docs' ) ) { $post_args = [ 'post_type' => 'docs', 'post_title' => $post->post_title, 'post_content' => $post->post_content, 'post_status' => $post->post_status, 'post_author' => $post->post_author, 'post_date' => $post->post_date, 'post_date_gmt' => $post->post_date_gmt, 'post_excerpt' => $post->post_excerpt, 'comment_status' => $post->comment_status, 'ping_status' => $post->ping_status, 'post_password' => $post->post_password, 'post_name' => $post->post_name, 'to_ping' => $post->to_ping, 'pinged' => $post->pinged, 'post_modified' => $post->post_modified, 'post_modified_gmt' => $post->post_modified_gmt, 'post_content_filtered' => $post->post_content_filtered, 'post_parent' => $post->post_parent, 'post_mime_type' => $post->post_mime_type, 'comment_count' => $post->comment_count, 'filter' => $post->filter ]; // Insert the post into the database $result = wp_insert_post( $post_args ); if ( $result && ! is_wp_error( $result ) ) { $cat_list = wp_get_post_terms( $post->ID, $existing_cat, ['fields' => 'all'] ); if ( $cat_list ) { $post_id = $result; wp_set_object_terms( $post_id, [$cat_list['0']->name], 'doc_category', false ); } $tag_list = wp_get_post_terms( $post->ID, $existing_tag, ['fields' => 'all'] ); if ( $tag_list ) { $post_id = $result; wp_set_object_terms( $post_id, [$tag_list['0']->name], 'doc_tag', false ); } } } } } } public function existing_plugins_data( $plugins ) { $plugins_data = []; if ( $plugins === 'wedocs' ) { $plugins_data['name'] = 'wedocs'; $plugins_data['url'] = 'wedocs/wedocs.php'; } if ( $plugins === 'bsf-docs' ) { $plugins_data['name'] = 'bsf-docs'; $plugins_data['url'] = 'bsf-docs/bsf-docs.php'; } if ( $plugins === 'documentor-lite' ) { $plugins_data['name'] = 'documentor-lite'; $plugins_data['url'] = 'documentor-lite/documentor-lite.php'; } if ( $plugins === 'echo-knowledge-base' ) { $plugins_data['name'] = 'echo-knowledge-base'; $plugins_data['url'] = 'echo-knowledge-base/echo-knowledge-base.php'; } if ( $plugins === 'pressapps-knowledge-base' ) { $plugins_data['name'] = 'pressapps-knowledge-base'; $plugins_data['url'] = 'pressapps-knowledge-base/pressapps-knowledge-base.php'; } return $plugins_data; } public function eco_knowledgebase_migration() { $this->insert_terms_hierarchically( 'epkb_post_type_1_category', 'doc_category' ); $this->insert_terms_hierarchically( 'epkb_post_type_1_tag', 'doc_tag' ); $this->insert_posts( 'epkb_post_type_1', 'epkb_post_type_1_category', 'epkb_post_type_1_tag' ); } public function pressapps_migration() { $this->insert_terms_hierarchically( 'knowledgebase_category', 'doc_category' ); $this->insert_terms_hierarchically( 'knowledgebase_tags', 'doc_tag' ); $this->insert_posts( 'knowledgebase', 'knowledgebase_category', 'knowledgebase_tags' ); } public function wedocs_migration() { // Step 1: Get posts with no parent (main posts) $args_step1 = array( 'post_type' => 'docs', 'post_status' => 'publish', 'posts_per_page' => -1, 'post_parent' => 0, ); $posts_step1 = get_posts( $args_step1 ); // Multidimensional array to store posts $nested_posts = array(); // First Dimension key: 'multiple_kb' foreach ( $posts_step1 as $post_step1 ) { $nested_posts['multiple_kb'][$post_step1->ID] = array( 'post' => $post_step1, 'doc_category' => array(), // Initialize the second dimension ); // Step 2: 'doc_category' $args_step2 = array( 'post_type' => 'docs', 'post_status' => 'publish', 'posts_per_page' => -1, 'post_parent' => $post_step1->ID, ); $posts_step2 = get_posts($args_step2); foreach ( $posts_step2 as $post_step2 ) { $nested_posts['multiple_kb'][$post_step1->ID]['doc_category'][$post_step2->ID] = array( 'post' => $post_step2, 'docs' => array(), // Initialize the third dimension ); // Step 3: 'docs' $args_step3 = array( 'post_type' => 'docs', // Replace with your actual post type 'post_status' => 'publish', 'posts_per_page' => -1, 'post_parent' => $post_step2->ID, ); $posts_step3 = get_posts($args_step3); foreach ( $posts_step3 as $post_step3 ) { $nested_posts['multiple_kb'][$post_step1->ID]['doc_category'][$post_step2->ID]['docs'][$post_step3->ID] = array( 'post' => $post_step3, ); // Continue with additional dimensions if needed } } } // Now, $nested_posts contains the posts organized in a multidimensional array with the specified key names foreach ( $nested_posts['multiple_kb'] as $multiple_kb_id => $multiple_kb_data ) { // Step 1: Insert posts as terms under 'knowledge_base' $knowledge_base_id = wp_insert_term($multiple_kb_data['post']->post_title, 'knowledge_base'); if ( ! is_wp_error($knowledge_base_id) ) { wp_delete_post($multiple_kb_data['post']->ID, true); $knowledge_base_term = get_term($knowledge_base_id['term_id'], 'knowledge_base'); } foreach ( $multiple_kb_data['doc_category'] as $doc_category_id => $doc_category_data ) { // Step 2: Insert posts as terms under 'doc_category' and set term meta $doc_category_id = wp_insert_term($doc_category_data['post']->post_title, 'doc_category'); if (!is_wp_error($doc_category_id)) { $doc_category_term = get_term($doc_category_id['term_id'], 'doc_category'); wp_delete_post($doc_category_data['post']->ID, true); $doc_category_kb = rest_sanitize_array( array($knowledge_base_term->slug) ); // Set term meta for 'knowledge_base_doc_category' update_term_meta($doc_category_id['term_id'], 'doc_category_knowledge_base', $doc_category_kb); } foreach ( $doc_category_data['docs'] as $docs_id => $docs_data ) { wp_set_post_terms($docs_data['post']->ID, array($knowledge_base_term->term_id), 'knowledge_base'); wp_set_post_terms($docs_data['post']->ID, array($doc_category_term->term_id), 'doc_category'); // // Step 3: Update posts to assign correct parent terms // wp_update_post(array( // 'ID' => $docs_data['post']->ID, // 'post_parent' => 0, // )); } } } } /** * Updates the 'betterdocs_migration' option with migrated knowledge base plugin names. * * This function checks if the option exists and is a serialized array. If the option exists, * it unserializes the current value, merges it with the new values, serializes the merged array, * and updates the option. If the option doesn't exist or is not a serialized array, it creates * a new option with the serialized format. * * @param string $kb_name The name of the knowledge base to be added or updated. * * @return void */ public function update_option( $kb_name ) { $existing_value = get_option( 'betterdocs_migration' ); $new_values = array( $kb_name ); if ($existing_value !== false && is_serialized( $existing_value )) { $existing_values_array = unserialize($existing_value); $merged_values = array_merge($existing_values_array, $new_values); update_option('betterdocs_migration', serialize($merged_values)); } else { update_option('betterdocs_migration', serialize($new_values)); } } public function get_migrated_plugins() { $existing_value = get_option( 'betterdocs_migration' ); if ( $existing_value ) { return unserialize($existing_value); } return []; } }