PluginProbe
BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot / 3.3.4
BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot v3.3.4
4.9.1 4.9.0 4.8.2 4.8.1 4.8.0 4.7.0 4.6.2 4.6.1 4.6.0 4.5.6 4.5.5 4.5.4 4.5.3 4.5.2 4.5.1 4.5.0 4.4.1 4.4.0 3.3.4 3.4.0 3.4.1 3.4.2 3.5.0 3.5.1 3.5.2 All 199 releases
betterdocs / includes / Core / KBMigration.php

KBMigration.php in BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot 3.3.4, at includes/Core/KBMigration.php

424 lines 19.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace WPDeveloper\BetterDocs\Core;
4
5 use WPDeveloper\BetterDocs\Utils\Base;
6 use WPDeveloper\BetterDocs\Utils\Helper;
7 use WPDeveloper\BetterDocs\Admin\Builder\Rules;
8
9 class KBMigration extends Base {
10 private $existing_plugins;
11 private $migrated_plugins;
12
13 public function __construct() {
14 $this->existing_plugins = $this->knowledge_base_plugins();
15 $this->migrated_plugins = $this->get_migrated_plugins();
16 if ( ! $this->existing_plugins || ( $this->existing_plugins && in_array( $this->existing_plugins[0][0], $this->migrated_plugins )) ) {
17 return;
18 }
19 add_filter( 'admin_notices', [ $this, 'migration_notice' ], 10, 1 );
20 add_filter( 'betterdocs_settings_tabs', [ $this, 'migration_settings' ], 10, 1 );
21 }
22
23 public function migration_notice() {
24 $screen = get_current_screen()->id;
25 if ( $screen === 'betterdocs_page_betterdocs-setup' ) {
26 return;
27 }
28 ?>
29 <div class="notice notice-success is-dismissible">
30 <?php
31 printf(
32 '<p>%s<a class="button button-primary betterdocs-migration-notice" href="%s">%s</a></p>',
33 __(
34 sprintf(
35 'Whoops! You are already using %s on your website. To migrate your %s data to BetterDocs, click here ',
36 '<strong>'. esc_html($this->existing_plugins[0][1]) .'</strong>',
37 '<strong>'. esc_html($this->existing_plugins[0][1]) .'</strong>'
38 ),
39 'betterdocs'
40 ),
41 esc_url(admin_url('admin.php?page=betterdocs-settings&tab=tab-migration')),
42 esc_html__('Start Migration', 'betterdocs')
43 );
44 ?>
45 </div>
46 <?php
47 }
48
49 public function migration_settings( $args ) {
50 /**
51 * License Tab
52 */
53 $args['tab-migration'] = apply_filters( 'betterdocs_settings_tab_migration', [
54 'id' => 'tab-migration',
55 'name' => 'tab-migration',
56 'classes' => 'tab-migration',
57 'type' => 'section',
58 'label' => __( 'Migration', 'betterdocs' ),
59 'save' => false,
60 'priority' => 80,
61 'fields' => [
62 'title-migration' => [
63 'name' => 'title-migration-tab',
64 'type' => 'section',
65 'label' => __( 'Migration', 'betterdocs' ),
66 'priority' => 80,
67 'submit' => [
68 'show' => false
69 ],
70 'step' => [
71 'show' => false
72 ],
73 'fields' => [
74 'kb_migration' => [
75 'name' => 'kb_migration',
76 'classes' => 'kb-migration-section',
77 'type' => 'section',
78 'priority' => 0,
79 'save' => false,
80 'fields' => apply_filters( 'betterdocs_migration_fields', [
81 'migration_header' => [
82 'name' => 'migration_header',
83 'type' => 'header',
84 'title' => __( 'Migration', 'betterdocs' ),
85 'direction' => 'column',
86 'description' => wp_sprintf(
87 __( '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' ),
88 $this->existing_plugins[0][1],
89 $this->existing_plugins[0][1]
90 ),
91 'icon' => '<img src="' . betterdocs()->assets->icon( 'icons/migration.svg', true ) . '"/>',
92 'priority' => 1,
93 ],
94 'migration_action' => [
95 'name' => 'migration_action',
96 'type' => 'button',
97 'text' => [
98 'normal' => __('Start Migration', 'betterdocs'),
99 'saved' => __('Migrated', 'betterdocs'),
100 'loading' => __('Migrating...', 'betterdocs'),
101 ],
102 'ajax' => [
103 'on' => 'click',
104 'api' => '/betterdocs/v1/migrate',
105 'data' => [
106 'existing_plugins' => $this->existing_plugins[0][1],
107 ],
108 'swal' => [
109 'text' => __('Import completed successfully.', 'betterdocs'),
110 'icon' => 'success',
111 'autoClose' => 1000
112 ],
113 'reload' => admin_url('admin.php?page=betterdocs-settings'),
114 ],
115 'priority' => 2,
116 ]
117 ])
118 ]
119 ]
120 ]
121 ]
122 ] );
123
124 return $args;
125 }
126
127 public function migrate() {
128 $existing_plugins = $this->knowledge_base_plugins();
129 $existing_plugins_data = $this->existing_plugins_data( $existing_plugins[0][0] );
130 if ( isset( $existing_plugins_data['name'] ) && isset( $existing_plugins_data['url'] ) ) {
131 if ( $existing_plugins_data['name'] === 'echo-knowledge-base' ) {
132 $this->eco_knowledgebase_migration();
133 } elseif ( $existing_plugins_data['name'] === 'pressapps-knowledge-base' ) {
134 $this->pressapps_migration();
135 } elseif ( $existing_plugins_data['name'] === 'wedocs' ) {
136 $this->wedocs_migration();
137 }
138 $this->update_option( $existing_plugins_data['name'] );
139 deactivate_plugins( $existing_plugins_data['url'] );
140 }
141 }
142
143 public function knowledge_base_plugins() {
144 $plugins = [];
145
146 if ( Helper::is_plugin_active( 'wedocs/wedocs.php' ) ) {
147 $plugins[] = ['wedocs', 'weDocs'];
148 }
149 if ( Helper::is_plugin_active( 'bsf-docs/bsf-docs.php' ) ) {
150 $plugins[] = ['bsf-docs', 'BSF docs'];
151 }
152 if ( Helper::is_plugin_active( 'documentor-lite/documentor-lite.php' ) ) {
153 $plugins[] = ['documentor-lite', 'Documentor'];
154 }
155 if ( Helper::is_plugin_active( 'echo-knowledge-base/echo-knowledge-base.php' ) ) {
156 $plugins[] = ['echo-knowledge-base', 'Echo Knowledge Base'];
157 }
158 if ( Helper::is_plugin_active( 'pressapps-knowledge-base/pressapps-knowledge-base.php' ) ) {
159 $plugins[] = ['pressapps-knowledge-base', 'PressApps Knowledge Base'];
160 }
161
162 return $plugins;
163 }
164
165 public function insert_terms_hierarchically( $existing_term, $new_term, $parentId = 0 ) {
166 $into = [];
167 $cats = get_terms( $existing_term, ['hide_empty' => false] );
168 if ( $cats ) {
169 foreach ( $cats as $i => $cat ) {
170 if ( $cat->parent == $parentId ) {
171 $into[$cat->term_id] = $cat;
172 unset( $cats[$i] );
173 $doc_parent_term = term_exists( $cat->name, $new_term );
174 wp_insert_term(
175 $cat->name,
176 $new_term,
177 [
178 'alias_of' => $cat->slug,
179 'description' => $cat->description,
180 'slug' => $cat->slug,
181 'parent' => $cat->parent
182 ]
183 );
184 }
185 }
186 if ( $cats ) {
187 foreach ( $cats as $i => $cat ) {
188 $get_existing_term = get_term_by( 'id', $cat->parent, $existing_term );
189 $doc_parent_term = term_exists( $get_existing_term->name, $new_term );
190 wp_insert_term(
191 $cat->name,
192 $new_term,
193 [
194 'alias_of' => $cat->slug,
195 'description' => $cat->description,
196 'slug' => $cat->slug,
197 'parent' => $doc_parent_term['term_id']
198 ]
199 );
200 }
201 }
202 }
203 }
204
205 public function insert_posts( $existing_post, $existing_cat, $existing_tag ) {
206 $args = [
207 'post_type' => $existing_post,
208 'post_status' => 'any',
209 'posts_per_page' => -1
210 ];
211 $postslist = get_posts( $args );
212 if ( $postslist ) {
213 foreach ( $postslist as $post ) {
214 // Create post object
215 if ( ! get_page_by_title( $post->post_title, 'OBJECT', 'docs' ) ) {
216 $post_args = [
217 'post_type' => 'docs',
218 'post_title' => $post->post_title,
219 'post_content' => $post->post_content,
220 'post_status' => $post->post_status,
221 'post_author' => $post->post_author,
222 'post_date' => $post->post_date,
223 'post_date_gmt' => $post->post_date_gmt,
224 'post_excerpt' => $post->post_excerpt,
225 'comment_status' => $post->comment_status,
226 'ping_status' => $post->ping_status,
227 'post_password' => $post->post_password,
228 'post_name' => $post->post_name,
229 'to_ping' => $post->to_ping,
230 'pinged' => $post->pinged,
231 'post_modified' => $post->post_modified,
232 'post_modified_gmt' => $post->post_modified_gmt,
233 'post_content_filtered' => $post->post_content_filtered,
234 'post_parent' => $post->post_parent,
235 'post_mime_type' => $post->post_mime_type,
236 'comment_count' => $post->comment_count,
237 'filter' => $post->filter
238 ];
239 // Insert the post into the database
240 $result = wp_insert_post( $post_args );
241 if ( $result && ! is_wp_error( $result ) ) {
242 $cat_list = wp_get_post_terms( $post->ID, $existing_cat, ['fields' => 'all'] );
243 if ( $cat_list ) {
244 $post_id = $result;
245 wp_set_object_terms( $post_id, [$cat_list['0']->name], 'doc_category', false );
246 }
247 $tag_list = wp_get_post_terms( $post->ID, $existing_tag, ['fields' => 'all'] );
248 if ( $tag_list ) {
249 $post_id = $result;
250 wp_set_object_terms( $post_id, [$tag_list['0']->name], 'doc_tag', false );
251 }
252 }
253 }
254 }
255 }
256 }
257
258 public function existing_plugins_data( $plugins ) {
259 $plugins_data = [];
260 if ( $plugins === 'wedocs' ) {
261 $plugins_data['name'] = 'wedocs';
262 $plugins_data['url'] = 'wedocs/wedocs.php';
263 }
264 if ( $plugins === 'bsf-docs' ) {
265 $plugins_data['name'] = 'bsf-docs';
266 $plugins_data['url'] = 'bsf-docs/bsf-docs.php';
267 }
268 if ( $plugins === 'documentor-lite' ) {
269 $plugins_data['name'] = 'documentor-lite';
270 $plugins_data['url'] = 'documentor-lite/documentor-lite.php';
271 }
272 if ( $plugins === 'echo-knowledge-base' ) {
273 $plugins_data['name'] = 'echo-knowledge-base';
274 $plugins_data['url'] = 'echo-knowledge-base/echo-knowledge-base.php';
275 }
276 if ( $plugins === 'pressapps-knowledge-base' ) {
277 $plugins_data['name'] = 'pressapps-knowledge-base';
278 $plugins_data['url'] = 'pressapps-knowledge-base/pressapps-knowledge-base.php';
279 }
280 return $plugins_data;
281 }
282
283 public function eco_knowledgebase_migration() {
284 $this->insert_terms_hierarchically( 'epkb_post_type_1_category', 'doc_category' );
285 $this->insert_terms_hierarchically( 'epkb_post_type_1_tag', 'doc_tag' );
286 $this->insert_posts( 'epkb_post_type_1', 'epkb_post_type_1_category', 'epkb_post_type_1_tag' );
287 }
288
289 public function pressapps_migration() {
290 $this->insert_terms_hierarchically( 'knowledgebase_category', 'doc_category' );
291 $this->insert_terms_hierarchically( 'knowledgebase_tags', 'doc_tag' );
292 $this->insert_posts( 'knowledgebase', 'knowledgebase_category', 'knowledgebase_tags' );
293 }
294
295 public function wedocs_migration() {
296 // Step 1: Get posts with no parent (main posts)
297 $args_step1 = array(
298 'post_type' => 'docs',
299 'post_status' => 'publish',
300 'posts_per_page' => -1,
301 'post_parent' => 0,
302 );
303
304 $posts_step1 = get_posts( $args_step1 );
305
306 // Multidimensional array to store posts
307 $nested_posts = array();
308
309 // First Dimension key: 'multiple_kb'
310 foreach ( $posts_step1 as $post_step1 ) {
311 $nested_posts['multiple_kb'][$post_step1->ID] = array(
312 'post' => $post_step1,
313 'doc_category' => array(), // Initialize the second dimension
314 );
315
316 // Step 2: 'doc_category'
317 $args_step2 = array(
318 'post_type' => 'docs',
319 'post_status' => 'publish',
320 'posts_per_page' => -1,
321 'post_parent' => $post_step1->ID,
322 );
323
324 $posts_step2 = get_posts($args_step2);
325
326 foreach ( $posts_step2 as $post_step2 ) {
327 $nested_posts['multiple_kb'][$post_step1->ID]['doc_category'][$post_step2->ID] = array(
328 'post' => $post_step2,
329 'docs' => array(), // Initialize the third dimension
330 );
331
332 // Step 3: 'docs'
333 $args_step3 = array(
334 'post_type' => 'docs', // Replace with your actual post type
335 'post_status' => 'publish',
336 'posts_per_page' => -1,
337 'post_parent' => $post_step2->ID,
338 );
339
340 $posts_step3 = get_posts($args_step3);
341
342 foreach ( $posts_step3 as $post_step3 ) {
343 $nested_posts['multiple_kb'][$post_step1->ID]['doc_category'][$post_step2->ID]['docs'][$post_step3->ID] = array(
344 'post' => $post_step3,
345 );
346 // Continue with additional dimensions if needed
347 }
348 }
349 }
350
351 // Now, $nested_posts contains the posts organized in a multidimensional array with the specified key names
352
353 foreach ( $nested_posts['multiple_kb'] as $multiple_kb_id => $multiple_kb_data ) {
354 // Step 1: Insert posts as terms under 'knowledge_base'
355 $knowledge_base_id = wp_insert_term($multiple_kb_data['post']->post_title, 'knowledge_base');
356
357 if ( ! is_wp_error($knowledge_base_id) ) {
358 wp_delete_post($multiple_kb_data['post']->ID, true);
359 $knowledge_base_term = get_term($knowledge_base_id['term_id'], 'knowledge_base');
360 }
361
362 foreach ( $multiple_kb_data['doc_category'] as $doc_category_id => $doc_category_data ) {
363
364 // Step 2: Insert posts as terms under 'doc_category' and set term meta
365 $doc_category_id = wp_insert_term($doc_category_data['post']->post_title, 'doc_category');
366
367 if (!is_wp_error($doc_category_id)) {
368 $doc_category_term = get_term($doc_category_id['term_id'], 'doc_category');
369 wp_delete_post($doc_category_data['post']->ID, true);
370 $doc_category_kb = rest_sanitize_array( array($knowledge_base_term->slug) );
371 // Set term meta for 'knowledge_base_doc_category'
372 update_term_meta($doc_category_id['term_id'], 'doc_category_knowledge_base', $doc_category_kb);
373 }
374
375 foreach ( $doc_category_data['docs'] as $docs_id => $docs_data ) {
376 wp_set_post_terms($docs_data['post']->ID, array($knowledge_base_term->term_id), 'knowledge_base');
377 wp_set_post_terms($docs_data['post']->ID, array($doc_category_term->term_id), 'doc_category');
378 // // Step 3: Update posts to assign correct parent terms
379 // wp_update_post(array(
380 // 'ID' => $docs_data['post']->ID,
381 // 'post_parent' => 0,
382 // ));
383 }
384 }
385 }
386 }
387
388 /**
389 * Updates the 'betterdos_migration' option with migrated knowledge base plugin names.
390 *
391 * This function checks if the option exists and is a serialized array. If the option exists,
392 * it unserializes the current value, merges it with the new values, serializes the merged array,
393 * and updates the option. If the option doesn't exist or is not a serialized array, it creates
394 * a new option with the serialized format.
395 *
396 * @param string $kb_name The name of the knowledge base to be added or updated.
397 *
398 * @return void
399 */
400 public function update_option( $kb_name ) {
401 $existing_value = get_option( 'betterdos_migration' );
402 $new_values = array( $kb_name );
403
404 if ($existing_value !== false && is_serialized( $existing_value )) {
405 $existing_values_array = unserialize($existing_value);
406 $merged_values = array_merge($existing_values_array, $new_values);
407
408 update_option('betterdos_migration', serialize($merged_values));
409 } else {
410 update_option('betterdos_migration', serialize($new_values));
411 }
412 }
413
414 public function get_migrated_plugins() {
415 $existing_value = get_option( 'betterdos_migration' );
416
417 if ( $existing_value ) {
418 return unserialize($existing_value);
419 }
420
421 return [];
422 }
423 }
424