PluginProbe
BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot / 2.3.6
BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot v2.3.6
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 / admin / class-betterdocs-admin.php

class-betterdocs-admin.php in BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot 2.3.6, at admin/class-betterdocs-admin.php

671 lines 17.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * The admin-specific functionality of the plugin.
5 *
6 * @link https://wpdeveloper.com
7 * @since 1.0.0
8 *
9 * @package BetterDocs
10 * @subpackage BetterDocs/admin
11 * @author WPDeveloper <support@wpdeveloper.com>
12 */
13
14 class BetterDocs_Admin
15 {
16
17 /**
18 * The ID of this plugin.
19 *
20 * @since 1.0.0
21 * @access private
22 * @var string $plugin_name The ID of this plugin.
23 */
24 private $plugin_name;
25 private $menu_slug;
26 /**
27 * All builder args
28 *
29 * @var array
30 */
31 private $builder_args;
32 /**
33 * Builder Metabox ID
34 *
35 * @var string
36 */
37 private $metabox_id;
38
39 /**
40 * The version of this plugin.
41 *
42 * @since 1.0.0
43 * @access private
44 * @var string $version The current version of this plugin.
45 */
46 private $version;
47
48 /**
49 * The type.
50 *
51 * @since 1.0.0
52 * @access public
53 * @var string the post type of betterdocs.
54 */
55 public $type = 'docs';
56
57 public $metabox;
58
59 public static $prefix = 'betterdocs_meta_';
60
61 public static $settings;
62
63 /**
64 * Initialize the class and set its properties.
65 *
66 * @since 1.0.0
67 * @param string $plugin_name The name of this plugin.
68 * @param string $version The version of this plugin.
69 */
70 public static $counts;
71
72 public static $enabled_types = [];
73 public static $active_items = [];
74
75 public function __construct($plugin_name, $version)
76 {
77
78 $this->plugin_name = $plugin_name;
79 $this->version = $version;
80 $this->metabox = new BetterDocs_MetaBox();
81 self::$settings = BetterDocs_DB::get_settings();
82 add_action('wp_ajax_betterdocs_dark_mode', array($this, 'dark_mode'));
83 add_action('wp_ajax_update_doc_cat_order', array($this, 'update_doc_cat_order'));
84 add_action('wp_ajax_update_doc_order_by_category', array($this, 'update_doc_order_by_category'));
85 add_action('wp_ajax_update_docs_term', array($this, 'update_docs_term'));
86 add_action('save_post_docs', array($this, 'update_new_post_doc_order_by_category'));
87 add_filter('betterdocs_articles_args', array($this, 'docs_args'), 11, 2);
88 add_action('new_to_auto-draft', array($this, 'auto_add_category'));
89 add_action('wp_ajax_test_email_report', array($this, 'test_email_report'));
90 }
91
92 /**
93 * Register the stylesheets for the admin area.
94 *
95 * @since 1.0.0
96 */
97 public function enqueue_styles($hook)
98 {
99 wp_enqueue_style(
100 $this->plugin_name . '-admin-global',
101 BETTERDOCS_ADMIN_URL . 'assets/css/betterdocs-global.css',
102 array(),
103 $this->version,
104 'all'
105 );
106
107 $tax = function_exists('get_current_screen') ? get_current_screen() : '';
108 if (!in_array($hook, array('toplevel_page_betterdocs-admin', 'betterdocs_page_betterdocs-settings', 'betterdocs_page_betterdocs-analytics', 'betterdocs_page_betterdocs-faq')) && $tax->taxonomy !== 'doc_category') {
109 return;
110 }
111
112 wp_enqueue_style(
113 $this->plugin_name . '-select2',
114 BETTERDOCS_ADMIN_URL . 'assets/css/select2.min.css',
115 array(),
116 $this->version,
117 'all'
118 );
119
120 wp_enqueue_style(
121 'daterangepicker',
122 BETTERDOCS_ADMIN_URL . 'assets/css/daterangepicker.css',
123 array(),
124 $this->version,
125 'all'
126 );
127
128 wp_enqueue_style(
129 $this->plugin_name,
130 BETTERDOCS_ADMIN_URL . 'assets/css/betterdocs-admin.css',
131 array(),
132 $this->version,
133 'all'
134 );
135
136 wp_enqueue_style(
137 $this->plugin_name . '-faq',
138 BETTERDOCS_ADMIN_URL . 'assets/css/betterdocs-faq.css',
139 array(),
140 $this->version,
141 'all'
142 );
143 }
144 /**
145 * Register the JavaScript for the admin area.
146 *
147 * @since 1.0.0
148 */
149 public function enqueue_scripts($hook)
150 {
151 wp_enqueue_script(
152 'betterdocs-admin-global',
153 BETTERDOCS_ADMIN_URL . 'assets/js/admin-global.js',
154 array('jquery'),
155 $this->version,
156 true
157 );
158
159 if( $hook === 'betterdocs_page_betterdocs-faq') {
160 $assets_faq = require_once BETTERDOCS_DIR_PATH . 'admin/assets/js/betterdocs-faq.asset.php';
161
162 wp_enqueue_script(
163 'betterdocs-faq',
164 BETTERDOCS_ADMIN_URL . 'assets/js/betterdocs-faq.js',
165 $assets_faq['dependencies'],
166 $assets_faq['version'],
167 true
168 );
169
170 wp_set_script_translations(
171 'betterdocs-faq',
172 'betterdocs',
173 BETTERDOCS_URL . 'languages'
174 );
175
176 // removing emoji support
177 remove_action( 'wp_head', 'print_emoji_detection_script', 7 );
178 remove_action( 'admin_print_scripts', 'print_emoji_detection_script' );
179
180 wp_localize_script(
181 'betterdocs-faq',
182 'betterdocs',
183 array(
184 'dir_url' => BETTERDOCS_URL,
185 'rest_url' => esc_url_raw( rest_url() ),
186 'free_version' => BETTERDOCS_VERSION,
187 'nonce' => wp_create_nonce( 'wp_rest' )
188 )
189 );
190 }
191
192 wp_localize_script(
193 'betterdocs-admin-global',
194 'betterdocs_admin',
195 array(
196 'menu_title' => __('Switch to BetterDocs UI', 'betterdocs'),
197 'site_address' => get_bloginfo('url'),
198 'betterdocs_pro_plugin' => is_plugin_active('betterdocs-pro/betterdocs-pro.php') ? 'true' : 'false'
199 )
200 );
201
202 $tax = function_exists('get_current_screen') ? get_current_screen() : '';
203
204 if (!in_array($hook, array('toplevel_page_betterdocs-admin', 'betterdocs_page_betterdocs-settings', 'betterdocs_page_betterdocs-analytics', 'betterdocs_page_betterdocs-setup')) && $tax->taxonomy !== 'doc_category') {
205 return;
206 }
207
208 wp_enqueue_script('wp-color-picker');
209
210 wp_enqueue_script(
211 $this->plugin_name . '-select2',
212 BETTERDOCS_ADMIN_URL . 'assets/js/select2.min.js',
213 array('jquery'),
214 $this->version,
215 true
216 );
217
218 wp_enqueue_script(
219 $this->plugin_name . '-sweetalert',
220 BETTERDOCS_ADMIN_URL . 'assets/js/sweetalert.min.js',
221 array('jquery'),
222 $this->version,
223 true
224 );
225
226 wp_enqueue_script(
227 'moment',
228 BETTERDOCS_ADMIN_URL . 'assets/js/moment.min.js',
229 array('jquery'),
230 $this->version,
231 true
232 );
233
234 wp_enqueue_script(
235 'daterangepicker',
236 BETTERDOCS_ADMIN_URL . 'assets/js/daterangepicker.min.js',
237 array('jquery'),
238 $this->version,
239 true
240 );
241
242
243 wp_enqueue_script(
244 $this->plugin_name,
245 BETTERDOCS_ADMIN_URL . 'assets/js/betterdocs-admin.js',
246 array('jquery'),
247 $this->version,
248 true
249 );
250
251 $dark_mode = false;
252
253 if (class_exists('BetterDocs_DB')) {
254 $dark_mode = BetterDocs_DB::get_settings('dark_mode');
255 }
256
257 wp_localize_script(
258 $this->plugin_name,
259 'betterdocs_admin',
260 array(
261 'ajaxurl' => admin_url('admin-ajax.php'),
262 'doc_cat_order_nonce' => wp_create_nonce('doc_cat_order_nonce'),
263 'knowledge_base_order_nonce' => wp_create_nonce('knowledge_base_order_nonce'),
264 'paged' => isset($_GET['paged']) ? absint(wp_unslash($_GET['paged'])) : 0,
265 'per_page_id' => "edit_{$tax->taxonomy}_per_page",
266 'menu_title' => __('Switch to BetterDocs UI', 'betterdocs'),
267 'dark_mode' => !empty($dark_mode) ? boolval($dark_mode) : false,
268 'text' => esc_html__('Copied!', 'betterdocs'),
269 'test_report' => esc_html__('Test Report!', 'betterdocs'),
270 'sending' => esc_html__('Sending...', 'betterdocs'),
271 )
272 );
273
274 wp_localize_script($this->plugin_name, 'betterdocsAdminConfig', self::toggleFields());
275 }
276
277 public function body_classes($classes)
278 {
279 $saved_settings = get_option('betterdocs_settings', false);
280 $dark_mode = isset($saved_settings['dark_mode']) ? $saved_settings['dark_mode'] : false;
281 $dark_mode = !empty($dark_mode) ? boolval($dark_mode) : false;
282 if ($dark_mode === true) {
283 $classes .= ' betterdocs-dark-mode ';
284 }
285 return $classes;
286 }
287
288 /**
289 * AJAX Handler to update terms' tax position.
290 */
291 public function dark_mode()
292 {
293 if (!check_ajax_referer('doc_cat_order_nonce', 'nonce', false)) {
294 wp_send_json_error();
295 }
296
297 if (isset($_POST['mode'])) {
298 $saved_settings = BetterDocs_DB::get_settings();
299 $saved_settings['dark_mode'] = $_POST['mode'];
300
301 if (BetterDocs_DB::update_settings($saved_settings)) {
302 wp_send_json_success();
303 }
304 }
305
306 wp_send_json_error();
307 }
308
309 public function toggleFields($builder = false)
310 {
311
312 $args = BetterDocs_Settings::settings_args();
313
314 $toggleFields = $hideFields = $conditions = array();
315
316 $tabs = $args;
317 if (!empty($tabs)) {
318 foreach ($tabs as $tab_id => $tab) {
319 $sections = isset($tab['sections']) ? $tab['sections'] : [];
320 if (!empty($sections)) {
321 foreach ($sections as $section_id => $section) {
322 $fields = isset($section['fields']) ? $section['fields'] : [];
323 if (isset($section['tabs']) && !empty($section['tabs'])) {
324 foreach ($section['tabs'] as $inner_field_tab_key => $inner_field_tab) {
325 if (isset($inner_field_tab['fields'])) {
326 foreach ($inner_field_tab['fields'] as $inner_tab_field_key => $inner_tab_field_tab) {
327 if (isset($inner_tab_field_tab['hide']) && !empty($inner_tab_field_tab['hide']) && is_array($inner_tab_field_tab['hide'])) {
328 $hideFields = $this->a_walk($inner_tab_field_tab['hide'], $inner_tab_field_key, $hideFields);
329 }
330 if (isset($inner_tab_field_tab['dependency']) && !empty($inner_tab_field_tab['dependency']) && is_array($inner_tab_field_tab['dependency'])) {
331 $conditions = $this->a_walk($inner_tab_field_tab['dependency'], $inner_tab_field_key, $conditions);
332 }
333 }
334 }
335 }
336 }
337 if (!empty($fields)) {
338 foreach ($fields as $field_key => $field) {
339 if (isset($field['fields'])) {
340 $iFields = $field['fields'];
341 foreach ($iFields as $inner_field_key => $inner_field) {
342 if (isset($inner_field['hide']) && !empty($inner_field['hide']) && is_array($inner_field['hide'])) {
343 $hideFields = $this->a_walk($inner_field['hide'], $inner_field_key, $hideFields);
344 }
345 if (isset($inner_field['dependency']) && !empty($inner_field['dependency']) && is_array($inner_field['dependency'])) {
346 $conditions = $this->a_walk($inner_field['dependency'], $inner_field_key, $conditions);
347 }
348 }
349 }
350 if (isset($field['hide']) && !empty($field['hide']) && is_array($field['hide'])) {
351 $hideFields = $this->a_walk($field['hide'], $field_key, $hideFields);
352 }
353 if (isset($field['dependency']) && !empty($field['dependency']) && is_array($field['dependency'])) {
354 $conditions = $this->a_walk($field['dependency'], $field_key, $conditions);
355 }
356 }
357 }
358 }
359 }
360 }
361 }
362
363 return array(
364 'toggleFields' => $conditions, // TODO: toggling system has to be more optimized!
365 'hideFields' => $hideFields,
366 );
367 }
368
369 public function a_walk($array, $field_key, &$returned_array = [])
370 {
371 array_walk($array, function ($value, $key) use ($field_key, &$returned_array) {
372 $returned_array[$field_key][$key] = $value;
373 });
374
375 return $returned_array;
376 }
377
378 public function quick_builder()
379 {
380 $builder_args = $this->builder_args;
381 $tabs = $this->builder_args['tabs'];
382 $prefix = self::$prefix;
383 $metabox_id = $this->metabox_id;
384 /**
385 * This lines of code is for editing a notification in simple|quick builder
386 *
387 * @var [type]
388 */
389 $idd = null;
390 if (isset($_GET['post_id']) && !empty($_GET['post_id'])) {
391 $idd = intval($_GET['post_id']);
392 }
393 include_once BETTERDOCS_ADMIN_DIR_PATH . 'partials/betterdocs-quick-builder-display.php';
394 }
395 /**
396 * Generate the builder data acording to default meta data
397 *
398 * @param array $data
399 * @return array
400 */
401 protected function builder_data($data)
402 {
403 $post_data = [];
404 $prefix = self::$prefix;
405 $meta_fields = BetterDocs_MetaBox::get_metabox_fields($prefix);
406 foreach ($meta_fields as $meta_key => $meta_field) {
407 if (in_array($meta_key, array_keys($data))) {
408 $post_data[$meta_key] = $data[$meta_key];
409 } else {
410 $post_data[$meta_key] = '';
411
412 if (isset($meta_field['defaults'])) {
413 $post_data[$meta_key] = $meta_field['defaults'];
414 }
415 if (isset($meta_field['default'])) {
416 $post_data[$meta_key] = $meta_field['default'];
417 }
418 }
419 }
420
421 return array_merge($post_data, $data);
422 }
423
424 public static function get_form_action($query_var = '', $builder_form = false)
425 {
426 $page = '/edit.php?post_type=docs&page=betterdocs-settings';
427
428 if (is_network_admin()) {
429 return network_admin_url($page . $query_var);
430 } else {
431 return admin_url($page . $query_var);
432 }
433 }
434
435
436 /**
437 * Admin Init For User Interactions
438 * @return void
439 */
440 public function admin_init($hook)
441 {
442 /**
443 * BetterDocs Admin URL
444 */
445 $current_url = admin_url('edit.php?post_type=docs&page=betterdocs-settings');
446 }
447 public function toolbar_menu($admin_bar)
448 {
449 if (!is_admin() || !is_admin_bar_showing()) {
450 return;
451 }
452
453 // Show only when the user is a member of this site, or they're a super admin.
454 if (!is_user_member_of_blog() && !is_super_admin()) {
455 return;
456 }
457
458 $saved_settings = BetterDocs_DB::get_settings();
459 $docs_url = '';
460 if (isset($saved_settings['builtin_doc_page']) && intval($saved_settings['builtin_doc_page'])) {
461 $docs_url = get_post_type_archive_link(BetterDocs_Docs_Post_Type::$post_type);
462 } elseif (isset($saved_settings['docs_page']) && intval($saved_settings['docs_page'])) {
463 $docs_url = !empty($saved_settings['docs_page']) ? get_page_link($saved_settings['docs_page']) : false;
464 }
465
466 if ($docs_url) {
467 $admin_bar->add_node(
468 array(
469 'parent' => 'site-name',
470 'id' => 'view-docs',
471 'title' => __('Visit Documentation', 'betterdocs'),
472 'href' => $docs_url,
473 )
474 );
475 }
476 }
477
478 /**
479 * Auto Add in Category, Adding from Sorting
480 *
481 * @param WP_Post $post
482 * @return void
483 */
484 public function auto_add_category($post)
485 {
486 if (!strpos($_SERVER['REQUEST_URI'], 'wp-admin/post-new.php')) {
487 return;
488 }
489 if (empty($_GET['cat'])) {
490 return;
491 }
492 $cat = wp_unslash($_GET['cat']);
493 if (false === ($cat = get_term_by('term_id', $cat, 'doc_category'))) {
494 return;
495 }
496 wp_set_post_terms($post->ID, array($cat->term_id), 'doc_category', false);
497 }
498
499 /**
500 *
501 * AJAX Handler to update terms' tax position.
502 *
503 */
504 public function update_doc_cat_order()
505 {
506 if (!check_ajax_referer('doc_cat_order_nonce', 'doc_cat_order_nonce', false)) {
507 wp_send_json_error();
508 }
509
510 $taxonomy_ordering_data = filter_var_array(wp_unslash($_POST['taxonomy_ordering_data']), FILTER_SANITIZE_NUMBER_INT);
511 $base_index = filter_var(wp_unslash($_POST['base_index']), FILTER_SANITIZE_NUMBER_INT);
512
513 foreach ($taxonomy_ordering_data as $order_data) {
514 if ($base_index > 0) {
515 $current_position = get_term_meta($order_data['term_id'], 'doc_category_order', true);
516
517 if ((int) $current_position < (int) $base_index) {
518 continue;
519 }
520 }
521 update_term_meta($order_data['term_id'], 'doc_category_order', ((int) $order_data['order'] + (int) $base_index));
522 }
523 wp_send_json_success();
524 }
525
526 /**
527 * AJAX Handler to update docs position.
528 */
529 public function update_doc_order_by_category()
530 {
531 if (!check_ajax_referer('doc_cat_order_nonce', 'doc_cat_order_nonce', false)) {
532 wp_send_json_error();
533 }
534
535 $docs_ordering_data = isset( $_POST['docs_ordering_data'] ) ? implode( ',', filter_var_array( $_POST['docs_ordering_data'], FILTER_SANITIZE_NUMBER_INT ) ) : '' ;
536 $term_id = intval($_POST['list_term_id']);
537
538 if (!$term_id) {
539 wp_send_json_error();
540 }
541
542 if ( update_term_meta( $term_id, '_docs_order', $docs_ordering_data ) ) {
543 wp_send_json_success();
544 }
545 }
546
547 /**
548 * AJAX Handler to update docs position.
549 */
550 public function update_docs_term()
551 {
552 if (!check_ajax_referer('doc_cat_order_nonce', 'doc_cat_order_nonce', false)) {
553 wp_send_json_error();
554 }
555
556 $object_id = intval($_POST['object_id']);
557 $term_id = intval($_POST['list_term_id']);
558 $prev_term_id = intval(isset($_POST['prev_term_id']) ? $_POST['prev_term_id'] : 0);
559
560 if (!$term_id || !$object_id) {
561
562 wp_send_json_error();
563 }
564
565 global $wpdb;
566
567 if ($prev_term_id) {
568
569 wp_remove_object_terms($object_id, $prev_term_id, 'doc_category');
570 }
571
572 $terms_added = wp_set_object_terms($object_id, $term_id, 'doc_category');
573
574 if (!is_wp_error($terms_added)) {
575
576 wp_send_json_success();
577 }
578
579 wp_send_json_error();
580 }
581
582 /**
583 * Update docs_term meta when new post created
584 */
585
586 public function update_new_post_doc_order_by_category($post_id)
587 {
588 $term_list = wp_get_post_terms($post_id, 'doc_category', array('fields' => 'ids'));
589
590 if (!empty($term_list)) {
591 foreach ($term_list as $term_id) {
592 $term = get_term($term_id, 'doc_category');
593 $term_slug = $term->slug;
594 $term_meta = get_term_meta($term_id, '_docs_order');
595 if (!empty($term_meta)) {
596 $term_meta_arr = explode(",", $term_meta[0]);
597
598 if (!in_array($post_id, $term_meta_arr)) {
599 array_unshift($term_meta_arr, $post_id);
600 $docs_ordering_data = filter_var_array(wp_unslash($term_meta_arr), FILTER_SANITIZE_NUMBER_INT);
601 $val = implode(',', $docs_ordering_data);
602 update_term_meta($term_id, '_docs_order', implode(',', $docs_ordering_data));
603 }
604 }
605 }
606 }
607 }
608
609 /**
610 *
611 * Update docs query arguments
612 *
613 */
614
615 public function docs_args($args, $term_id = null)
616 {
617 if (is_null($term_id) || isset($args['orderby'])) {
618 return $args;
619 }
620
621 $docs_order = get_term_meta($term_id, '_docs_order', true);
622
623 global $wpdb;
624
625 if (!empty($docs_order)) {
626
627 $docs_order = explode(',', $docs_order);
628
629 $new_ids = [];
630 $results = $wpdb->get_results("SELECT * FROM {$wpdb->prefix}term_relationships WHERE term_taxonomy_id = $term_id");
631
632 if (!is_null($results) && !empty($results) && is_array($results)) {
633
634 $object_ids = array_filter($results, function ($value) use ($docs_order) {
635 return !in_array($value->object_id, $docs_order);
636 });
637
638 if (!empty($object_ids)) {
639
640 array_walk($object_ids, function ($value) use (&$new_ids) {
641 $new_ids[] = $value->object_id;
642 });
643 }
644 }
645
646 $args['orderby'] = 'post__in';
647 $args['post__in'] = array_merge($new_ids, $docs_order);
648 }
649
650 return $args;
651 }
652
653 /**
654 *
655 * AJAX Handler to update terms' tax position.
656 *
657 */
658 public function test_email_report()
659 {
660 $template = new BetterDocs_Report_Email();
661 $reporting_frequency = apply_filters('betterdocs_test_reporting_frequency', 'betterdocs_weekly');
662 $email = $template->send_email($reporting_frequency);
663
664 if ($email) {
665 wp_send_json_success();
666 } else {
667 wp_send_json_error();
668 }
669 }
670 }
671