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

630 lines 16.7 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')) && $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 /**
137 * Register the JavaScript for the admin area.
138 *
139 * @since 1.0.0
140 */
141 public function enqueue_scripts($hook)
142 {
143 wp_enqueue_script(
144 'betterdocs-admin-global',
145 BETTERDOCS_ADMIN_URL . 'assets/js/admin-global.js',
146 array('jquery'),
147 $this->version,
148 true
149 );
150
151 wp_localize_script(
152 'betterdocs-admin-global',
153 'betterdocs_admin',
154 array(
155 'menu_title' => __('Switch to BetterDocs UI', 'betterdocs'),
156 'site_address' => get_bloginfo('url'),
157 'betterdocs_pro_plugin' => is_plugin_active('betterdocs-pro/betterdocs-pro.php') ? 'true' : 'false'
158 )
159 );
160
161 $tax = function_exists('get_current_screen') ? get_current_screen() : '';
162
163 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') {
164 return;
165 }
166
167 wp_enqueue_script('wp-color-picker');
168
169 wp_enqueue_script(
170 $this->plugin_name . '-select2',
171 BETTERDOCS_ADMIN_URL . 'assets/js/select2.min.js',
172 array('jquery'),
173 $this->version,
174 true
175 );
176
177 wp_enqueue_script(
178 $this->plugin_name . '-sweetalert',
179 BETTERDOCS_ADMIN_URL . 'assets/js/sweetalert.min.js',
180 array('jquery'),
181 $this->version,
182 true
183 );
184
185 wp_enqueue_script(
186 'moment',
187 BETTERDOCS_ADMIN_URL . 'assets/js/moment.min.js',
188 array('jquery'),
189 $this->version,
190 true
191 );
192
193 wp_enqueue_script(
194 'daterangepicker',
195 BETTERDOCS_ADMIN_URL . 'assets/js/daterangepicker.min.js',
196 array('jquery'),
197 $this->version,
198 true
199 );
200
201
202 wp_enqueue_script(
203 $this->plugin_name,
204 BETTERDOCS_ADMIN_URL . 'assets/js/betterdocs-admin.js',
205 array('jquery'),
206 $this->version,
207 true
208 );
209
210 $dark_mode = false;
211
212 if (class_exists('BetterDocs_DB')) {
213 $dark_mode = BetterDocs_DB::get_settings('dark_mode');
214 }
215
216 wp_localize_script(
217 $this->plugin_name,
218 'betterdocs_admin',
219 array(
220 'ajaxurl' => admin_url('admin-ajax.php'),
221 'doc_cat_order_nonce' => wp_create_nonce('doc_cat_order_nonce'),
222 'knowledge_base_order_nonce' => wp_create_nonce('knowledge_base_order_nonce'),
223 'paged' => isset($_GET['paged']) ? absint(wp_unslash($_GET['paged'])) : 0,
224 'per_page_id' => "edit_{$tax->taxonomy}_per_page",
225 'menu_title' => __('Switch to BetterDocs UI', 'betterdocs'),
226 'dark_mode' => !empty($dark_mode) ? boolval($dark_mode) : false,
227 'text' => esc_html__('Copied!', 'betterdocs'),
228 'test_report' => esc_html__('Test Report!', 'betterdocs'),
229 'sending' => esc_html__('Sending...', 'betterdocs'),
230 )
231 );
232
233 wp_localize_script($this->plugin_name, 'betterdocsAdminConfig', self::toggleFields());
234 }
235
236 public function body_classes($classes)
237 {
238 $saved_settings = get_option('betterdocs_settings', false);
239 $dark_mode = isset($saved_settings['dark_mode']) ? $saved_settings['dark_mode'] : false;
240 $dark_mode = !empty($dark_mode) ? boolval($dark_mode) : false;
241 if ($dark_mode === true) {
242 $classes .= ' betterdocs-dark-mode ';
243 }
244 return $classes;
245 }
246
247 /**
248 * AJAX Handler to update terms' tax position.
249 */
250 public function dark_mode()
251 {
252 if (!check_ajax_referer('doc_cat_order_nonce', 'nonce', false)) {
253 wp_send_json_error();
254 }
255
256 if (isset($_POST['mode'])) {
257 $saved_settings = BetterDocs_DB::get_settings();
258 $saved_settings['dark_mode'] = $_POST['mode'];
259
260 if (BetterDocs_DB::update_settings($saved_settings)) {
261 wp_send_json_success();
262 }
263 }
264
265 wp_send_json_error();
266 }
267
268 public function toggleFields($builder = false)
269 {
270
271 $args = BetterDocs_Settings::settings_args();
272
273 $toggleFields = $hideFields = $conditions = array();
274
275 $tabs = $args;
276 if (!empty($tabs)) {
277 foreach ($tabs as $tab_id => $tab) {
278 $sections = isset($tab['sections']) ? $tab['sections'] : [];
279 if (!empty($sections)) {
280 foreach ($sections as $section_id => $section) {
281 $fields = isset($section['fields']) ? $section['fields'] : [];
282 if (isset($section['tabs']) && !empty($section['tabs'])) {
283 foreach ($section['tabs'] as $inner_field_tab_key => $inner_field_tab) {
284 if (isset($inner_field_tab['fields'])) {
285 foreach ($inner_field_tab['fields'] as $inner_tab_field_key => $inner_tab_field_tab) {
286 if (isset($inner_tab_field_tab['hide']) && !empty($inner_tab_field_tab['hide']) && is_array($inner_tab_field_tab['hide'])) {
287 $hideFields = $this->a_walk($inner_tab_field_tab['hide'], $inner_tab_field_key, $hideFields);
288 }
289 if (isset($inner_tab_field_tab['dependency']) && !empty($inner_tab_field_tab['dependency']) && is_array($inner_tab_field_tab['dependency'])) {
290 $conditions = $this->a_walk($inner_tab_field_tab['dependency'], $inner_tab_field_key, $conditions);
291 }
292 }
293 }
294 }
295 }
296 if (!empty($fields)) {
297 foreach ($fields as $field_key => $field) {
298 if (isset($field['fields'])) {
299 $iFields = $field['fields'];
300 foreach ($iFields as $inner_field_key => $inner_field) {
301 if (isset($inner_field['hide']) && !empty($inner_field['hide']) && is_array($inner_field['hide'])) {
302 $hideFields = $this->a_walk($inner_field['hide'], $inner_field_key, $hideFields);
303 }
304 if (isset($inner_field['dependency']) && !empty($inner_field['dependency']) && is_array($inner_field['dependency'])) {
305 $conditions = $this->a_walk($inner_field['dependency'], $inner_field_key, $conditions);
306 }
307 }
308 }
309 if (isset($field['hide']) && !empty($field['hide']) && is_array($field['hide'])) {
310 $hideFields = $this->a_walk($field['hide'], $field_key, $hideFields);
311 }
312 if (isset($field['dependency']) && !empty($field['dependency']) && is_array($field['dependency'])) {
313 $conditions = $this->a_walk($field['dependency'], $field_key, $conditions);
314 }
315 }
316 }
317 }
318 }
319 }
320 }
321
322 return array(
323 'toggleFields' => $conditions, // TODO: toggling system has to be more optimized!
324 'hideFields' => $hideFields,
325 );
326 }
327
328 public function a_walk($array, $field_key, &$returned_array = [])
329 {
330 array_walk($array, function ($value, $key) use ($field_key, &$returned_array) {
331 $returned_array[$field_key][$key] = $value;
332 });
333
334 return $returned_array;
335 }
336
337 public function quick_builder()
338 {
339 $builder_args = $this->builder_args;
340 $tabs = $this->builder_args['tabs'];
341 $prefix = self::$prefix;
342 $metabox_id = $this->metabox_id;
343 /**
344 * This lines of code is for editing a notification in simple|quick builder
345 *
346 * @var [type]
347 */
348 $idd = null;
349 if (isset($_GET['post_id']) && !empty($_GET['post_id'])) {
350 $idd = intval($_GET['post_id']);
351 }
352 include_once BETTERDOCS_ADMIN_DIR_PATH . 'partials/betterdocs-quick-builder-display.php';
353 }
354 /**
355 * Generate the builder data acording to default meta data
356 *
357 * @param array $data
358 * @return array
359 */
360 protected function builder_data($data)
361 {
362 $post_data = [];
363 $prefix = self::$prefix;
364 $meta_fields = BetterDocs_MetaBox::get_metabox_fields($prefix);
365 foreach ($meta_fields as $meta_key => $meta_field) {
366 if (in_array($meta_key, array_keys($data))) {
367 $post_data[$meta_key] = $data[$meta_key];
368 } else {
369 $post_data[$meta_key] = '';
370
371 if (isset($meta_field['defaults'])) {
372 $post_data[$meta_key] = $meta_field['defaults'];
373 }
374 if (isset($meta_field['default'])) {
375 $post_data[$meta_key] = $meta_field['default'];
376 }
377 }
378 }
379
380 return array_merge($post_data, $data);
381 }
382
383 public static function get_form_action($query_var = '', $builder_form = false)
384 {
385 $page = '/edit.php?post_type=docs&page=betterdocs-settings';
386
387 if (is_network_admin()) {
388 return network_admin_url($page . $query_var);
389 } else {
390 return admin_url($page . $query_var);
391 }
392 }
393
394
395 /**
396 * Admin Init For User Interactions
397 * @return void
398 */
399 public function admin_init($hook)
400 {
401 /**
402 * BetterDocs Admin URL
403 */
404 $current_url = admin_url('edit.php?post_type=docs&page=betterdocs-settings');
405 }
406 public function toolbar_menu($admin_bar)
407 {
408 if (!is_admin() || !is_admin_bar_showing()) {
409 return;
410 }
411
412 // Show only when the user is a member of this site, or they're a super admin.
413 if (!is_user_member_of_blog() && !is_super_admin()) {
414 return;
415 }
416
417 $saved_settings = BetterDocs_DB::get_settings();
418 $docs_url = '';
419 if (isset($saved_settings['builtin_doc_page']) && intval($saved_settings['builtin_doc_page'])) {
420 $docs_url = get_post_type_archive_link(BetterDocs_Docs_Post_Type::$post_type);
421 } elseif (isset($saved_settings['docs_page']) && intval($saved_settings['docs_page'])) {
422 $docs_url = !empty($saved_settings['docs_page']) ? get_page_link($saved_settings['docs_page']) : false;
423 }
424
425 if ($docs_url) {
426 $admin_bar->add_node(
427 array(
428 'parent' => 'site-name',
429 'id' => 'view-docs',
430 'title' => __('Visit Documentation', 'betterdocs'),
431 'href' => $docs_url,
432 )
433 );
434 }
435 }
436
437 /**
438 * Auto Add in Category, Adding from Sorting
439 *
440 * @param WP_Post $post
441 * @return void
442 */
443 public function auto_add_category($post)
444 {
445 if (!strpos($_SERVER['REQUEST_URI'], 'wp-admin/post-new.php')) {
446 return;
447 }
448 if (empty($_GET['cat'])) {
449 return;
450 }
451 $cat = wp_unslash($_GET['cat']);
452 if (false === ($cat = get_term_by('term_id', $cat, 'doc_category'))) {
453 return;
454 }
455 wp_set_post_terms($post->ID, array($cat->term_id), 'doc_category', false);
456 }
457
458 /**
459 *
460 * AJAX Handler to update terms' tax position.
461 *
462 */
463 public function update_doc_cat_order()
464 {
465 if (!check_ajax_referer('doc_cat_order_nonce', 'doc_cat_order_nonce', false)) {
466 wp_send_json_error();
467 }
468
469 $taxonomy_ordering_data = filter_var_array(wp_unslash($_POST['taxonomy_ordering_data']), FILTER_SANITIZE_NUMBER_INT);
470 $base_index = filter_var(wp_unslash($_POST['base_index']), FILTER_SANITIZE_NUMBER_INT);
471
472 foreach ($taxonomy_ordering_data as $order_data) {
473 if ($base_index > 0) {
474 $current_position = get_term_meta($order_data['term_id'], 'doc_category_order', true);
475
476 if ((int) $current_position < (int) $base_index) {
477 continue;
478 }
479 }
480 update_term_meta($order_data['term_id'], 'doc_category_order', ((int) $order_data['order'] + (int) $base_index));
481 }
482 wp_send_json_success();
483 }
484
485 /**
486 * AJAX Handler to update docs position.
487 */
488 public function update_doc_order_by_category()
489 {
490 if (!check_ajax_referer('doc_cat_order_nonce', 'doc_cat_order_nonce', false)) {
491 wp_send_json_error();
492 }
493
494 $docs_ordering_data = isset( $_POST['docs_ordering_data'] ) ? implode( ',', filter_var_array( $_POST['docs_ordering_data'], FILTER_SANITIZE_NUMBER_INT ) ) : '' ;
495 $term_id = intval($_POST['list_term_id']);
496
497 if (!$term_id) {
498 wp_send_json_error();
499 }
500
501 if ( update_term_meta( $term_id, '_docs_order', $docs_ordering_data ) ) {
502 wp_send_json_success();
503 }
504 }
505
506 /**
507 * AJAX Handler to update docs position.
508 */
509 public function update_docs_term()
510 {
511 if (!check_ajax_referer('doc_cat_order_nonce', 'doc_cat_order_nonce', false)) {
512 wp_send_json_error();
513 }
514
515 $object_id = intval($_POST['object_id']);
516 $term_id = intval($_POST['list_term_id']);
517 $prev_term_id = intval(isset($_POST['prev_term_id']) ? $_POST['prev_term_id'] : 0);
518
519 if (!$term_id || !$object_id) {
520
521 wp_send_json_error();
522 }
523
524 global $wpdb;
525
526 if ($prev_term_id) {
527
528 wp_remove_object_terms($object_id, $prev_term_id, 'doc_category');
529 }
530
531 $terms_added = wp_set_object_terms($object_id, $term_id, 'doc_category');
532
533 if (!is_wp_error($terms_added)) {
534
535 wp_send_json_success();
536 }
537
538 wp_send_json_error();
539 }
540
541 /**
542 * Update docs_term meta when new post created
543 */
544
545 public function update_new_post_doc_order_by_category( $post_id )
546 {
547 $term_list = wp_get_post_terms($post_id, 'doc_category', array('fields' => 'ids'));
548
549 if (!empty($term_list)) {
550 foreach ($term_list as $term_id) {
551 $term = get_term($term_id, 'doc_category');
552 $term_slug = $term->slug;
553 $term_meta = get_term_meta($term_id, '_docs_order');
554 if (!empty($term_meta)) {
555 $term_meta_arr = explode(",", $term_meta[0]);
556
557 if (!in_array($post_id, $term_meta_arr)) {
558 array_unshift($term_meta_arr, $post_id);
559 $docs_ordering_data = filter_var_array(wp_unslash($term_meta_arr), FILTER_SANITIZE_NUMBER_INT);
560 $val = implode(',', $docs_ordering_data);
561 update_term_meta($term_id, '_docs_order', implode(',', $docs_ordering_data));
562 }
563 }
564 }
565 }
566 }
567
568 /**
569 *
570 * Update docs query arguments
571 *
572 */
573
574 public function docs_args($args, $term_id = null)
575 {
576 if (is_null($term_id) || isset($args['orderby'])) {
577 return $args;
578 }
579
580 $docs_order = get_term_meta($term_id, '_docs_order', true);
581
582 global $wpdb;
583
584 if (!empty($docs_order)) {
585
586 $docs_order = explode(',', $docs_order);
587
588 $new_ids = [];
589 $results = $wpdb->get_results("SELECT * FROM {$wpdb->prefix}term_relationships WHERE term_taxonomy_id = $term_id");
590
591 if (!is_null($results) && !empty($results) && is_array($results)) {
592
593 $object_ids = array_filter($results, function ($value) use ($docs_order) {
594 return !in_array($value->object_id, $docs_order);
595 });
596
597 if (!empty($object_ids)) {
598
599 array_walk($object_ids, function ($value) use (&$new_ids) {
600 $new_ids[] = $value->object_id;
601 });
602 }
603 }
604
605 $args['orderby'] = 'post__in';
606 $args['post__in'] = array_merge($new_ids, $docs_order);
607 }
608
609 return $args;
610 }
611
612 /**
613 *
614 * AJAX Handler to update terms' tax position.
615 *
616 */
617 public function test_email_report()
618 {
619 $template = new BetterDocs_Report_Email();
620 $reporting_frequency = apply_filters('betterdocs_test_reporting_frequency', 'betterdocs_weekly');
621 $email = $template->send_email($reporting_frequency);
622
623 if ($email) {
624 wp_send_json_success();
625 } else {
626 wp_send_json_error();
627 }
628 }
629 }
630