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

741 lines 30.2 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 Exception;
6 use PriyoMukul\WPNotice\Notices;
7 use PriyoMukul\WPNotice\Utils\CacheBank;
8 use PriyoMukul\WPNotice\Utils\NoticeRemover;
9 use WPDeveloper\BetterDocs\Admin\Analytics;
10 use WPDeveloper\BetterDocs\Dependencies\DI\Container;
11 use WPDeveloper\BetterDocs\Utils\Base;
12 use WPDeveloper\BetterDocs\Utils\Enqueue;
13 use WPDeveloper\BetterDocs\Utils\Helper;
14 use WPDeveloper\BetterDocs\Utils\Insights;
15 use WPDeveloper\BetterDocs\Core\KBMigration;
16
17 class Admin extends Base {
18 /**
19 * @var CacheBank
20 */
21 private static $cache_bank;
22 /**
23 * Admin Root Menu Slug
24 * @var string
25 */
26 private $slug = 'betterdocs-admin';
27 /**
28 * Insights
29 *
30 * @var Insights
31 */
32 private $insights = null;
33
34 /**
35 * DI\Container
36 *
37 * @var Container
38 */
39 private $container;
40
41 /**
42 * Database Wrapper
43 *
44 * @var Settings
45 */
46 private $settings;
47
48 /**
49 * KBMigration
50 *
51 * @var KBMigration
52 */
53 private $kbmigration;
54
55 /**
56 * Enqueue
57 * @var Enqueue
58 */
59 private $assets;
60
61 /**
62 * FAQBuilder
63 * @var FAQBuilder
64 */
65 private $faq_builder;
66
67 public function __construct( Container $container, PostType $type, Enqueue $assets, Settings $settings, KBMigration $kbmigration ) {
68 $this->container = $container;
69 $this->assets = $assets;
70 $this->settings = $settings;
71 $this->kbmigration = $kbmigration;
72 $this->slug = 'betterdocs-admin';
73
74 add_action( 'init', [ $type, 'register' ], 9 );
75
76 $type->init();
77 $type->admin_init();
78
79 $this->faq_builder = $this->container->get( FAQBuilder::class );
80
81 if ( ! is_admin() ) {
82 return;
83 }
84
85 $this->plugin_insights();
86 add_action( 'admin_notices', [$this, 'compatibility_notices'] );
87 // add_action( 'admin_init', [$this, 'notices'], 9 );
88 add_filter( 'admin_init', [$this, 'save_admin_page'], 99 );
89
90 add_action( 'admin_menu', [$this, 'menus'] );
91 add_action( 'admin_menu', [$this, 'reset_submenu'] );
92 add_filter( 'plugin_action_links_' . BETTERDOCS_PLUGIN_BASENAME, [$this, 'insert_plugin_links'] );
93
94 // $this->container->get( SetupWizard::class )->init();
95
96 add_action( 'admin_enqueue_scripts', [ $this, 'styles' ] );
97 add_action( 'admin_enqueue_scripts', [ $this, 'scripts' ] );
98 add_action( 'betterdocs_listing_header', [ $this, 'header' ], 10, 1 );
99 add_action( 'admin_bar_menu', [ $this, 'toolbar_menu' ], 32 );
100
101 add_filter( 'admin_body_class', [ $this, 'body_classes' ] );
102 add_filter( 'parent_file', [ $type, 'highlight_admin_menu' ] );
103 add_filter( 'submenu_file', [ $type, 'highlight_admin_submenu' ], 10, 2 );
104 add_filter( 'betterdocs_admin_menu', [ $this, 'quick_setup_menu' ], 10, 1 );
105
106 /**
107 * Remove Comments Column from List Table.
108 */
109 add_filter( 'manage_docs_posts_columns', [ $this, 'set_custom_edit_action_columns' ] );
110 add_filter( 'manage_docs_posts_custom_column', [ $this, 'manage_custom_columns' ], 10, 2 );
111
112 self::$cache_bank = CacheBank::get_instance();
113 try {
114 // $this->notices();
115 add_action('admin_init', [$this, 'notices']);
116 } catch ( Exception $e ) {
117 unset( $e );
118 }
119 // Remove OLD notice from 1.0.0 (if other WPDeveloper plugin has notice)
120 NoticeRemover::get_instance( '1.0.0' );
121 }
122
123 public function compatibility_notices() {
124 if ( betterdocs()->is_pro_active() ) {
125 $plugins = Helper::get_plugins();
126 $plugin_data = $plugins['betterdocs-pro/betterdocs-pro.php'];
127
128 if ( isset( $plugin_data['Version'] ) && version_compare( $plugin_data['Version'], '2.5.0', '>=' ) ) {
129 return;
130 }
131
132 betterdocs()->views->get( 'admin/notices/compatibility', [ 'version' => $plugin_data['Version'] ] );
133 }
134 }
135
136 public function plugin_insights( $prevent_init = false ) {
137 $this->insights = Insights::get_instance( BETTERDOCS_PLUGIN_FILE, [
138 'opt_in' => true,
139 'goodbye_form' => true,
140 'item_id' => 'c7b16777b4f1b83f6083'
141 ] );
142
143 $this->insights->set_notice_options( [
144 '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' ),
145 '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' )
146 ] );
147
148 if ( ! $prevent_init ) {
149 $this->insights->init();
150 }
151
152 return $this->insights;
153 }
154
155 /**
156 * Admin notices for Review and others.
157 *
158 * @return void
159 * @throws Exception
160 */
161 public function notices() {
162 $notices = new Notices( [
163 'id' => 'betterdocs',
164 'storage_key' => 'notices',
165 'lifetime' => 3,
166 'stylesheet_url' => $this->assets->asset_url( 'admin/css/notices.css' ),
167 'styles' => $this->assets->asset_url( 'admin/css/notices.css' ),
168 'priority' => 4
169 ] );
170
171 /**
172 * Review Notice
173 * @var mixed $message
174 */
175
176 $message = __( '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?', 'betterdocs' );
177
178 $_review_notice = [
179 'thumbnail' => $this->assets->icon( 'betterdocs-logo.svg', true ),
180 'html' => '<p>' . $message . '</p>',
181 'links' => [
182 'later' => [
183 'link' => 'https://wordpress.org/plugins/betterdocs/#reviews',
184 'target' => '_blank',
185 'label' => __( 'Sure, you deserve it!', 'betterdocs' ),
186 'icon_class' => 'dashicons dashicons-external'
187 ],
188 'allready' => [
189 'label' => __( 'I already did', 'betterdocs' ),
190 'icon_class' => 'dashicons dashicons-smiley',
191 'attributes' => [
192 'data-dismiss' => true
193 ]
194 ],
195 'maybe_later' => [
196 'label' => __( 'Maybe Later', 'betterdocs' ),
197 'icon_class' => 'dashicons dashicons-calendar-alt',
198 'attributes' => [
199 'data-later' => true,
200 'class' => 'dismiss-btn'
201 ]
202 ],
203 'support' => [
204 'link' => 'https://wpdeveloper.com/support',
205 'attributes' => [
206 'target' => '_blank'
207 ],
208 'label' => __( 'I need help', 'betterdocs' ),
209 'icon_class' => 'dashicons dashicons-sos'
210 ],
211 'never_show_again' => [
212 'label' => __( 'Never show again', 'betterdocs' ),
213 'icon_class' => 'dashicons dashicons-dismiss',
214 'attributes' => [
215 'data-dismiss' => true
216 ]
217 ]
218 ]
219 ];
220
221 $notices->add( 'review', $_review_notice, [
222 'start' => $notices->strtotime( '+10 days' ),
223 'recurrence' => 30,
224 'dismissible' => true
225 ] );
226
227 if ( $this->kbmigration->existing_plugins && ! in_array( $this->kbmigration->existing_plugins[0][0], $this->kbmigration->migrated_plugins ) ) {
228 $migration_message = sprintf(
229 '<p class="migration-message">%s</p><a class="button button-primary betterdocs-migration-notice" href="%s">%s</a>',
230 __(
231 sprintf(
232 'Already using %s? Power up your Knowledge Base by migrating all your docs, settings to BetterDocs with just 1 click.',
233 '<strong>' . esc_html($this->kbmigration->existing_plugins[0][1]) . '</strong>',
234 '<strong>' . esc_html($this->kbmigration->existing_plugins[0][1]) . '</strong>'
235 ),
236 'betterdocs'
237 ),
238 esc_url(admin_url('admin.php?page=betterdocs-settings&tab=tab-migration')),
239 __('Start Migration', 'betterdocs')
240 );
241
242 $_migration_notice = [
243 'thumbnail' => '',
244 'html' => $migration_message,
245 'links' => [
246 'maybe_later' => [
247 'label' => __( 'Maybe Later', 'betterdocs' ),
248 'icon_class' => 'dashicons dashicons-calendar-alt',
249 'attributes' => [
250 'data-later' => true,
251 'class' => 'dismiss-btn'
252 ]
253 ],
254 'never_show_again' => [
255 'label' => __( 'Never show again', 'betterdocs' ),
256 'icon_class' => 'dashicons dashicons-dismiss',
257 'attributes' => [
258 'data-dismiss' => true
259 ]
260 ]
261 ]
262 ];
263
264 $notices->add( 'migration', $_migration_notice, [
265 'start' => $notices->time(),
266 'recurrence' => false,
267 'dismissible' => true,
268 'display_if' => current_user_can( 'delete_users' )
269 ] );
270 }
271
272 /**
273 * Opt-In Notice
274 */
275 if ( $this->insights != null ) {
276 $notices->add( 'opt_in', [ $this->insights, 'notice' ], [
277 'classes' => 'updated put-dismiss-notice',
278 'start' => $notices->strtotime( '+20 days' ),
279 'dismissible' => true,
280 'do_action' => 'wpdeveloper_notice_clicked_for_betterdocs',
281 'display_if' => ! function_exists( 'betterdocs_pro' )
282 ] );
283 }
284
285 $b_message = '<p style="margin-top: 0; margin-bottom: 10px;">Black Friday Sale: Enjoy 40% off & unlock <strong>premium features to streamline customer support</strong> & knowledge base 🎁</p><a class="button button-primary" href="https://wpdeveloper.com/upgrade/betterdocs-bfcm" target="_blank">Upgrade to pro</a> <button data-dismiss="true" class="dismiss-btn button button-link">I don’t want to save money</button>';
286 $_black_friday_notice = [
287 'thumbnail' => $this->assets->icon( 'betterdocs-logo.svg', true ),
288 'html' => $b_message,
289 ];
290
291 $notices->add( 'black_friday_notice', $_black_friday_notice, [
292 'start' => $notices->time(),
293 'recurrence' => false,
294 'dismissible' => true,
295 'refresh' => BETTERDOCS_VERSION,
296 "expire" => strtotime( '11:59:59pm 2nd December, 2023' ),
297 'display_if' => ! is_plugin_active( 'betterdocs-pro/betterdocs-pro.php' )
298 ] );
299
300 self::$cache_bank->create_account( $notices );
301 self::$cache_bank->calculate_deposits( $notices );
302 }
303
304 public function body_classes( $classes ) {
305 $saved_settings = get_option( 'betterdocs_settings', false );
306 $dark_mode = isset( $saved_settings['dark_mode'] ) ? $saved_settings['dark_mode'] : false;
307 $dark_mode = ! empty( $dark_mode ) ? boolval( $dark_mode ) : false;
308
309 if ( $dark_mode === true ) {
310 $classes .= ' betterdocs-dark-mode ';
311 }
312
313 return $classes;
314 }
315
316 /**
317 * Remove Comments Column From List Table
318 *
319 * @param array $columns
320 *
321 * @return array
322 * @since 1.0.0
323 */
324 public function set_custom_edit_action_columns( $columns ) {
325 unset( $columns['comments'] );
326 $new_columns = [];
327 foreach ( $columns as $key => $value ) {
328 if ( $key == 'date' ) {
329 $new_columns['betterdocs_word_count'] = __( 'Word Count', 'betterdocs' ); // put the tags column before it
330 $new_columns['betterdocs_reaction'] = __( 'Reactions', 'betterdocs' );
331 }
332 $new_columns[ $key ] = $value;
333 }
334
335 return $new_columns;
336 }
337
338 public function manage_custom_columns( $column, $post_id ) {
339 global $wpdb;
340 switch ( $column ) {
341 case 'betterdocs_word_count':
342 $word_count = str_word_count( trim( strip_tags( get_post_field( 'post_content', $post_id ) ) ) );
343 echo '<span>' . $word_count . '</span>';
344 break;
345 case 'betterdocs_reaction' :
346 $where = "WHERE post_id='" . esc_sql($post_id) . "'";
347 $analytics = $wpdb->get_results(
348 "SELECT
349 sum(impressions) as totalViews,
350 sum(unique_visit) as totalUniqueViews,
351 sum(happy + sad + normal) as totalReactions,
352 sum(happy) as totalHappy,
353 sum(normal) as totalNormal,
354 sum(sad) as totalSad
355 FROM {$wpdb->prefix}betterdocs_analytics
356 $where"
357 );
358 //echo '<span>'. ($analytics[0]->totalHappy != NULL ? $analytics[0]->totalHappy : 0) .'</span>';
359 // var_dump($analytics);
360 echo '<ul class="reactions-count">
361 <li>
362 <a title="happy" class="betterdocs-feelings happy" data-feelings="happy" href="#">
363 <svg width="15" height="15" version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 20 20" style="enable-background:new 0 0 20 20;" xml:space="preserve">
364 <path class="st0" d="M10,0.1c-5.4,0-9.9,4.4-9.9,9.8c0,5.4,4.4,9.9,9.8,9.9c5.4,0,9.9-4.4,9.9-9.8C19.9,4.5,15.4,0.1,10,0.1z
365 M13.3,6.4c0.8,0,1.5,0.7,1.5,1.5c0,0.8-0.7,1.5-1.5,1.5c-0.8,0-1.5-0.7-1.5-1.5C11.8,7.1,12.5,6.4,13.3,6.4z M6.7,6.4
366 c0.8,0,1.5,0.7,1.5,1.5c0,0.8-0.7,1.5-1.5,1.5c-0.8,0-1.5-0.7-1.5-1.5C5.2,7.1,5.9,6.4,6.7,6.4z M10,16.1c-2.6,0-4.9-1.6-5.8-4
367 l1.2-0.4c0.7,1.9,2.5,3.2,4.6,3.2s3.9-1.3,4.6-3.2l1.2,0.4C14.9,14.5,12.6,16.1,10,16.1z" />
368 <path class="st1" d="M-6.6-119.7c-7.1,0-12.9,5.8-12.9,12.9s5.8,12.9,12.9,12.9s12.9-5.8,12.9-12.9S0.6-119.7-6.6-119.7z
369 M-2.3-111.4c1.1,0,2,0.9,2,2c0,1.1-0.9,2-2,2c-1.1,0-2-0.9-2-2C-4.3-110.5-3.4-111.4-2.3-111.4z M-10.9-111.4c1.1,0,2,0.9,2,2
370 c0,1.1-0.9,2-2,2c-1.1,0-2-0.9-2-2C-12.9-110.5-12-111.4-10.9-111.4z M-6.6-98.7c-3.4,0-6.4-2.1-7.6-5.3l1.6-0.6
371 c0.9,2.5,3.3,4.2,6,4.2s5.1-1.7,6-4.2L1-104C-0.1-100.8-3.2-98.7-6.6-98.7z" />
372 </svg>
373 <span>'. ($analytics[0]->totalHappy != NULL ? $analytics[0]->totalHappy : 0) .'</span>
374 </a>
375 </li>
376 <li>
377 <a title="normal" class="betterdocs-feelings normal" data-feelings="normal" href="#">
378 <svg width="15" height="15" version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 20 20" style="enable-background:new 0 0 20 20;" xml:space="preserve">
379 <path class="st0" d="M10,0.2c-5.4,0-9.8,4.4-9.8,9.8s4.4,9.8,9.8,9.8s9.8-4.4,9.8-9.8S15.4,0.2,10,0.2z M6.7,6.5
380 c0.8,0,1.5,0.7,1.5,1.5c0,0.8-0.7,1.5-1.5,1.5C5.9,9.5,5.2,8.9,5.2,8C5.2,7.2,5.9,6.5,6.7,6.5z M14.2,14.3H5.9
381 c-0.3,0-0.6-0.3-0.6-0.6c0-0.3,0.3-0.6,0.6-0.6h8.3c0.3,0,0.6,0.3,0.6,0.6C14.8,14,14.5,14.3,14.2,14.3z M13.3,9.5
382 c-0.8,0-1.5-0.7-1.5-1.5c0-0.8,0.7-1.5,1.5-1.5c0.8,0,1.5,0.7,1.5,1.5C14.8,8.9,14.1,9.5,13.3,9.5z" />
383 </svg>
384 <span>'. ($analytics[0]->totalNormal != NULL ? $analytics[0]->totalNormal : 0) .'</span>
385 </a>
386 </li>
387 <li>
388 <a title="sad" class="betterdocs-feelings sad" data-feelings="sad" href="#">
389 <svg width="15" height="15" version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 20 20" style="enable-background:new 0 0 20 20;" xml:space="preserve">
390 <circle class="st0" cx="27.5" cy="0.6" r="1.9" />
391 <circle class="st0" cx="36" cy="0.6" r="1.9" />
392 <path class="st1" d="M10,0.3c-5.4,0-9.8,4.4-9.8,9.8s4.4,9.8,9.8,9.8s9.8-4.4,9.8-9.8S15.4,0.3,10,0.3z M13.3,6.6
393 c0.8,0,1.5,0.7,1.5,1.5c0,0.8-0.7,1.5-1.5,1.5c-0.8,0-1.5-0.7-1.5-1.5C11.8,7.3,12.4,6.6,13.3,6.6z M6.7,6.6c0.8,0,1.5,0.7,1.5,1.5
394 c0,0.8-0.7,1.5-1.5,1.5C5.9,9.6,5.2,9,5.2,8.1C5.2,7.3,5.9,6.6,6.7,6.6z M14.1,15L14.1,15c-0.2,0-0.4-0.1-0.5-0.2
395 c-0.9-1-2.2-1.7-3.7-1.7s-2.8,0.6-3.7,1.7C6.2,14.9,6,15,5.9,15h0c-0.6,0-0.8-0.6-0.5-1.1c1.1-1.3,2.8-2.1,4.6-2.1
396 c1.8,0,3.5,0.8,4.6,2.1C15,14.3,14.7,15,14.1,15z" />
397 </svg>
398 <span>'. ($analytics[0]->totalSad != NULL ? $analytics[0]->totalSad : 0) .'</span>
399 </a>
400 </li>
401 </ul>';
402 break;
403 }
404 }
405
406 /**
407 * Enqueue Assets for Admin ( Styles )
408 *
409 * @param string $hook
410 *
411 * @return void
412 * @since 1.0.0
413 */
414 public function styles( $hook ) {
415 $this->assets->enqueue( 'betterdocs-global', 'admin/css/global.css', [], 'all' );
416
417 if ( ! in_array( $hook, [
418 'toplevel_page_betterdocs-admin',
419 'betterdocs_page_betterdocs-settings',
420 'betterdocs_page_betterdocs-analytics'
421 ] ) ) {
422 return;
423 }
424
425 $this->assets->enqueue( 'betterdocs-select2', 'vendor/css/select2.min.css', [], 'all' );
426 $this->assets->enqueue( 'betterdocs-daterangepicker', 'vendor/css/daterangepicker.css', [], 'all' );
427 $this->assets->enqueue( 'betterdocs-icons', 'admin/btd-icon/style.css' );
428 $this->assets->enqueue( 'betterdocs', 'admin/css/betterdocs.css', [], 'all' );
429 }
430
431 /**
432 * Enqueue Assets for Admin ( Scripts )
433 *
434 * @param string $hook
435 *
436 * @return void
437 * @since 1.0.0
438 */
439 public function scripts( $hook ) {
440 $this->assets->register( 'betterdocs-admin', 'admin/js/betterdocs.js', [ 'jquery', 'jquery-ui-sortable' ] );
441
442 $saved_settings = get_option( 'betterdocs_settings', false );
443 $dark_mode = isset( $saved_settings['dark_mode'] ) ? $saved_settings['dark_mode'] : false;
444 $dark_mode = ! empty( $dark_mode ) ? boolval( $dark_mode ) : false;
445 $this->assets->localize( 'betterdocs-admin', 'betterdocs_admin', [
446 'ajaxurl' => admin_url( 'admin-ajax.php' ),
447 'doc_cat_order_nonce' => wp_create_nonce( 'doc_cat_order_nonce' ),
448 'knowledge_base_order_nonce' => wp_create_nonce( 'knowledge_base_order_nonce' ),
449 'paged' => isset( $_GET['paged'] ) ? absint( wp_unslash( $_GET['paged'] ) ) : 0,
450 'per_page_id' => "edit_doc_category_per_page",
451 'menu_title' => __( 'Switch to BetterDocs UI', 'betterdocs' ),
452 'dark_mode' => ! empty( $dark_mode ) ? boolval( $dark_mode ) : false,
453 'text' => __( 'Copied!', 'betterdocs' ),
454 'test_report' => __( 'Test Report!', 'betterdocs' ),
455 'sending' => __( 'Sending...', 'betterdocs' ),
456 'generate_data_url' => get_rest_url( null, '/betterdocs/v1/create-sample-docs' ),
457 'nonce' => wp_create_nonce( 'wp_rest' )
458 ] );
459
460 if ( ( $hook === 'edit.php' || $hook === 'toplevel_page_betterdocs-admin' ) && get_post_type() == 'docs' ) {
461 $this->assets->enqueue( 'betterdocs-switcher', 'admin/js/switcher.js', [
462 'jquery'
463 ] );
464
465 $this->assets->localize( 'betterdocs-switcher', 'betterdocsSwitcher', [
466 'menu_title' => __( 'Switch to BetterDocs UI', 'betterdocs' ),
467 'site_address' => get_bloginfo( 'url' ),
468 'betterdocs_pro_plugin' => betterdocs()->is_pro_active()
469 ] );
470 }
471
472 if ( ! in_array( $hook, [ 'toplevel_page_betterdocs-admin', 'betterdocs_page_betterdocs-analytics' ] ) ) {
473 return;
474 }
475
476 wp_enqueue_script( 'wp-color-picker' );
477
478 $this->assets->enqueue( 'betterdocs-select2', 'vendor/js/select2.min.js', [] );
479 $this->assets->enqueue( 'betterdocs-sweetalert', 'vendor/js/sweetalert.min.js', [] );
480 $this->assets->enqueue( 'moment', 'vendor/js/moment.min.js', [] );
481 $this->assets->enqueue( 'betterdocs-daterangepicker', 'vendor/js/daterangepicker.min.js', [] );
482 wp_enqueue_script( 'betterdocs-admin' );
483 }
484
485 /**
486 * All admin pages header
487 *
488 * @return void
489 * @since 1.0.0
490 */
491 public function header( $admin_tab_name ) {
492 $quick_links = [
493 'switch_view' => sprintf( '<a href="%s" class="betterdocs-button betterdocs-button-secondary">%s</a>', add_query_arg( [
494 'post_type' => 'docs',
495 'bdocs_view' => 'classic'
496 ], 'edit.php' ), __( 'Switch to Classic UI', 'betterdocs' ) ),
497 'add_new_doc' => sprintf( '<a href="%s" class="betterdocs-button betterdocs-button-primary">%s</a>', add_query_arg( [ 'post_type' => 'docs' ], 'post-new.php' ), __( 'Add New Doc', 'betterdocs' ) )
498 ];
499
500 $quick_links = apply_filters( 'betterdocs_quick_links', $quick_links );
501
502 betterdocs()->views->get( 'admin/header', [
503 'quick_links' => $quick_links,
504 'active_tab' => $admin_tab_name
505 ] );
506 }
507
508 /**
509 * Register all the menus for BetterDocs
510 *
511 * @return void
512 * @since 1.0.0
513 */
514 // public function menus() {
515 // add_menu_page(
516 // 'BetterDocs',
517 // 'BetterDocs',
518 // 'edit_posts',
519 // $this->slug,
520 // [$this, 'output'],
521 // betterdocs()->assets->icon( 'betterdocs-icon-white.svg', true ),
522 // 5 // Position on the menu (use a unique number)
523 // );
524 // }
525
526 public function menus() {
527 $default_args = [
528 'page_title' => 'BetterDocs',
529 'menu_title' => 'BetterDocs',
530 'capability' => 'edit_posts',
531 'menu_slug' => $this->slug,
532 'callback' => [ $this, 'output' ],
533 'icon_url' => betterdocs()->assets->icon( 'betterdocs-icon-white.svg', true ),
534 'position' => 5
535 ];
536
537 $_menu_position = 5;
538
539 foreach ( $this->menu_list() as $key => $value ) {
540 if ( $key === 'betterdocs' ) {
541 $callable = 'add_menu_page';
542 $value = wp_parse_args( $value, $default_args );
543 } else {
544 $callable = 'add_submenu_page';
545 $default_args['callback'] = '';
546 $default_args['position'] = $_menu_position;
547 unset( $default_args['icon_url'] );
548 $value = wp_parse_args( $value, array_merge( [ 'parent_slug' => $this->slug ], $default_args ) );
549 }
550
551 $_menu_position++;
552
553 call_user_func_array( $callable, $value );
554 }
555 }
556
557 /**
558 * BetterDocs Admin Page Output
559 *
560 * @return void
561 * @since 1.0.0
562 */
563 public function output() {
564 betterdocs()->views->get( 'admin/main', [
565 'admin_ui' => 'dnd'
566 ] );
567 }
568
569 /**
570 * Menu creator helper
571 *
572 * @param string $title
573 * @param string $slug
574 * @param string $cap
575 * @param array $callback
576 *
577 * @return array
578 * @since 2.5.0
579 *
580 */
581 private function normalize_menu( $title, $slug, $cap = 'edit_docs', $callback = null ) {
582 return Helper::normalize_menu( $title, $slug, $cap, $callback );
583 }
584
585 /**
586 * BetterDocs Menu List
587 *
588 * @return array
589 * @since 1.0.0
590 */
591 private function menu_list() {
592 $betterdocs_admin_pages = [
593 'betterdocs' => [
594 'menu_slug' => $this->slug,
595 'page_title' => 'BetterDocs',
596 'menu_title' => 'BetterDocs',
597 'capability' => 'edit_docs',
598 'callback' => [ $this, 'output' ],
599 'icon_url' => betterdocs()->assets->icon( 'betterdocs-icon-white.svg', true ),
600 'position' => 5
601 ],
602 'all_docs' => $this->normalize_menu( __( 'All Docs', 'betterdocs' ), $this->ui_slug() ),
603 'add_new' => $this->normalize_menu( __( 'Add New', 'betterdocs' ), 'post-new.php?post_type=docs' ),
604 'categories' => $this->normalize_menu(
605 __( 'Categories', 'betterdocs' ),
606 'edit-tags.php?taxonomy=doc_category&post_type=docs',
607 'manage_doc_terms'
608 ),
609 'tags' => $this->normalize_menu(
610 __( 'Tags', 'betterdocs' ),
611 'edit-tags.php?taxonomy=doc_tag&post_type=docs',
612 'manage_doc_terms'
613 ),
614 'settings' => $this->normalize_menu(
615 __( 'Settings', 'betterdocs' ),
616 'betterdocs-settings',
617 'edit_docs_settings',
618 [$this->container->get( Settings::class ), 'views']
619 ),
620 'analytics' => $this->normalize_menu(
621 __( 'Analytics', 'betterdocs' ),
622 'betterdocs-analytics',
623 'read_docs_analytics',
624 [$this->container->get( Analytics::class ), 'views']
625 ),
626 'faq' => $this->normalize_menu(
627 __( 'FAQ Builder', 'betterdocs' ),
628 'betterdocs-faq',
629 'read_docs_analytics',
630 [$this->faq_builder, 'output']
631 )
632 ];
633
634 return apply_filters( 'betterdocs_admin_menu', $betterdocs_admin_pages );
635 }
636
637 public function quick_setup_menu( $menus ) {
638 $betterdocs_settings = get_option( 'betterdocs_settings' );
639 if ( $betterdocs_settings ) {
640 return $menus;
641 } else {
642 $menus['quick_setup'] = $this->normalize_menu( __( 'Quick Setup', 'betterdocs' ), 'betterdocs-setup', 'delete_users', [
643 $this->container->get( SetupWizard::class ),
644 'views'
645 ] );
646 }
647
648 return $menus;
649 }
650
651 public function insert_plugin_links( $links ) {
652 $links[] = '<a href="admin.php?page=betterdocs-settings">' . __( 'Settings', 'betterdocs' ) . '</a>';
653
654 return $links;
655 }
656
657 public function toolbar_menu( $admin_bar ) {
658 if ( ! is_admin() || ! is_admin_bar_showing() ) {
659 return;
660 }
661
662 // Show only when the user is a member of this site, or they're a super admin.
663 if ( ! is_user_member_of_blog() && ! is_super_admin() ) {
664 return;
665 }
666
667 $docs_url = '';
668
669 if ( $this->settings->get( 'builtin_doc_page' ) ) {
670 $docs_url = get_post_type_archive_link( 'docs' );
671 } elseif ( intval( $docs_page = $this->settings->get( 'docs_page' ) ) ) {
672 $docs_url = ! empty( $docs_page ) ? get_page_link( $docs_page ) : false;
673 }
674
675 if ( ! $docs_url ) {
676 return;
677 }
678
679 $admin_bar->add_node( [
680 'parent' => 'site-name',
681 'id' => 'view-docs',
682 'title' => __( 'Visit Documentation', 'betterdocs' ),
683 'href' => $docs_url
684 ] );
685 }
686 /**
687 * Save last visited admin ui
688 *
689 * @since 3.0.1
690 *
691 */
692 public function save_admin_page() {
693 if (isset($_GET['post_type']) && $_GET['post_type'] === 'docs' && isset($_GET['bdocs_view']) && $_GET['bdocs_view'] === 'classic') {
694 update_user_meta( get_current_user_id(), 'last_visited_docs_admin_page', 'classic_ui' );
695 } elseif (isset($_GET['page']) && $_GET['page'] === 'betterdocs-admin') {
696 update_user_meta( get_current_user_id(), 'last_visited_docs_admin_page', 'modern_ui' );
697 }
698 }
699
700 /**
701 * Return last visited admin ui slug
702 *
703 * @since 3.0.1
704 * @return string
705 */
706 public function ui_slug() {
707 $last_visited = get_user_meta( get_current_user_id(), 'last_visited_docs_admin_page', true);
708 $docs = get_posts( ['post_type' => 'docs', 'post_status' => 'any', 'numberposts' => -1] );
709
710 if ($last_visited === 'modern_ui' || count($docs) == 0 ) {
711 $slug = 'betterdocs-admin';
712 } else {
713 $slug = admin_url('edit.php?post_type=docs&bdocs_view=classic');
714 }
715
716 return $slug;
717 }
718
719 /**
720 * Resets a duplicate submenu in WordPress if the parent main menu and the first submenu permalink are not the same.
721 *
722 * @since 3.0.1
723 * @return string
724 */
725 public function reset_submenu() {
726 global $submenu;
727
728 $docs = get_posts( ['post_type' => 'docs'] );
729 if ( count($docs) == 0 ) {
730 return;
731 }
732
733 $last_visited = get_user_meta( get_current_user_id(), 'last_visited_docs_admin_page', true);
734
735 if ($last_visited === 'classic_ui' && isset($submenu['betterdocs-admin']) && in_array("betterdocs-admin", $submenu['betterdocs-admin'][0])) {
736 unset($submenu['betterdocs-admin'][0]);
737 $submenu['betterdocs-admin'] = array_values($submenu['betterdocs-admin']);
738 }
739 }
740 }
741