PluginProbe ʕ •ᴥ•ʔ
Admin Help Docs / 2.0.0.1
Admin Help Docs v2.0.0.1
2.0.1.1 trunk 1.4.3.2 2.0.0 2.0.0.1 2.0.0.2 2.0.1
admin-help-docs / inc / post-type-help-docs.php
admin-help-docs / inc Last commit date
css 3 months ago docs 3 months ago img 3 months ago js 3 months ago tabs 3 months ago api.php 3 months ago cleanup.php 3 months ago colors.php 3 months ago deprecated.php 3 months ago header.php 3 months ago helpers.php 3 months ago index.php 3 months ago menu.php 3 months ago plugins-page.php 3 months ago post-type-help-doc-imports.php 3 months ago post-type-help-docs.php 3 months ago shortcodes.php 3 months ago taxonomy-folders.php 3 months ago
post-type-help-docs.php
1221 lines
1 <?php
2 /**
3 * Help Docs post type (Manage Tab)
4 */
5
6 namespace PluginRx\AdminHelpDocs;
7
8 if ( ! defined( 'ABSPATH' ) ) exit;
9
10 class HelpDocs {
11
12 /**
13 * Post type slug
14 *
15 * @var string
16 */
17 public static $post_type = 'help-docs';
18
19
20 /**
21 * Get available site locations for displaying help docs
22 *
23 * @return array
24 */
25 public static function site_locations() {
26 $cache_key = 'helpdocs_loc_' . get_current_user_id();
27 $cached = get_transient( $cache_key );
28
29 if ( false !== $cached && is_array( $cached ) ) {
30 return apply_filters( 'helpdocs_site_locations', $cached );
31 }
32
33 $locations = [
34 'main' => [
35 'label' => __( 'Main Documentation Page', 'admin-help-docs' ),
36 'fields' => [ 'order', 'toc' ]
37 ],
38 'admin_bar' => [
39 'label' => __( 'Admin Bar Menu (Must Be Enabled in Settings)', 'admin-help-docs' ),
40 'fields' => [ 'order', 'admin_bar_tips' ]
41 ],
42 'update-core.php' => [
43 'label' => __( 'Updates Page', 'admin-help-docs' ),
44 'fields' => [ 'page_location', 'page_location:element:css_selector' ]
45 ],
46 'replace_dashboard' => [
47 'label' => __( 'WordPress Dashboard (Replaces Dashboard Entirely)', 'admin-help-docs' ),
48 'fields' => [ 'dashboard_warning' ]
49 ],
50 'index.php' => [
51 'label' => __( 'WordPress Dashboard Widget', 'admin-help-docs' ),
52 'fields' => []
53 ],
54 'function' => [
55 'label' => __( 'Function: admin_help_doc( id )', 'admin-help-docs' ),
56 'fields' => [ 'function_example' ]
57 ],
58 'post.php' => [
59 'label' => __( 'Post/Page Edit Screen', 'admin-help-docs' ),
60 'fields' => [ 'page_location', 'post_types', 'page_location:element:css_selector' ]
61 ],
62 'edit.php' => [
63 'label' => __( 'Post/Page Admin List Screen', 'admin-help-docs' ),
64 'fields' => [ 'page_location', 'post_types', 'page_location:element:css_selector' ]
65 ]
66 ];
67
68 global $menu, $submenu;
69 $fetching_all_locations = false;
70
71 if ( ! empty( $menu ) && is_array( $menu ) ) {
72 $fetching_all_locations = true;
73
74 $site_location_names = apply_filters( 'helpdocs_location_names', [
75 'edit-comments.php' => __( 'Comments', 'admin-help-docs' ),
76 'site-editor.php' => __( 'Editor', 'admin-help-docs' ),
77 'plugins.php' => __( 'Plugins', 'admin-help-docs' ),
78 'dev-debug-tools' => 'Dev Debug Tools',
79 'admin.php?page=dev-debug-tools&tool=logs' => __( 'Logs', 'admin-help-docs' )
80 ] );
81
82 $textdomain = Bootstrap::textdomain();
83 $admin_url = Bootstrap::admin_url();
84
85 foreach ( $menu as $m ) {
86
87 // Skip separators
88 if ( str_starts_with( $m[2], 'separator' ) || $m[2] == 'hp_separator' || ( isset( $m[4] ) && strpos( $m[4], 'wp-menu-separator' ) !== false ) ) {
89 continue;
90 }
91
92 // Skip dashboard and help topics
93 if ( $m[2] == 'index.php' || $m[2] == $textdomain ) {
94 continue;
95 }
96
97 // Skip post types
98 if ( str_starts_with( $m[2], 'edit.php' ) ) {
99 continue;
100 }
101
102 // Change option names
103 if ( array_key_exists( $m[2], $site_location_names ) ) {
104 $site_location_name = $site_location_names[ $m[2] ];
105 } else {
106 $site_location_name = $m[0];
107 }
108
109 // Strip html
110 $site_location_name = self::strip_admin_menu_counters( $site_location_name );
111
112 // Add the parent location
113 if ( ! array_key_exists( $m[2], $submenu ) ) {
114
115 $url = self::get_admin_menu_item_url( $m[2] );
116 if ( is_null( $url ) ) {
117 $url = 'not found';
118 }
119
120 $url = str_replace( $admin_url, '', $url );
121
122 $locations[ $url ] = [
123 'label' => $site_location_name,
124 'fields' => [ 'page_location', 'page_location:element:css_selector' ]
125 ];
126 }
127
128 // Check for sub menu items
129 foreach ( $submenu as $k => $sub ) {
130
131 if ( $k == $m[2] ) {
132 foreach ( $sub as $s ) {
133
134 if ( array_key_exists( $s[2], $site_location_names ) ) {
135 $sublocation_name = $site_location_names[ $s[2] ];
136 } else {
137 $sublocation_name = $s[0];
138 }
139
140 $sublocation_name = self::strip_admin_menu_counters( $sublocation_name );
141
142 $url = self::get_admin_menu_item_url( $s[2] );
143 if ( is_null( $url ) ) {
144 $url = 'not found';
145 }
146
147 $url = str_replace( $admin_url, '', $url );
148
149 $locations[ $url ] = [
150 'label' => $site_location_name . ' > ' . $sublocation_name,
151 'fields' => [ 'page_location', 'page_location:element:css_selector' ]
152 ];
153 }
154 }
155 }
156 }
157 }
158
159 // Add a custom link option to the bottom
160 $locations[ 'custom' ] = [
161 'label' => __( 'Other/Custom Page', 'admin-help-docs' ),
162 'fields' => [ 'custom', 'addt_params', 'page_location', 'page_location:element:css_selector' ]
163 ];
164
165 // Cache the result for 1 hour
166 if ( $fetching_all_locations ) {
167 set_transient( $cache_key, $locations, 12 * HOUR_IN_SECONDS );
168 }
169
170 return apply_filters( 'helpdocs_site_locations', $locations );
171 } // End site_locations()
172
173
174 /**
175 * Get available page locations for displaying help docs
176 *
177 * @return array
178 */
179 public static function page_locations() {
180 $locations = [
181 'contextual' => __( 'Contextual Help Tab (At Top of Screen)', 'admin-help-docs' ),
182 'top' => __( 'Top', 'admin-help-docs' ),
183 'bottom' => __( 'Bottom', 'admin-help-docs' ),
184 'side' => __( 'Side', 'admin-help-docs' ),
185 'element' => __( 'Next to Specific Element (Beta)', 'admin-help-docs' ),
186 ];
187
188 return apply_filters( 'helpdocs_page_locations', $locations );
189 } // End page_locations()
190
191
192 /**
193 * Get available post types for displaying help docs
194 *
195 * @return array
196 */
197 public static function post_types() {
198 return array_merge( [ 'post' => 'post', 'page' => 'page' ], get_post_types( [ '_builtin' => false ] ) );
199 } // End post_types()
200
201
202 /**
203 * The single instance of the class
204 *
205 * @var self|null
206 */
207 private static ?HelpDocs $instance = null;
208
209
210 /**
211 * Get the singleton instance
212 *
213 * @return self
214 */
215 public static function instance() : self {
216 return self::$instance ??= new self();
217 } // End instance()
218
219
220 /**
221 * HelpDocs constructor.
222 *
223 * Private to enforce singleton pattern.
224 */
225 private function __construct() {
226
227 // Register the post type
228 add_action( 'init', [ $this, 'register_post_type' ] );
229
230 // Add the header to the top of the admin list page
231 add_action( 'load-edit.php', [ $this, 'add_header' ] );
232
233 // Move the search box to the subheader
234 add_action( 'helpdocs_subheader_right', [ $this, 'render_search_box' ] );
235
236 // Add the meta box
237 add_action( 'add_meta_boxes', [ $this, 'meta_boxes' ], 999 );
238
239 // Rename excerpt meta box
240 add_filter( 'gettext', [ $this, 'excerpt_meta_box' ], 10, 2 );
241
242 // Save the post data
243 add_action( 'save_post', [ $this, 'save_post' ] );
244 add_action( 'before_delete_post', [ $this, 'delete_post' ] );
245
246 // Add admin columns
247 add_filter( 'manage_' . self::$post_type . '_posts_columns', [ $this, 'admin_columns' ] );
248 add_action( 'manage_' . self::$post_type . '_posts_custom_column', [ $this, 'admin_column_content' ], 10, 2 );
249
250 // Either enqueue block editor styles or disable block editor
251 if ( ! get_option( 'helpdocs_gutenberg_editor' ) ) {
252 add_filter( 'use_block_editor_for_post_type', [ $this, 'disable_gutenberg' ], 10, 2 );
253 }
254
255 // Enqueue back-end styles
256 add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_admin_styles' ] );
257
258 } // End __construct()
259
260
261 /**
262 * Register the post type
263 */
264 public function register_post_type() {
265 // Set the labels
266 $labels = [
267 'name' => _x( 'Help Documents', 'Post Type General Name', 'admin-help-docs' ),
268 'singular_name' => _x( 'Help Document', 'Post Type Singular Name', 'admin-help-docs' ),
269 'menu_name' => __( 'Help Documents', 'admin-help-docs' ),
270 'name_admin_bar' => __( 'Help Documents', 'admin-help-docs' ),
271 'archives' => __( 'Help Document Archives', 'admin-help-docs' ),
272 'attributes' => __( 'Help Document Attributes', 'admin-help-docs' ),
273 'parent_item_colon' => __( 'Parent Help Document:', 'admin-help-docs' ),
274 'all_items' => __( 'All Help Documents', 'admin-help-docs' ),
275 'add_new_item' => __( 'Add New Help Document', 'admin-help-docs' ),
276 'add_new' => __( 'Add New', 'admin-help-docs' ),
277 'new_item' => __( 'New Help Document', 'admin-help-docs' ),
278 'edit_item' => __( 'Edit Help Document', 'admin-help-docs' ),
279 'update_item' => __( 'Update Help Document', 'admin-help-docs' ),
280 'view_item' => __( 'View Help Document', 'admin-help-docs' ),
281 'view_items' => __( 'View Help Documents', 'admin-help-docs' ),
282 'search_items' => __( 'Search Help Documents', 'admin-help-docs' ),
283 'not_found' => __( 'Not found', 'admin-help-docs' ),
284 'not_found_in_trash' => __( 'Not found in Trash', 'admin-help-docs' ),
285 'insert_into_item' => __( 'Insert into help document', 'admin-help-docs' ),
286 'uploaded_to_this_item' => __( 'Uploaded to this help document', 'admin-help-docs' ),
287 'items_list' => __( 'Help Document list', 'admin-help-docs' ),
288 'items_list_navigation' => __( 'Help Document list navigation', 'admin-help-docs' ),
289 'filter_items_list' => __( 'Filter help document list', 'admin-help-docs' ),
290 ];
291
292 // Allow filter for supports and taxonomies
293 $supports = apply_filters( 'helpdocs_post_type_supports', [ 'title', 'editor' ] );
294 $taxonomies = apply_filters( 'helpdocs_post_type_taxonomies', [] );
295
296 // Set the CPT args
297 $args = [
298 'label' => __( 'Help Documents', 'admin-help-docs' ),
299 'description' => __( 'Help Documents', 'admin-help-docs' ),
300 'labels' => $labels,
301 'supports' => $supports,
302 'taxonomies' => $taxonomies,
303 'public' => true,
304 'show_ui' => true,
305 'show_in_menu' => false,
306 'show_in_admin_bar' => false,
307 'show_in_nav_menus' => false,
308 'can_export' => true,
309 'has_archive' => false,
310 'exclude_from_search' => true,
311 'publicly_queryable' => false,
312 'query_var' => self::$post_type,
313 'capability_type' => 'post',
314 'show_in_rest' => true,
315 ];
316
317 // Register the CPT
318 register_post_type( self::$post_type, $args );
319 } // End register_post_type()
320
321
322 /**
323 * Add the header to the top of the admin list page
324 *
325 * @return void
326 */
327 public function add_header() {
328 $screen = get_current_screen();
329 if ( 'edit-' . self::$post_type === $screen->id ) {
330 add_action( 'in_admin_header', function() {
331 include Bootstrap::path( 'inc/header.php' );
332 } );
333 }
334 } // End add_header()
335
336
337 /**
338 * Add a search box to the subheader on the folders page
339 *
340 * @param string $current_tab The current admin tab
341 * @return void
342 */
343 public function render_search_box( string $current_tab ) {
344 if ( $current_tab !== 'manage' ) {
345 return;
346 }
347
348 $search_value = sanitize_text_field( wp_unslash( $_GET[ 's' ] ?? '' ) ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended
349 ?>
350 <form method="get" class="helpdocs-posttype-search">
351 <?php foreach ( $_GET as $key => $value ) : // phpcs:ignore WordPress.Security.NonceVerification.Recommended
352 if ( in_array( $key, [ 's', 'action', 'paged' ], true ) ) continue;
353 ?>
354 <input type="hidden" name="<?php echo esc_attr( $key ); ?>" value="<?php echo esc_attr( $value ); ?>" />
355 <?php endforeach; ?>
356
357 <input type="search"
358 name="s"
359 value="<?php echo esc_attr( $search_value ); ?>"
360 placeholder="<?php echo esc_attr__( 'Search Docs', 'admin-help-docs' ); ?>"
361 class="helpdocs-search-input" />
362
363 <input type="submit"
364 class="helpdocs-button"
365 value="<?php echo esc_attr__( 'Search', 'admin-help-docs' ); ?>" />
366
367 <a href="<?php
368 $clear_url = remove_query_arg( 's' );
369 echo esc_url( $clear_url );
370 ?>" class="helpdocs-button">
371 <?php echo esc_html__( 'Clear', 'admin-help-docs' ); ?>
372 </a>
373 </form>
374 <?php
375 } // End render_search_box()
376
377
378 /**
379 * Meta box
380 *
381 * @return void
382 */
383 public function meta_boxes() {
384 global $wp_meta_boxes;
385
386 $screen = get_current_screen();
387 if ( $screen && $screen->post_type === self::$post_type ) {
388
389 // Define the IDs we want to KEEP
390 $whitelist = [
391 'submitdiv', // The Publish box
392 'formatdiv', // Post Formats
393 'categorydiv', // Standard Category box
394 'tagsdiv-post_tag', // Standard Tags box
395 'pageparentdiv', // Page Attributes
396 'postimagediv', // Featured Image
397 'tagsdiv-' . Folders::$taxonomy // Folders taxonomy box
398 ];
399
400 // Loop through all contexts (normal, advanced, side)
401 foreach ( [ 'normal', 'advanced', 'side' ] as $context ) {
402 foreach ( [ 'high', 'core', 'default', 'low' ] as $priority ) {
403
404 if ( ! isset( $wp_meta_boxes[ self::$post_type ][ $context ][ $priority ] ) ) {
405 continue;
406 }
407
408 foreach ( $wp_meta_boxes[ self::$post_type ][ $context ][ $priority ] as $box_id => $box_data ) {
409 // If the box ID is NOT in our whitelist, remove it
410 if ( ! in_array( $box_id, $whitelist ) ) {
411 remove_meta_box( $box_id, self::$post_type, $context );
412 }
413 }
414 }
415 }
416
417 // 2. Now that the deck is clear, add ONLY your meta box
418 add_meta_box(
419 'helpdocs_locations',
420 __( 'Location', 'admin-help-docs' ),
421 [ $this, 'meta_box_content' ],
422 self::$post_type,
423 'advanced',
424 'high'
425 );
426 }
427 } // End meta_boxes()
428
429
430 /**
431 * Rename excerpt meta box as description
432 *
433 * @param string $translation
434 * @param string $original
435 * @return string
436 */
437 public function excerpt_meta_box( $translation, $original ) {
438 // Make sure we are only looking at our post type
439 global $post_type;
440 if ( $post_type != self::$post_type ) {
441 return $translation;
442 }
443
444 // Update the box
445 if ( 'Excerpt' == $original ) {
446 return __( 'Description', 'admin-help-docs' );
447 } elseif ( false !== strpos( $original, 'Excerpts are optional hand-crafted summaries of your' ) ) {
448 return __( 'This is only used to summarize the document for the manage documents list table. If left blank, it will show first couple of lines of the content.', 'admin-help-docs' );
449 }
450 return $translation;
451 } // End excerpt_meta_box()
452
453
454 /**
455 * Meta box content
456 *
457 * @param object $post
458 * @return void
459 */
460 public function meta_box_content( $post ) {
461 wp_nonce_field( 'help_location_nonce', 'help_location_nonce' );
462
463 $locations = get_post_meta( $post->ID, 'helpdocs_locations', true );
464
465 if ( 'auto-draft' === $post->post_status && isset( $_GET[ 'site_location' ] ) ) { // phpcs:ignore
466 $locations = [
467 [
468 'site_location' => sanitize_text_field( wp_unslash( $_GET[ 'site_location' ] ) ), // phpcs:ignore WordPress.Security.NonceVerification.Recommended
469 'page_location' => 'top', // Default to top
470 'custom' => isset( $_GET[ 'custom_url' ] ) ? esc_url_raw( wp_unslash( $_GET[ 'custom_url' ] ) ) : '', // phpcs:ignore WordPress.Security.NonceVerification.Recommended
471 'post_types' => isset( $_GET[ 'slpt' ] ) ? [ sanitize_text_field( wp_unslash( $_GET[ 'slpt' ] ) ) ] : [], // phpcs:ignore WordPress.Security.NonceVerification.Recommended
472 'order' => 0,
473 'toc' => false,
474 'css_selector' => '',
475 'addt_params' => true,
476 ]
477 ];
478 }
479
480 if ( ! is_array( $locations ) || empty( $locations ) ) {
481 // Backward compatibility: use legacy single-location fields
482 $meta = get_post_meta( $post->ID );
483
484 $locations = [
485 [
486 'site_location' => $meta[ 'helpdocs_site_location' ][ 0 ] ?? '',
487 'page_location' => $meta[ 'helpdocs_page_location' ][ 0 ] ?? '',
488 'custom' => $meta[ 'helpdocs_custom' ][ 0 ] ?? '',
489 'addt_params' => ! empty( $meta[ 'helpdocs_addt_params' ][ 0 ] ),
490 'post_types' => isset( $meta[ 'helpdocs_post_types' ][ 0 ] ) ? Helpers::normalize_meta_array( $meta[ 'helpdocs_post_types' ][ 0 ] ) : [],
491 'order' => isset( $meta[ 'helpdocs_order' ][ 0 ] ) ? intval( $meta[ 'helpdocs_order' ][ 0 ] ) : 0,
492 'toc' => isset( $meta[ 'helpdocs_toc' ][ 0 ] ) ? filter_var( $meta[ 'helpdocs_toc' ][ 0 ], FILTER_VALIDATE_BOOLEAN ) : false,
493 'css_selector' => $meta[ 'helpdocs_css_selector' ][ 0 ] ?? '',
494 ]
495 ];
496 }
497
498 // Global fields
499 $meta = get_post_meta( $post->ID );
500 $api = $meta[ 'helpdocs_api' ][ 0 ] ?? '';
501 $view_roles = isset( $meta[ 'helpdocs_view_roles' ][ 0 ] ) ? Helpers::normalize_meta_array( $meta[ 'helpdocs_view_roles' ][ 0 ] ) : [];
502 $roles = Helpers::get_role_options();
503
504 $all_site_locations = self::site_locations();
505 $all_page_locations = self::page_locations();
506 $all_post_types = self::post_types();
507 ?>
508 <!-- Repeater -->
509 <div id="helpdocs-location-repeater">
510 <?php foreach ( $locations as $i => $location ) :
511 $site_location = $location[ 'site_location' ] ?? '';
512 $site_location_decoded = base64_decode( $site_location );
513 $page_location = $location[ 'page_location' ] ?? '';
514 $custom = $location[ 'custom' ] ?? '';
515 $addt_params = ! empty( $location[ 'addt_params' ] );
516 $post_types = $location[ 'post_types' ] ?? [];
517 $order = $location[ 'order' ] ?? 0;
518 $toc = ! empty( $location[ 'toc' ] );
519 $css_selector = $location[ 'css_selector' ] ?? '';
520
521 // Determine which fields to show
522 $fields_to_show = [];
523 if ( isset( $all_site_locations[ $site_location_decoded ][ 'fields' ] ) ) {
524 foreach ( $all_site_locations[ $site_location_decoded ][ 'fields' ] as $f ) {
525 if ( strpos( $f, ':' ) !== false ) {
526 list( $controller, $controller_value, $dependent ) = explode( ':', $f );
527 if ( ( $location[ $controller ] ?? '' ) === $controller_value ) {
528 $fields_to_show[] = $dependent;
529 }
530 } else {
531 $fields_to_show[] = $f;
532 }
533 }
534 }
535 ?>
536 <div class="helpdocs-location-row" style="margin-bottom:15px; padding:10px; border:1px solid #ddd;">
537 <div class="helpdocs-row-main">
538
539 <!-- Site Location -->
540 <?php $id_site = 'helpdocs_locations_' . $i . '_site_location'; ?>
541 <label for="<?php echo esc_attr( $id_site ); ?>"><?php esc_html_e( 'Site Location:', 'admin-help-docs' ); ?></label>
542 <select name="helpdocs_locations[ <?php echo esc_attr( $i ); ?> ][site_location]" id="<?php echo esc_attr( $id_site ); ?>">
543 <option value=""><?php esc_html_e( '-- None --', 'admin-help-docs' ); ?></option>
544 <?php foreach ( $all_site_locations as $key_l => $info ) :
545 $encoded = base64_encode( $key_l );
546 ?>
547 <option value="<?php echo esc_attr( $encoded ); ?>" <?php selected( $encoded, $site_location ); ?>>
548 <?php echo esc_html( $info[ 'label' ] ); ?>
549 </option>
550 <?php endforeach; ?>
551 </select>
552
553 <?php if ( $i > 0 ) : ?>
554 <button type="button" class="remove-location button" title="Remove Location"><span class="dashicons dashicons-trash"></span></button>
555 <?php endif; ?>
556
557 <!-- Page Location -->
558 <?php $id_page = 'helpdocs_locations_' . $i . '_page_location'; ?>
559 <label for="<?php echo esc_attr( $id_page ); ?>" style="display:<?php echo in_array( 'page_location', $fields_to_show ) ? 'block' : 'none'; ?>;">
560 <?php esc_html_e( 'Page Location:', 'admin-help-docs' ); ?>
561 </label>
562 <select name="helpdocs_locations[ <?php echo esc_attr( $i ); ?> ][page_location]" id="<?php echo esc_attr( $id_page ); ?>" style="display:<?php echo in_array( 'page_location', $fields_to_show ) ? 'block' : 'none'; ?>;">
563 <?php foreach ( $all_page_locations as $key_lop => $lop ) : ?>
564 <option value="<?php echo esc_attr( $key_lop ); ?>" <?php selected( $key_lop, $page_location ); ?>>
565 <?php echo esc_html( $lop ); ?>
566 </option>
567 <?php endforeach; ?>
568 </select>
569
570 <!-- Element CSS Selector -->
571 <?php $id_css_selector = 'helpdocs_locations_' . $i . '_css_selector'; ?>
572 <label for="<?php echo esc_attr( $id_css_selector ); ?>" style="display:<?php echo in_array( 'css_selector', $fields_to_show ) ? 'block' : 'none'; ?>;">
573 <?php esc_html_e( 'Element CSS Selector:', 'admin-help-docs' ); ?>
574 </label>
575 <input type="text" name="helpdocs_locations[ <?php echo esc_attr( $i ); ?> ][css_selector]" id="<?php echo esc_attr( $id_css_selector ); ?>" value="<?php echo esc_attr( $css_selector ); ?>" style="display:<?php echo in_array( 'css_selector', $fields_to_show ) ? 'inline-block' : 'none'; ?>;">
576
577 <!-- Order -->
578 <?php $id_order = 'helpdocs_locations_' . $i . '_order'; ?>
579 <label for="<?php echo esc_attr( $id_order ); ?>" style="display:<?php echo in_array( 'order', $fields_to_show ) ? 'block' : 'none'; ?>;">
580 <?php esc_html_e( 'Menu Order:', 'admin-help-docs' ); ?>
581 </label>
582 <input type="number" name="helpdocs_locations[ <?php echo esc_attr( $i ); ?> ][order]" id="<?php echo esc_attr( $id_order ); ?>" value="<?php echo esc_attr( $order ); ?>" style="display:<?php echo in_array( 'order', $fields_to_show ) ? 'inline-block' : 'none'; ?>;">
583
584 <!-- TOC -->
585 <?php $id_toc = 'helpdocs_locations_' . $i . '_toc'; ?>
586 <label style="display:<?php echo in_array( 'toc', $fields_to_show ) ? 'block' : 'none'; ?>;">
587 <input type="checkbox" name="helpdocs_locations[ <?php echo esc_attr( $i ); ?> ][toc]" id="<?php echo esc_attr( $id_toc ); ?>" value="1" <?php checked( $toc ); ?>>
588 <?php esc_html_e( 'Add to Dashboard Table of Contents', 'admin-help-docs' ); ?>
589 </label>
590
591 </div>
592
593 <!-- Function Example -->
594 <?php $id_function = 'helpdocs_locations_' . $i . '_function_example'; ?>
595 <span class="helpdocs-function-example info" id="<?php echo esc_attr( $id_function ); ?>" style="display:<?php echo in_array( 'function_example', $fields_to_show ) ? 'block' : 'none'; ?>;">
596 <?php esc_html_e( 'Developers can use this function to display a specific help document by its ID:', 'admin-help-docs' ); ?> <code>admin_help_doc(<?php echo esc_attr( $post->ID ); ?>);</code>
597 </span>
598
599 <!-- Admin Bar Tips -->
600 <?php $id_function = 'helpdocs_locations_' . $i . '_admin_bar_tips'; ?>
601 <span class="helpdocs-admin-bar-tips info" id="<?php echo esc_attr( $id_function ); ?>" style="display:<?php echo in_array( 'admin_bar_tips', $fields_to_show ) ? 'block' : 'none'; ?>;">
602 <?php esc_html_e( ' To add a quick link to the admin bar, set the title of this help doc to the label and add the link by itself to the content.', 'admin-help-docs' ); ?>
603 </span>
604
605 <!-- Dashboard Warning -->
606 <?php $id_dashboard_warning = 'helpdocs_locations_' . $i . '_dashboard_warning'; ?>
607 <span class="helpdocs-dashboard-warning warning" id="<?php echo esc_attr( $id_dashboard_warning ); ?>" style="display:<?php echo in_array( 'dashboard_warning', $fields_to_show ) ? 'block' : 'none'; ?>;">
608 <?php esc_html_e( 'You must enable "Replace WordPress Dashboard with a Help Doc" in Settings for this to show up. Warning: Replacing the WordPress dashboard entirely may affect other plugins and functionality. No other widgets or dashboard elements will be displayed.', 'admin-help-docs' ); ?>
609 </span>
610
611 <!-- Custom URL -->
612 <div class="helpdocs-custom-url" style="display:<?php echo in_array( 'custom', $fields_to_show ) ? 'block' : 'none'; ?>;">
613 <?php $id_custom = 'helpdocs_locations_' . $i . '_custom'; ?>
614 <label class="helpdocs-custom-label" for="<?php echo esc_attr( $id_custom ); ?>">
615 <?php esc_html_e( 'Custom URL:', 'admin-help-docs' ); ?>
616 </label>
617 <input class="helpdocs-custom" type="text" name="helpdocs_locations[ <?php echo esc_attr( $i ); ?> ][custom]" id="<?php echo esc_attr( $id_custom ); ?>" value="<?php echo esc_attr( $custom ); ?>" style="width:60%; display:<?php echo in_array( 'custom', $fields_to_show ) ? 'inline-block' : 'none'; ?>;">
618
619 <!-- Ignore Params -->
620 <?php $id_addt = 'helpdocs_locations_' . $i . '_addt_params'; ?>
621 <label style="display:<?php echo in_array( 'addt_params', $fields_to_show ) ? 'block' : 'none'; ?>;">
622 <input type="checkbox" name="helpdocs_locations[ <?php echo esc_attr( $i ); ?> ][addt_params]" id="<?php echo esc_attr( $id_addt ); ?>" value="1" <?php checked( $addt_params ); ?>>
623 <?php esc_html_e( 'Ignore Additional Query String Parameters', 'admin-help-docs' ); ?>
624 </label>
625 </div>
626
627 <!-- Post Types -->
628 <?php $id_post_types = 'helpdocs_locations_' . $i . '_post_types'; ?>
629 <div id="<?php echo esc_attr( $id_post_types ); ?>" class="helpdocs-post-types" style="display:<?php echo in_array( 'post_types', $fields_to_show ) ? 'block' : 'none'; ?>;">
630 <div class="helpdocs-checkboxes">
631 <?php foreach ( $all_post_types as $pt ) :
632 $pt_obj = get_post_type_object( $pt );
633 if ( ! $pt_obj || ! $pt_obj->show_ui ) continue;
634 ?>
635 <label>
636 <input type="checkbox" name="helpdocs_locations[ <?php echo esc_attr( $i ); ?> ][post_types][]" value="<?php echo esc_attr( $pt ); ?>" <?php checked( in_array( $pt, $post_types ) ); ?>>
637 <?php echo esc_html( $pt_obj->labels->name ); ?>
638 </label>
639 <?php endforeach; ?>
640 </div>
641 </div>
642
643 </div>
644 <?php endforeach; ?>
645 </div>
646
647 <button type="button" id="add-location" class="button button-primary"><?php esc_html_e( 'Add Location', 'admin-help-docs' ); ?></button>
648
649 <!-- -----------------------------
650 Global Fields
651 ----------------------------- -->
652
653 <div class="helpdocs-global-settings">
654
655 <!-- API -->
656 <div class="helpdocs-api">
657 <?php $id_api = 'helpdocs_api'; ?>
658 <label for="<?php echo esc_attr( $id_api ); ?>"><?php esc_html_e( 'Allow Public:', 'admin-help-docs' ); ?></label>
659 <select name="helpdocs_api" id="<?php echo esc_attr( $id_api ); ?>">
660 <?php
661 $get_default_api = get_option( 'helpdocs_api' );
662 if ( $get_default_api === 'yes' || $get_default_api === true ) {
663 $default_api_choice = 'yes';
664 } else {
665 $default_api_choice = 'no';
666 }
667 $api_choices = [
668 'default' => sprintf( __( 'Default ( %s )', 'admin-help-docs' ), ucwords( $default_api_choice ) ),
669 'no' => __( 'No', 'admin-help-docs' ),
670 'yes' => __( 'Yes', 'admin-help-docs' )
671 ];
672 foreach ( $api_choices as $key_api => $a ) :
673 ?>
674 <option value="<?php echo esc_attr( $key_api ); ?>" <?php selected( $key_api, $api ? $api : 'default' ); ?>>
675 <?php echo esc_html( $a ); ?>
676 </option>
677 <?php endforeach; ?>
678 </select>
679 </div>
680
681 <!-- View Roles -->
682 <div class="helpdocs-view-roles">
683 <label><?php esc_html_e( 'Viewable By Roles:', 'admin-help-docs' ); ?></label>
684 <div class="helpdocs-checkboxes">
685 <?php foreach ( $roles as $role ) : ?>
686 <label>
687 <input type="checkbox" name="helpdocs_view_roles[]" value="<?php echo esc_attr( $role[ 'value' ] ); ?>" <?php checked( in_array( $role[ 'value' ], $view_roles ) ); ?>>
688 <?php echo esc_html( $role[ 'label' ] ); ?>
689 </label>
690 <?php endforeach; ?>
691 </div>
692 </div>
693
694 </div>
695 <?php
696 } // End meta_box_content()
697
698
699 /**
700 * Get menu item url
701 * Snippet courtesy of Mighty Minnow
702 * https://www.mightyminnow.com/2013/12/how-to-get-urls-for-wordpress-admin-menu-items/
703 *
704 * @param [type] $menu_item_file
705 * @param boolean $submenu_as_parent
706 * @return string
707 */
708 public static function get_admin_menu_item_url( $menu_item_file, $submenu_as_parent = true ) {
709 global $menu, $submenu, $self, $typenow;
710
711 $admin_is_parent = false;
712 $item = '';
713 $submenu_item = '';
714 $url = '';
715
716 // 1. Check if top-level menu item
717 foreach( $menu as $key => $menu_item ) {
718 if ( array_keys( $menu_item, $menu_item_file, true ) ) {
719 $item = $menu[ $key ];
720 }
721
722 if ( $submenu_as_parent && ! empty( $submenu_item ) ) {
723 $menu_hook = get_plugin_page_hook( $submenu_item[2], $item[2] );
724 $menu_file = $submenu_item[2];
725
726 if ( false !== ( $pos = strpos( $menu_file, '?' ) ) )
727 $menu_file = substr( $menu_file, 0, $pos );
728 if ( ! empty( $menu_hook ) || ( ( 'index.php' != $submenu_item[2] ) && file_exists( WP_PLUGIN_DIR . "/$menu_file" ) && ! file_exists( ABSPATH . "/wp-admin/$menu_file" ) ) ) {
729 $admin_is_parent = true;
730 $url = 'admin.php?page=' . $submenu_item[2];
731 } else {
732 $url = $submenu_item[2];
733 }
734 }
735
736 elseif ( ! empty( $item[2] ) && current_user_can( $item[1] ) ) {
737 $menu_hook = get_plugin_page_hook( $item[2], 'admin.php' );
738 $menu_file = $item[2];
739
740 if ( false !== ( $pos = strpos( $menu_file, '?' ) ) )
741 $menu_file = substr( $menu_file, 0, $pos );
742 if ( ! empty( $menu_hook ) || ( ( 'index.php' != $item[2] ) && file_exists( WP_PLUGIN_DIR . "/$menu_file" ) && ! file_exists( ABSPATH . "/wp-admin/$menu_file" ) ) ) {
743 $admin_is_parent = true;
744 $url = 'admin.php?page=' . $item[2];
745 } else {
746 $url = $item[2];
747 }
748 }
749 }
750
751 // 2. Check if sub-level menu item
752 if ( ! $item ) {
753 $sub_item = '';
754 foreach( $submenu as $top_file => $submenu_items ) {
755
756 // Reindex $submenu_items
757 $submenu_items = array_values( $submenu_items );
758
759 foreach( $submenu_items as $key => $submenu_item ) {
760 if ( array_keys( $submenu_item, $menu_item_file ) ) {
761 $sub_item = $submenu_items[ $key ];
762 break;
763 }
764 }
765
766 if ( ! empty( $sub_item ) )
767 break;
768 }
769
770 // Get top-level parent item
771 foreach( $menu as $key => $menu_item ) {
772 if ( array_keys( $menu_item, $top_file, true ) ) {
773 $item = $menu[ $key ];
774 break;
775 }
776 }
777
778 // If the $menu_item_file parameter doesn't match any menu item, return false
779 if ( ! $sub_item )
780 return false;
781
782 // Get URL
783 $menu_file = $item[2];
784
785 if ( false !== ( $pos = strpos( $menu_file, '?' ) ) )
786 $menu_file = substr( $menu_file, 0, $pos );
787
788 // Handle current for post_type=post|page|foo pages, which won't match $self.
789 // $self_type = ! empty( $typenow ) ? $self . '?post_type=' . $typenow : 'nothing';
790 $menu_hook = get_plugin_page_hook( $sub_item[2], $item[2] );
791
792 $sub_file = $sub_item[2];
793 if ( false !== ( $pos = strpos( $sub_file, '?' ) ) )
794 $sub_file = substr($sub_file, 0, $pos);
795
796 if ( ! empty( $menu_hook ) || ( ( 'index.php' != $sub_item[2] ) && file_exists( WP_PLUGIN_DIR . "/$sub_file" ) && ! file_exists( ABSPATH . "/wp-admin/$sub_file" ) ) ) {
797 // If admin.php is the current page or if the parent exists as a file in the plugins or admin dir
798 if ( ( ! $admin_is_parent && file_exists( WP_PLUGIN_DIR . "/$menu_file" ) && ! is_dir( WP_PLUGIN_DIR . "/{$item[2]}" ) ) || file_exists( $menu_file ) )
799 $url = add_query_arg( array( 'page' => $sub_item[2] ), $item[2] );
800 else
801 $url = add_query_arg( array( 'page' => $sub_item[2] ), 'admin.php' );
802 } else {
803 $url = $sub_item[2];
804 }
805 }
806
807 return esc_url( $url );
808 } // End get_admin_menu_item_url()
809
810
811 /**
812 * Save the post data
813 *
814 * @param int $post_id
815 * @return void
816 */
817 public function save_post( $post_id ) {
818 // Check nonce and permissions
819 if ( ! Helpers::can_save_post( self::$post_type, 'help_location_nonce', 'help_location_nonce' ) ) {
820 return;
821 }
822
823 $all_site_locations = self::site_locations();
824 $locations_input = isset( $_POST[ 'helpdocs_locations' ] ) ? wp_unslash( $_POST[ 'helpdocs_locations' ] ) : []; // phpcs:ignore
825 $locations = [];
826
827 if ( is_array( $locations_input ) ) {
828 foreach ( $locations_input as $loc ) {
829 if ( empty( $loc[ 'site_location' ] ) ) {
830 continue;
831 }
832
833 $site_key_encoded = sanitize_text_field( $loc[ 'site_location' ] );
834 $site_key_decoded = base64_decode( $site_key_encoded );
835
836 if ( ! isset( $all_site_locations[ $site_key_decoded ] ) ) {
837 continue;
838 }
839
840 $clean = [ 'site_location' => $site_key_encoded ];
841 $allowed_fields = $all_site_locations[ $site_key_decoded ][ 'fields' ] ?? [];
842
843 foreach ( $allowed_fields as $field_rule ) {
844 $field_name = $field_rule;
845 $should_save = true;
846
847 // Handle complex rules (controller:value:dependent)
848 if ( strpos( $field_rule, ':' ) !== false ) {
849 $parts = explode( ':', $field_rule );
850 if ( count( $parts ) === 3 ) {
851 list( $controller, $controller_value, $dependent ) = $parts;
852 $field_name = $dependent;
853
854 // Only save if the controller field matches the required value
855 $current_val = $loc[ $controller ] ?? '';
856 if ( $current_val !== $controller_value ) {
857 $should_save = false;
858 }
859 } else {
860 $field_name = end( $parts );
861 }
862 }
863
864 if ( ! $should_save ) {
865 continue;
866 }
867
868 // If the field isn't in POST, skip it (except post_types which might be empty)
869 if ( ! isset( $loc[ $field_name ] ) && $field_name !== 'post_types' ) {
870 continue;
871 }
872
873 switch ( $field_name ) {
874 case 'order':
875 $clean[ $field_name ] = intval( $loc[ $field_name ] );
876 break;
877
878 case 'toc':
879 case 'addt_params':
880 $clean[ $field_name ] = ! empty( $loc[ $field_name ] );
881 break;
882
883 case 'post_types':
884 $pts = isset( $loc[ 'post_types' ] ) ? (array) $loc[ 'post_types' ] : [];
885 $clean[ $field_name ] = array_map( 'sanitize_key', $pts );
886 break;
887
888 case 'custom':
889 $clean[ $field_name ] = esc_url_raw( $loc[ $field_name ] );
890 break;
891
892 case 'page_location':
893 $clean[ $field_name ] = sanitize_key( $loc[ $field_name ] );
894 break;
895
896 case 'css_selector':
897 $clean[ $field_name ] = sanitize_text_field( $loc[ $field_name ] );
898 break;
899
900 default:
901 $clean[ $field_name ] = sanitize_text_field( $loc[ $field_name ] );
902 break;
903 }
904 }
905 $locations[] = $clean;
906 }
907 }
908
909 update_post_meta( $post_id, 'helpdocs_locations', $locations );
910
911 // Global fields
912 $view_roles = isset( $_POST[ 'helpdocs_view_roles' ] ) ? array_map( 'sanitize_key', wp_unslash( $_POST[ 'helpdocs_view_roles' ] ) ) : []; // phpcs:ignore
913 update_post_meta( $post_id, 'helpdocs_view_roles', $view_roles );
914
915 $api = isset( $_POST[ 'helpdocs_api' ] ) ? sanitize_text_field( wp_unslash( $_POST[ 'helpdocs_api' ] ) ) : 'default'; // phpcs:ignore
916 update_post_meta( $post_id, 'helpdocs_api', $api );
917
918 // Cleanup legacy meta fields: these are now handled within the 'helpdocs_locations' repeater array.
919 $legacy_keys = [
920 'site_location',
921 'page_location',
922 'custom',
923 'addt_params',
924 'post_types',
925 'order',
926 'toc',
927 'css_selector'
928 ];
929
930 foreach ( $legacy_keys as $key ) {
931 delete_post_meta( $post_id, 'helpdocs_' . $key );
932 }
933
934 // Flush the cache so changes show immediately
935 Helpers::flush_location_cache();
936 } // End save_post()
937
938
939 /**
940 * Delete post callback to flush cache
941 *
942 * @param int $post_id
943 * @return void
944 */
945 public function delete_post( $post_id ) {
946 if ( get_post_type( $post_id ) !== self::$post_type ) {
947 return;
948 }
949
950 // Flush the cache so changes show immediately
951 Helpers::flush_location_cache();
952 } // End delete_post()
953
954
955 /**
956 * Admin columns
957 *
958 * @param array $columns
959 * @return array
960 */
961 public function admin_columns( $columns ) {
962 $columns[ 'helpdocs_desc' ] = __( 'Description', 'admin-help-docs' );
963 $columns[ 'helpdocs_site_locations' ] = __( 'Site Locations', 'admin-help-docs' );
964 $columns[ 'helpdocs_allow_public' ] = __( 'Public', 'admin-help-docs' );
965 return $columns;
966 } // End admin_columns()
967
968
969 /**
970 * Admin column content
971 *
972 * @param string $column
973 * @param int $post_id
974 * @return void
975 */
976 public function admin_column_content( $column, $post_id ) {
977 // Description
978 if ( 'helpdocs_desc' === $column ) {
979 echo esc_html( $this->truncate( get_the_excerpt( $post_id ), 140 ) );
980 }
981
982 // Consolidated Locations Column
983 if ( 'helpdocs_site_locations' === $column ) {
984 $locations = get_post_meta( $post_id, 'helpdocs_locations', true );
985
986 // Back-compat check: if repeater is empty, try to build a single location from legacy meta
987 if ( ! is_array( $locations ) || empty( $locations ) ) {
988 $site_val = get_post_meta( $post_id, 'helpdocs_site_location', true );
989 if ( ! empty( $site_val ) ) {
990 $locations = [
991 [
992 'site_location' => $site_val,
993 'page_location' => get_post_meta( $post_id, 'helpdocs_page_location', true ),
994 'custom' => get_post_meta( $post_id, 'helpdocs_custom', true ),
995 'post_types' => Helpers::normalize_meta_array( get_post_meta( $post_id, 'helpdocs_post_types', true ) ),
996 'order' => get_post_meta( $post_id, 'helpdocs_order', true ),
997 'css_selector' => get_post_meta( $post_id, 'helpdocs_css_selector', true ),
998 ]
999 ];
1000 }
1001 }
1002
1003 if ( ! is_array( $locations ) || empty( $locations ) ) {
1004 echo '<span class="description">' . esc_html__( 'No locations set.', 'admin-help-docs' ) . '</span>';
1005 return;
1006 }
1007
1008 echo '<ul style="margin:0; padding:0; list-style:none;">';
1009 foreach ( $locations as $loc ) {
1010 $site_location_encoded = $loc[ 'site_location' ] ?? '';
1011 if ( empty( $site_location_encoded ) ) {
1012 continue;
1013 }
1014
1015 $label = Helpers::get_admin_page_title_from_url( $site_location_encoded );
1016 $url = Helpers::get_link_from_site_location( $post_id, $loc );
1017
1018 echo '<li style="margin-bottom: 8px; border-bottom: 1px solid #eee; padding-bottom: 4px;">';
1019 if ( $url ) {
1020 echo '<a href="' . esc_url( $url ) . '" target="_blank"><strong>' . wp_kses_post( $label ) . '</strong></a>';
1021 } else {
1022 echo '<strong>' . wp_kses_post( $label ) . '</strong>';
1023 }
1024
1025 // Meta detail string
1026 $details = [];
1027
1028 // 1. Page Location
1029 if ( ! empty( $loc[ 'page_location' ] ) ) {
1030 $page_loc = ucwords( str_replace( '_', ' ', $loc[ 'page_location' ] ) );
1031 if ( $page_loc === 'Contextual' ) {
1032 $page_loc .= ' Help Tab';
1033 }
1034 $details[] = '<em>' . esc_html( $page_loc ) . '</em>';
1035 }
1036
1037 // 2. Custom URL
1038 if ( ! empty( $loc[ 'custom' ] ) ) {
1039 $details[] = '<code style="font-size:10px;">' . esc_html( $loc[ 'custom' ] ) . '</code>';
1040 }
1041
1042 // 3. Post Types
1043 if ( ! empty( $loc[ 'post_types' ] ) && is_array( $loc[ 'post_types' ] ) ) {
1044 $pt_labels = [];
1045 foreach ( $loc[ 'post_types' ] as $pt ) {
1046 $pt_obj = get_post_type_object( $pt );
1047 $pt_labels[] = $pt_obj ? $pt_obj->labels->name : $pt;
1048 }
1049 $details[] = 'Types: ' . esc_html( implode( ', ', $pt_labels ) );
1050 }
1051
1052 // 4. CSS Selector
1053 if ( ! empty( $loc[ 'css_selector' ] ) ) {
1054 $details[] = 'Selector: <code>' . esc_html( $loc[ 'css_selector' ] ) . '</code>';
1055 }
1056
1057 // 5. Order
1058 if ( isset( $loc[ 'order' ] ) && $loc[ 'order' ] !== '' ) {
1059 $details[] = 'Order: ' . intval( $loc[ 'order' ] );
1060 }
1061
1062 if ( ! empty( $details ) ) {
1063 echo '<br><span class="description" style="font-size:11px;">' . wp_kses_post( implode( ' | ', $details ) ) . '</span>';
1064 }
1065
1066 echo '</li>';
1067 }
1068 echo '</ul>';
1069 }
1070
1071 if ( 'helpdocs_allow_public' === $column ) {
1072 $api = sanitize_key( get_post_meta( $post_id, 'helpdocs_api', true ) );
1073 if ( empty( $api ) || 'default' === $api ) {
1074 $default_api = get_option( 'helpdocs_api' );
1075 if ( $default_api === 'yes' || $default_api === true ) {
1076 $default_api = true;
1077 } else {
1078 $default_api = false;
1079 }
1080 $api = $default_api ? __( 'Default (Yes)', 'admin-help-docs' ) : __( 'Default (No)', 'admin-help-docs' );
1081 } else {
1082 $api = ucwords( $api );
1083 }
1084 echo esc_html( $api );
1085 }
1086 } // End admin_column_content()
1087
1088
1089 /**
1090 * Strip admin menu counters from a label
1091 *
1092 * @param string $label
1093 * @return string
1094 */
1095 private static function strip_admin_menu_counters( $label ) {
1096 if ( !is_string( $label ) ) {
1097 return $label;
1098 }
1099
1100 // Remove update badges (nested spans included)
1101 $label = preg_replace( '/<span[^>]*class="[^"]*\b(update-plugins|awaiting-mod|count-[0-9]+|bubble)\b[^"]*"[^>]*>.*?<\/span>/i', '', $label );
1102
1103 // Remove any remaining HTML
1104 $label = wp_strip_all_tags( $label );
1105
1106 // Decode entities then trim
1107 $label = trim( html_entity_decode( $label, ENT_QUOTES, 'UTF-8' ) );
1108
1109 // Remove trailing counts like "85", "(85)", "[85]", "{85}"
1110 $label = preg_replace( '/(?:\s*[\(\[\{]\s*\d+\s*[\)\]\}])|\s*\d+\s*$/', '', $label );
1111
1112 return trim( $label );
1113 } // End strip_admin_menu_counters()
1114
1115
1116 /**
1117 * Trancate string with ellipses
1118 *
1119 * @param string $string
1120 * @param int $length
1121 * @return string
1122 */
1123 public function truncate( $string, $length ) {
1124 if ( strlen( $string ) > $length ) {
1125 return substr( $string, 0, $length - 3 ).'...';
1126 }
1127 return $string;
1128 } // End truncate()
1129
1130
1131 /**
1132 * Disable Gutenberg while allowing rest
1133 *
1134 * @param [type] $current_status
1135 * @param [type] $post_type
1136 * @return void
1137 */
1138 public function disable_gutenberg( $current_status, $post_type ) {
1139 $disabled_post_types = [ self::$post_type ];
1140 if ( in_array( $post_type, $disabled_post_types, true ) ) {
1141 $current_status = false;
1142 }
1143 return $current_status;
1144 } // End disable_gutenberg()
1145
1146
1147 /**
1148 * Get the location rules
1149 *
1150 * @return array
1151 */
1152 public static function location_rules( $all_site_locations ) {
1153 $rules = [];
1154
1155 foreach ( $all_site_locations as $loc_key => $loc_info ) {
1156 $fields = [];
1157
1158 if ( isset( $loc_info[ 'fields' ] ) ) {
1159 foreach ( $loc_info[ 'fields' ] as $f ) {
1160 if ( strpos( $f, ':' ) !== false ) {
1161 $parts = explode( ':', $f );
1162 // Handle controller:value:dependent (and more)
1163 $fields[] = [
1164 'controller' => $parts[ 0 ],
1165 'controller_value' => $parts[ 1 ],
1166 'dependent' => end( $parts ), // Always the last part
1167 ];
1168 } else {
1169 $fields[] = [
1170 'field' => $f,
1171 ];
1172 }
1173 }
1174 }
1175
1176 $rules[ base64_encode( $loc_key ) ] = $fields;
1177 }
1178
1179 return $rules;
1180 } // End location_rules()
1181
1182
1183 /**
1184 * Enqueue admin styles.
1185 */
1186 public function enqueue_admin_styles() {
1187 // Only load on our post type edit screen
1188 global $current_screen;
1189 if ( ! is_admin() || ! isset( $current_screen ) || $current_screen->id !== self::$post_type || $current_screen->base !== 'post' ) {
1190 return;
1191 }
1192
1193 $text_domain = Bootstrap::textdomain();
1194 $version = Bootstrap::script_version();
1195
1196 // CSS
1197 wp_enqueue_style(
1198 $text_domain . '-post-type-' . self::$post_type,
1199 Bootstrap::url( 'inc/css/post-type-' . self::$post_type . '.css' ),
1200 [],
1201 $version
1202 );
1203
1204 // JS
1205 wp_enqueue_script(
1206 $text_domain . '-post-type-' . self::$post_type,
1207 Bootstrap::url( 'inc/js/post-type-' . self::$post_type . '.js' ),
1208 [ 'jquery' ],
1209 $version,
1210 true
1211 );
1212
1213 wp_localize_script( $text_domain . '-post-type-' . self::$post_type, 'helpdocs_' . str_replace( '-', '_', self::$post_type ), [
1214 'location_rules' => self::location_rules( self::site_locations() ),
1215 ] );
1216 } // End enqueue_admin_styles()
1217
1218 }
1219
1220
1221 HelpDocs::instance();