PluginProbe
BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot / 2.5.2
BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot v2.5.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 / includes / Core / Admin.php

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

544 lines 19.5 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\Utils\Enqueue;
8 use WPDeveloper\BetterDocs\Utils\Database;
9 use WPDeveloper\BetterDocs\Utils\Insights;
10 use WPDeveloper\BetterDocs\Admin\Analytics;
11 use WPDeveloper\BetterDocs\Dependencies\DI\Container;
12 use WPDeveloper\BetterDocs\Dependencies\PriyoMukul\WPNotice\Notices;
13
14 class Admin extends Base {
15 /**
16 * Admin Root Menu Slug
17 * @var string
18 */
19 private $slug = 'betterdocs-admin';
20 /**
21 * Insights
22 *
23 * @var Insights
24 */
25 private $insights = null;
26
27 /**
28 * DI\Container
29 *
30 * @var Container
31 */
32 private $container;
33
34 /**
35 * Database Wrapper
36 *
37 * @var Settings
38 */
39 private $settings;
40
41 /**
42 * Enqueue
43 * @var Enqueue
44 */
45 private $assets;
46
47 /**
48 * FAQBuilder
49 * @var FAQBuilder
50 */
51 private $faq_builder;
52
53 public function __construct( Container $container, PostType $type, Enqueue $assets, Settings $settings ) {
54 $this->container = $container;
55 $this->assets = $assets;
56 $this->settings = $settings;
57
58 add_action( 'init', [$type, 'register'], 9 );
59
60 $type->init();
61
62 $this->faq_builder = $this->container->get( FAQBuilder::class );
63
64 if ( ! is_admin() ) {
65 return;
66 }
67
68 $this->plugin_insights();
69 add_action( 'admin_notices', [$this, 'compatibility_notices'] );
70 add_action( 'admin_init', [$this, 'notices'], 9 );
71
72 $type->admin_init();
73
74 add_action( 'admin_menu', [$this, 'menus'] );
75 add_filter( 'plugin_action_links_' . BETTERDOCS_PLUGIN_BASENAME, [$this, 'insert_plugin_links'] );
76
77 $this->container->get( SetupWizard::class )->init();
78
79 add_action( 'admin_enqueue_scripts', [$this, 'styles'] );
80 add_action( 'admin_enqueue_scripts', [$this, 'scripts'] );
81 add_action( 'betterdocs_listing_header', [$this, 'header'], 10, 1 );
82 add_action( 'admin_bar_menu', [$this, 'toolbar_menu'], 32 );
83
84 add_filter( 'admin_body_class', [$this, 'body_classes'] );
85 add_filter( 'parent_file', [$type, 'highlight_admin_menu'] );
86 add_filter( 'submenu_file', [$type, 'highlight_admin_submenu'], 10, 2 );
87
88 /**
89 * Remove Comments Column from List Table.
90 */
91 add_filter( 'manage_docs_posts_columns', [$this, 'set_custom_edit_action_columns'] );
92 add_filter( 'manage_docs_posts_custom_column', [$this, 'manage_custom_columns'], 10, 2 );
93 }
94
95 public function compatibility_notices() {
96 if ( betterdocs()->is_pro_active() ) {
97 $plugins = Helper::get_plugins();
98 $plugin_data = $plugins['betterdocs-pro/betterdocs-pro.php'];
99
100 if ( isset( $plugin_data['Version'] ) && version_compare( $plugin_data['Version'], '2.5.0', '>=' ) ) {
101 return;
102 }
103
104 betterdocs()->views->get( 'admin/notices/compatibility', [ 'version' => $plugin_data['Version'] ] );
105 }
106 }
107
108 public function plugin_insights() {
109 $this->insights = Insights::get_instance( BETTERDOCS_PLUGIN_FILE, [
110 'opt_in' => true,
111 'goodbye_form' => true,
112 'item_id' => 'c7b16777b4f1b83f6083'
113 ] );
114
115 $this->insights->set_notice_options( [
116 'notice' => __( 'Want to help make <strong>BetterDocs</strong> even more awesome? You can get a <strong>10% discount coupon</strong> for Premium extensions if you allow us to track the usage.', 'betterdocs' ),
117 'extra_notice' => __( 'We collect non-sensitive diagnostic data and plugin usage information. Your site URL, WordPress & PHP version, plugins & themes and email address to send you the discount coupon. This data lets us make sure this plugin always stays compatible with the most popular plugins and themes. No spam, I promise.', 'betterdocs' )
118 ] );
119
120 $this->insights->init();
121 }
122
123 /**
124 * Admin notices for Review and others.
125 *
126 * @return void
127 */
128 public function notices() {
129 $notices = new Notices( [
130 'id' => 'betterdocs',
131 'store' => 'options',
132 'storage_key' => 'notices',
133 'version' => '1.0.0',
134 'lifetime' => 3,
135 'styles' => $this->assets->asset_url( 'admin/css/notices.css' )
136 // 'dev_mode' => true
137 ] );
138
139 /**
140 * Review Notice
141 * @var mixed $message
142 */
143
144 $message = __(
145 'We hope you\'re enjoying BetterDocs! Could you please do us a BIG favor and give it a 5-star rating on WordPress to help us spread the word and boost our motivation?',
146 'betterdocs'
147 );
148
149 $_review_notice = [
150 'thumbnail' => $this->assets->icon( 'betterdocs-icon.svg', true ),
151 'html' => '<p>' . $message . '</p>',
152 'links' => [
153 'later' => [
154 'link' => 'https://wordpress.org/plugins/betterdocs/#reviews',
155 'target' => '_blank',
156 'label' => __( 'Sure, you deserve it!', 'betterdocs' ),
157 'icon_class' => 'dashicons dashicons-external'
158 ],
159 'allready' => [
160 'label' => __( 'I already did', 'betterdocs' ),
161 'icon_class' => 'dashicons dashicons-smiley',
162 'attributes' => [
163 'data-dismiss' => true
164 ]
165 ],
166 'maybe_later' => [
167 'label' => __( 'Maybe Later', 'betterdocs' ),
168 'icon_class' => 'dashicons dashicons-calendar-alt',
169 'attributes' => [
170 'data-later' => true,
171 'class' => 'dismiss-btn'
172 ]
173 ],
174 'support' => [
175 'link' => 'https://wpdeveloper.com/support',
176 'attributes' => [
177 'target' => '_blank'
178 ],
179 'label' => __( 'I need help', 'betterdocs' ),
180 'icon_class' => 'dashicons dashicons-sos'
181 ],
182 'never_show_again' => [
183 'label' => __( 'Never show again', 'betterdocs' ),
184 'icon_class' => 'dashicons dashicons-dismiss',
185 'attributes' => [
186 'data-dismiss' => true
187 ]
188 ]
189 ]
190 ];
191
192 $notices->add(
193 'review',
194 $_review_notice,
195 [
196 'start' => $notices->strtotime( '+10 days' ),
197 'recurrence' => 30,
198 'dismissible' => true
199 // 'screens' => [
200 // 'dashboard', 'plugins', 'themes', 'edit-page',
201 // 'edit-post', 'users', 'tools', 'options-general',
202 // 'nav-menus', 'toplevel_page_betterdocs-admin', 'betterdocs_page_betterdocs-settings', 'betterdocs_page_betterdocs-analytics', 'betterdocs_page_betterdocs-faq', 'edit-doc_tag', 'edit-doc_category'
203 // ]
204 ]
205 );
206
207 /**
208 * Opt-In Notice
209 */
210 if ( $this->insights != null ) {
211 $notices->add(
212 'opt_in',
213 [$this->insights, 'notice'],
214 [
215 'classes' => 'updated put-dismiss-notice',
216 'start' => $notices->time(),
217 // 'start' => $notices->strtotime('+20 days'),
218 'dismissible' => true,
219 'do_action' => 'wpdeveloper_notice_clicked_for_betterdocs',
220 'display_if' => ! function_exists( 'betterdocs_pro' )
221 ]
222 );
223 }
224
225 $notices->init();
226 }
227
228 public function body_classes( $classes ) {
229 $saved_settings = get_option( 'betterdocs_settings', false );
230 $dark_mode = isset( $saved_settings['dark_mode'] ) ? $saved_settings['dark_mode'] : false;
231 $dark_mode = ! empty( $dark_mode ) ? boolval( $dark_mode ) : false;
232
233 if ( $dark_mode === true ) {
234 $classes .= ' betterdocs-dark-mode ';
235 }
236 return $classes;
237 }
238
239 /**
240 * Remove Comments Column From List Table
241 *
242 * @since 1.0.0
243 * @param array $columns
244 *
245 * @return array
246 */
247 public function set_custom_edit_action_columns( $columns ) {
248 unset( $columns['comments'] );
249 $new_columns = [];
250 foreach ( $columns as $key => $value ) {
251 if ( $key == 'date' ) {
252 $new_columns['betterdocs_word_count'] = __( 'Word Count', 'betterdocs' ); // put the tags column before it
253 }
254 $new_columns[$key] = $value;
255 }
256 return $new_columns;
257 }
258
259 public function manage_custom_columns( $column, $post_id ) {
260 switch ( $column ) {
261 case 'betterdocs_word_count':
262 $word_count = str_word_count( trim( strip_tags( get_post_field( 'post_content', $post_id ) ) ) );
263 echo '<span>' . $word_count . '</span>';
264 break;
265 }
266 }
267
268 /**
269 * Enqueue Assets for Admin ( Styles )
270 *
271 * @since 1.0.0
272 * @param string $hook
273 *
274 * @return void
275 */
276 public function styles( $hook ) {
277 $this->assets->enqueue( 'betterdocs-global', 'admin/css/global.css', [], 'all' );
278
279 // FIXME: need to check this condition
280 // $tax = function_exists('get_current_screen') ? get_current_screen() : '';
281 // if (!in_array($hook, array('toplevel_page_betterdocs-admin', 'betterdocs_page_betterdocs-settings', 'betterdocs_page_betterdocs-analytics'))) {
282 // if ($tax->taxonomy !== 'doc_category') {
283 // return;
284 // } else {
285 // return;
286 // }
287 // }
288
289 if ( ! in_array( $hook, ['toplevel_page_betterdocs-admin', 'betterdocs_page_betterdocs-settings', 'betterdocs_page_betterdocs-analytics'] ) ) {
290 return;
291 }
292
293 $this->assets->enqueue( 'betterdocs-select2', 'vendor/css/select2.min.css', [], 'all' );
294 $this->assets->enqueue( 'betterdocs-daterangepicker', 'vendor/css/daterangepicker.css', [], 'all' );
295 $this->assets->enqueue( 'betterdocs', 'admin/css/betterdocs.css', [], 'all' );
296 }
297
298 /**
299 * Enqueue Assets for Admin ( Scripts )
300 *
301 * @since 1.0.0
302 * @param string $hook
303 *
304 * @return void
305 */
306 public function scripts( $hook ) {
307 if ( ( $hook === 'edit.php' || $hook === 'toplevel_page_betterdocs-admin' ) && get_post_type() == 'docs' ) {
308 $this->assets->enqueue( 'betterdocs-switcher', 'admin/js/switcher.js', [
309 'jquery'
310 ] );
311
312 $this->assets->localize( 'betterdocs-switcher', 'betterdocsSwitcher', [
313 'menu_title' => __( 'Switch to BetterDocs UI', 'betterdocs' ),
314 'site_address' => get_bloginfo( 'url' ),
315 'betterdocs_pro_plugin' => betterdocs()->is_pro_active()
316 ] );
317 }
318 // global $current_screen;
319 // dump( $hook, $current_screen );
320
321 // FIXME: need to check this condition
322 // $tax = function_exists( 'get_current_screen' ) ? get_current_screen() : '';
323 // if ( ! in_array( $hook, ['toplevel_page_betterdocs-admin', 'betterdocs_page_betterdocs-settings', 'betterdocs_page_betterdocs-analytics'] ) ) {
324 // if ( $tax->taxonomy !== 'doc_category' ) {
325 // return;
326 // } else {
327 // return;
328 // }
329 // }
330
331 if ( ! in_array( $hook, ['toplevel_page_betterdocs-admin', 'betterdocs_page_betterdocs-analytics'] ) ) {
332 return;
333 }
334
335 wp_enqueue_script( 'wp-color-picker' );
336
337 $this->assets->enqueue( 'betterdocs-select2', 'vendor/js/select2.min.js', [] );
338 $this->assets->enqueue( 'betterdocs-sweetalert', 'vendor/js/sweetalert.min.js', [] );
339 $this->assets->enqueue( 'moment', 'vendor/js/moment.min.js', [] );
340 $this->assets->enqueue( 'betterdocs-daterangepicker', 'vendor/js/daterangepicker.min.js', [] );
341 $this->assets->enqueue( 'betterdocs-admin', 'admin/js/betterdocs.js', ['jquery', 'jquery-ui-sortable'] );
342
343 $dark_mode = $this->settings->get( 'dark_mode', false );
344
345 $this->assets->localize( 'betterdocs-admin', 'betterdocs_admin', [
346 'ajaxurl' => admin_url( 'admin-ajax.php' ),
347 'doc_cat_order_nonce' => wp_create_nonce( 'doc_cat_order_nonce' ),
348 'knowledge_base_order_nonce' => wp_create_nonce( 'knowledge_base_order_nonce' ),
349 'paged' => isset( $_GET['paged'] ) ? absint( wp_unslash( $_GET['paged'] ) ) : 0,
350 'per_page_id' => "edit_doc_category_per_page",
351 'menu_title' => __( 'Switch to BetterDocs UI', 'betterdocs' ),
352 'dark_mode' => ! empty( $dark_mode ) ? boolval( $dark_mode ) : false,
353 'text' => __( 'Copied!', 'betterdocs' ),
354 'test_report' => __( 'Test Report!', 'betterdocs' ),
355 'sending' => __( 'Sending...', 'betterdocs' )
356 ] );
357 }
358
359 /**
360 * All admin pages header
361 *
362 * @since 1.0.0
363 * @return void
364 */
365 public function header( $admin_tab_name ) {
366 $quick_links = [
367 'switch_view' => sprintf(
368 '<a href="%s" class="betterdocs-button betterdocs-button-secondary">%s</a>',
369 add_query_arg( ['post_type' => 'docs', 'bdocs_view' => 'classic'], 'edit.php' ),
370 __( 'Switch to Classic UI', 'betterdocs' )
371 ),
372 'add_new_doc' => sprintf(
373 '<a href="%s" class="betterdocs-button betterdocs-button-primary">%s</a>',
374 add_query_arg( ['post_type' => 'docs'], 'post-new.php' ),
375 __( 'Add New Doc', 'betterdocs' )
376 )
377 ];
378
379 $quick_links = apply_filters( 'betterdocs_quick_links', $quick_links );
380
381 betterdocs()->views->get( 'admin/header', [
382 'quick_links' => $quick_links,
383 'active_tab' => $admin_tab_name
384 ] );
385 }
386
387 /**
388 * Register all the menus for BetterDocs
389 *
390 * @since 1.0.0
391 * @return void
392 */
393 public function menus() {
394 $default_args = [
395 'page_title' => 'BetterDocs',
396 'menu_title' => 'BetterDocs',
397 'capability' => 'edit_posts',
398 'menu_slug' => $this->slug,
399 'callback' => [$this, 'output'],
400 'icon_url' => betterdocs()->assets->icon( 'betterdocs-icon-white.svg', true ),
401 'position' => 5
402 ];
403
404 $_menu_position = 5;
405
406 foreach ( $this->menu_list() as $key => $value ) {
407 if ( $key === 'betterdocs' ) {
408 $callable = 'add_menu_page';
409 $value = wp_parse_args( $value, $default_args );
410 } else {
411 $callable = 'add_submenu_page';
412 $default_args['callback'] = '';
413 $default_args['position'] = $_menu_position;
414 unset( $default_args['icon_url'] );
415 $value = wp_parse_args( $value, array_merge( ['parent_slug' => $this->slug], $default_args ) );
416 }
417
418 $_menu_position++;
419
420 $hookname = call_user_func_array( $callable, $value );
421 }
422 }
423
424 /**
425 * BetterDocs Admin Page Output
426 *
427 * @since 1.0.0
428 * @return void
429 */
430 public function output() {
431 betterdocs()->views->get( 'admin/main', [
432 'admin_ui' => 'dnd'
433 ] );
434 }
435
436 /**
437 * Menu creator helper
438 *
439 * @since 2.5.0
440 *
441 * @param string $title
442 * @param string $slug
443 * @param string $cap
444 * @param array $callback
445 *
446 * @return array
447 */
448 private function normalize_menu( $title, $slug, $cap = 'edit_docs', $callback = null ) {
449 return Helper::normalize_menu( $title, $slug, $cap, $callback );
450 }
451
452 /**
453 * BetterDocs Menu List
454 *
455 * @since 1.0.0
456 * @return array
457 */
458 private function menu_list() {
459 $betterdocs_admin_pages = [
460 'betterdocs' => [
461 'menu_slug' => $this->slug,
462 'page_title' => 'BetterDocs',
463 'menu_title' => 'BetterDocs',
464 'capability' => 'edit_docs',
465 'callback' => [$this, 'output'],
466 'icon_url' => betterdocs()->assets->icon( 'betterdocs-icon-white.svg', true ),
467 'position' => 5
468 ],
469 'all_docs' => $this->normalize_menu( __( 'All Docs', 'betterdocs' ), $this->slug ),
470 'add_new' => $this->normalize_menu( __( 'Add New', 'betterdocs' ), 'post-new.php?post_type=docs' ),
471 'categories' => $this->normalize_menu(
472 __( 'Categories', 'betterdocs' ),
473 'edit-tags.php?taxonomy=doc_category&post_type=docs',
474 'manage_doc_terms'
475 ),
476 'tags' => $this->normalize_menu(
477 __( 'Tags', 'betterdocs' ),
478 'edit-tags.php?taxonomy=doc_tag&post_type=docs',
479 'manage_doc_terms'
480 ),
481 'quick_setup' => $this->normalize_menu(
482 __( 'Quick Setup', 'betterdocs' ),
483 'betterdocs-setup',
484 'delete_users',
485 [$this->container->get( SetupWizard::class ), 'views']
486 ),
487 'settings' => $this->normalize_menu(
488 __( 'Settings', 'betterdocs' ),
489 'betterdocs-settings',
490 'edit_docs_settings',
491 [$this->container->get( Settings::class ), 'views']
492 ),
493 'analytics' => $this->normalize_menu(
494 __( 'Analytics', 'betterdocs' ),
495 'betterdocs-analytics',
496 'read_docs_analytics',
497 [$this->container->get( Analytics::class ), 'views']
498 ),
499 'faq' => $this->normalize_menu(
500 __( 'FAQ Builder', 'betterdocs' ),
501 'betterdocs-faq',
502 'read_docs_analytics',
503 [$this->faq_builder, 'output']
504 )
505 ];
506 return apply_filters( 'betterdocs_admin_menu', $betterdocs_admin_pages );
507 }
508
509 public function insert_plugin_links( $links ) {
510 $links[] = '<a href="admin.php?page=betterdocs-settings">' . __( 'Settings', 'betterdocs' ) . '</a>';
511 return $links;
512 }
513
514 public function toolbar_menu( $admin_bar ) {
515 if ( ! is_admin() || ! is_admin_bar_showing() ) {
516 return;
517 }
518
519 // Show only when the user is a member of this site, or they're a super admin.
520 if ( ! is_user_member_of_blog() && ! is_super_admin() ) {
521 return;
522 }
523
524 $docs_url = '';
525
526 if ( $this->settings->get( 'builtin_doc_page' ) ) {
527 $docs_url = get_post_type_archive_link( 'docs' );
528 } elseif ( intval( $docs_page = $this->settings->get( 'docs_page' ) ) ) {
529 $docs_url = ! empty( $docs_page ) ? get_page_link( $docs_page ) : false;
530 }
531
532 if ( ! $docs_url ) {
533 return;
534 }
535
536 $admin_bar->add_node( [
537 'parent' => 'site-name',
538 'id' => 'view-docs',
539 'title' => __( 'Visit Documentation', 'betterdocs' ),
540 'href' => $docs_url
541 ] );
542 }
543 }
544