init();
} );
/**
* Main plugin class.
*/
class HELPDOCS_DOCUMENTATION {
/**
* Post type
*
* @var string
*/
public $post_type;
/**
* Folder taxonomy
*
* @var string
*/
public $folder_taxonomy;
/**
* Site location
*
* @var array
*/
public $site_location;
/**
* Page location
*
* @var array
*/
public $page_location;
/**
* Priority for other pages
*
* @var array
*/
public $priority;
/**
* Constructor
*/
public function __construct() {
// Define the post type
$this->post_type = 'help-docs';
// Define the folder taxonomy name
$this->folder_taxonomy = 'help-docs-folder';
// Set the locations
$this->site_location = [
'main' => 'Main Documentation Page',
'admin_bar' => 'Admin Bar Menu (Must Be Enabled in Settings)',
'index.php' => 'Dashboard',
'post.php' => 'Post/Page Edit Screen',
'edit.php' => 'Post/Page Admin List Screen',
];
// Locations on the page
$this->page_location = [
'contextual' => 'Contextual Help Tab (At Top of Screen)',
'top' => 'Top',
'bottom' => 'Bottom',
'side' => 'Side'
];
// Priority for meta boxes
$this->priority = [
'high' => 'High',
'core' => 'Core',
'default' => 'Default',
'low' => 'Low'
];
} // End __construct()
/**
* Load on init, but not every time the class is called
*
* @return void
*/
public function init() {
// Register the post type
$this->register_post_type();
// Register taxonomy
$this->register_taxonomy();
// Either enqueue block editor styles or disable block editor
if ( ! get_option( 'helpdocs_gutenberg_editor' ) ) {
add_filter( 'use_block_editor_for_post_type', [ $this, 'disable_gutenberg' ], 10, 2 );
}
// Enqueue back-end styles
add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_admin_styles' ] );
// Add the header to the top of the admin list page
add_action( 'load-edit.php', [ $this, 'add_header' ] );
add_action( 'load-edit-tags.php', [ $this, 'add_header' ] );
// Add the meta box
add_action( 'add_meta_boxes', [ $this, 'meta_boxes' ] );
// Rename excerpt meta box
add_filter( 'gettext', [ $this, 'excerpt_meta_box' ], 10, 2 );
// Save the post data
add_action( 'save_post', [ $this, 'save_post' ] );
// Add admin columns
add_filter( 'manage_'.$this->post_type.'_posts_columns', [ $this, 'admin_columns' ] );
add_action( 'manage_'.$this->post_type.'_posts_custom_column', [ $this, 'admin_column_content' ], 10, 2 );
// Make admin columns sortable
add_filter( 'manage_edit-'.$this->post_type.'_sortable_columns', [ $this, 'sort_columns' ] );
add_action( 'pre_get_posts', [ $this, 'sort_columns_query' ] );
// Dashboard widgets
add_action( 'wp_dashboard_setup', [ $this, 'dashboard_widgets' ] );
// Other locations
add_action( 'admin_head', [ $this, 'add_to_other_pages' ] );
// Gutenberg
add_action( 'admin_footer', [ $this, 'gutenberg_content' ] );
// Update order of documentation with Ajax
add_action( 'wp_ajax_'.HELPDOCS_GO_PF.'update_order', [ $this, 'update_order' ] );
add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_order_scripts' ] );
// Edit doc scripts
add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_edit_doc_scripts' ] );
// Fire when a new folder is created
add_action( 'create_term', [ $this, 'on_create_folder' ], 10, 4 );
// Add a filter dropdown to admin table
add_action( 'restrict_manage_posts', [ $this, 'admin_folder_filter' ] );
// Filter admin table
add_action( 'pre_get_posts', [ $this, 'filter_admin_columns' ] );
// Display shortcodes without executing them
add_shortcode( 'dont_do_shortcode', [ $this, 'display_shortcode_without_executing' ] );
// Add a link back to main documentation page on the edit screen
add_action( 'edit_form_after_title', [ $this, 'add_link_back_to_edit_screen' ] );
// Add CSS to docs
add_shortcode( 'helpdocs_css', [ $this, 'add_css_to_docs' ] );
} // End init()
/**
* Register the post type
*/
public function register_post_type() {
// Set the labels
$labels = [
'name' => _x( 'Help Documents', 'Post Type General Name', 'admin-help-docs' ),
'singular_name' => _x( 'Help Document', 'Post Type Singular Name', 'admin-help-docs' ),
'menu_name' => __( 'Help Documents', 'admin-help-docs' ),
'name_admin_bar' => __( 'Help Documents', 'admin-help-docs' ),
'archives' => __( 'Help Document Archives', 'admin-help-docs' ),
'attributes' => __( 'Help Document Attributes', 'admin-help-docs' ),
'parent_item_colon' => __( 'Parent Help Document:', 'admin-help-docs' ),
'all_items' => __( 'All Help Documents', 'admin-help-docs' ),
'add_new_item' => __( 'Add New Help Document', 'admin-help-docs' ),
'add_new' => __( 'Add New', 'admin-help-docs' ),
'new_item' => __( 'New Help Document', 'admin-help-docs' ),
'edit_item' => __( 'Edit Help Document', 'admin-help-docs' ),
'update_item' => __( 'Update Help Document', 'admin-help-docs' ),
'view_item' => __( 'View Help Document', 'admin-help-docs' ),
'view_items' => __( 'View Help Documents', 'admin-help-docs' ),
'search_items' => __( 'Search Help Documents', 'admin-help-docs' ),
'not_found' => __( 'Not found', 'admin-help-docs' ),
'not_found_in_trash' => __( 'Not found in Trash', 'admin-help-docs' ),
'featured_image' => __( 'Featured Image', 'admin-help-docs' ),
'set_featured_image' => __( 'Set featured image', 'admin-help-docs' ),
'remove_featured_image' => __( 'Remove featured image', 'admin-help-docs' ),
'use_featured_image' => __( 'Use as featured image', 'admin-help-docs' ),
'insert_into_item' => __( 'Insert into help document', 'admin-help-docs' ),
'uploaded_to_this_item' => __( 'Uploaded to this help document', 'admin-help-docs' ),
'items_list' => __( 'Help Document list', 'admin-help-docs' ),
'items_list_navigation' => __( 'Help Document list navigation', 'admin-help-docs' ),
'filter_items_list' => __( 'Filter help document list', 'admin-help-docs' ),
];
// Allow filter for supports and taxonomies
$supports = apply_filters( HELPDOCS_GO_PF.'post_type_supports', [ 'title', 'editor', 'author', 'revisions', 'excerpt' ] );
$taxonomies = apply_filters( HELPDOCS_GO_PF.'post_type_taxonomies', [] );
// Set the CPT args
$args = [
'label' => __( 'Help Documents', 'admin-help-docs' ),
'description' => __( 'Help Documents', 'admin-help-docs' ),
'labels' => $labels,
'supports' => $supports,
'taxonomies' => $taxonomies,
'public' => true,
'show_ui' => true,
'show_in_menu' => false,
'show_in_admin_bar' => false,
'show_in_nav_menus' => false,
'can_export' => true,
'has_archive' => false,
'exclude_from_search' => true,
'publicly_queryable' => false,
'query_var' => $this->post_type,
'capability_type' => 'post',
'show_in_rest' => true,
];
// Register the CPT
register_post_type( $this->post_type, $args );
} // End register_post_type()
/**
* Enqueue admin styles.
*/
public function enqueue_admin_styles() {
// Add block styles
if ( get_option( 'helpdocs_gutenberg_editor' ) ) {
wp_enqueue_style(
'wp-block-library-frontend',
includes_url( 'css/dist/block-library/style.css' ),
[],
false
);
}
// Enqueuing frontend styles
if ( get_option( 'helpdocs_enqueue_frontend_styles' ) ) {
// Add theme styles
global $wp_styles;
do_action( 'wp_enqueue_scripts' );
$skip = [ 'wp-block-library', 'wp-admin', 'colors', 'dashicons' ];
foreach ( $wp_styles->queue as $handle ) {
if ( in_array( $handle, $skip, true ) ) {
continue;
}
$style = $wp_styles->registered[ $handle ] ?? null;
if ( $style && ! wp_style_is( $handle, 'enqueued' ) ) {
wp_enqueue_style(
$handle,
$style->src,
$style->deps,
$style->ver
);
}
}
// Add our own fixes
wp_enqueue_style(
'helpdocs-backend-styles',
HELPDOCS_PLUGIN_CSS_PATH . 'style.css',
[],
false
);
}
} // End enqueue_admin_styles()
/**
* Disable Gutenberg while allowing rest
*
* @param [type] $current_status
* @param [type] $post_type
* @return void
*/
public function disable_gutenberg( $current_status, $post_type ) {
// Disabled post types
$disabled_post_types = [ $this->post_type ];
// Change $can_edit to false for any post types in the disabled post types array
if ( in_array( $post_type, $disabled_post_types, true ) ) {
$current_status = false;
}
return $current_status;
} // End disable_gutenberg()
/**
* Register taxonomy
*/
public function register_taxonomy() {
// Make sure it's lowercase
$taxonomy = $this->folder_taxonomy;
// Create the labels
$labels = [
'name' => _x( 'Folder', 'taxonomy general name' ),
'singular_name' => _x( 'Folder', 'taxonomy singular name' ),
'search_items' => __( 'Search Folders' ),
'all_items' => __( 'Add to Folder' ),
'parent_item' => __( 'Parent Folder' ),
'parent_item_colon' => __( 'Parent Folder: ' ),
'edit_item' => __( 'Edit Folder' ),
'update_item' => __( 'Update Folder' ),
'add_new_item' => __( 'Add New Folder' ),
'new_item_name' => __( 'New Folder Name' ),
'menu_name' => __( 'Folders' ),
];
// Register it as a new taxonomy
register_taxonomy( $taxonomy, $this->post_type, [
'hierarchical' => true,
'labels' => $labels,
'show_ui' => true,
'show_in_rest' => false,
'show_admin_column' => true,
'show_in_quick_edit' => true,
'query_var' => true,
'public' => false,
'rewrite' => [ 'slug' => $taxonomy, 'with_front' => false ],
] );
} // End register_taxonomy()
/**
* Do stuff when a new folder is created
*
* @return void
*/
public function on_create_folder( $term_id, $tt_id, $taxonomy, $args ) {
// Add order meta
update_term_meta( $term_id, HELPDOCS_GO_PF.'order', 0 );
} // End on_create_folder()
/**
* Add the header to the top of the admin list page
*
* @return void
*/
public function add_header() {
$screen = get_current_screen();
// Only edit post screen:
if ( 'edit-'.$this->post_type === $screen->id || 'edit-'.$this->folder_taxonomy === $screen->id ) {
// Add the header
add_action( 'all_admin_notices', function() {
include HELPDOCS_PLUGIN_ADMIN_PATH.'header.php';
echo '
';
} );
}
} // End add_header()
/**
* Meta box
*
* @return void
*/
public function meta_boxes() {
// Add the location meta box to our custom post type
add_meta_box(
'help-locations',
__( 'Location', 'admin-help-docs' ),
[ $this, 'meta_box_content' ],
$this->post_type,
'advanced',
'high'
);
// Start the args to get the docs
$args = [
'posts_per_page' => -1,
'post_status' => 'publish',
'post_type' => $this->post_type,
'meta_key' => HELPDOCS_GO_PF.'site_location', // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key
'meta_value' => base64_encode( 'post.php' ), // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_value
'meta_compare' => '=',
];
// Get the posts
$docs = get_posts( $args );
// Also get the imports
$imports = helpdocs_get_imports( $args );
// Merge them together
if ( !empty( $imports ) ) {
$docs = array_merge( $docs, $imports );
}
// Iter the docs
foreach ( $docs as $doc ) {
// Skip if the page location is not bottom or side
$page_location_var = HELPDOCS_GO_PF.'page_location';
$page_location = $doc->$page_location_var;
if ( $page_location != 'bottom' && $page_location != 'side' ) {
continue;
}
// Skip if bottom of gutenberg editor
if ( $page_location == 'bottom' && is_gutenberg() ) {
continue;
}
// Get the post type
$post_types_var = HELPDOCS_GO_PF.'post_types';
$post_types = unserialize( $doc->$post_types_var );
if ( empty( $post_types ) ) {
continue;
}
// Set the location
if ( $page_location == 'bottom' ) {
$context = 'advanced';
} else {
$context = 'side';
}
// Get the priority
$priority_var = HELPDOCS_GO_PF.'priority';
if ( $doc->$priority_var != '' && $page_location == 'side' ) {
$priority = $doc->$priority_var;
} else {
$priority = 'low';
}
// Pass docs in the args
$args = [ $doc ];
// Create the meta box
add_meta_box(
HELPDOCS_GO_PF.$doc->ID,
esc_html( $doc->post_title ),
[ $this, 'post_page_meta_box_content' ],
$post_types,
$context,
$priority,
$args
);
}
} // End meta_boxes()
/**
* Rename excerpt meta box as description
*
* @param string $translation
* @param string $original
* @return string
*/
public function excerpt_meta_box( $translation, $original ) {
// Make sure we are only looking at our post type
global $post_type;
if ( $post_type != $this->post_type ) {
return $translation;
}
// Update the box
if ( 'Excerpt' == $original ) {
return __( 'Description', 'admin-help-docs' );
} elseif ( false !== strpos( $original, 'Excerpts are optional hand-crafted summaries of your' ) ) {
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' );
}
return $translation;
} // End excerpt_meta_box()
/**
* Meta box content
*
* @param object $post
* @return void
*/
public function meta_box_content( $post ) {
// Add a nonce field so we can check for it later.
wp_nonce_field( 'help_location_nonce', 'help_location_nonce' );
// Get the current values
$site_location = sanitize_text_field( get_post_meta( $post->ID, HELPDOCS_GO_PF.'site_location', true ) );
$page_location = sanitize_key( get_post_meta( $post->ID, HELPDOCS_GO_PF.'page_location', true ) );
$custom = filter_var( get_post_meta( $post->ID, HELPDOCS_GO_PF.'custom', true ), FILTER_SANITIZE_URL );
$addt_params = get_post_meta( $post->ID, HELPDOCS_GO_PF.'addt_params', true ) ? filter_var( get_post_meta( $post->ID, HELPDOCS_GO_PF.'addt_params', true ), FILTER_VALIDATE_BOOLEAN ) : false;
$post_types = unserialize( get_post_meta( $post->ID, HELPDOCS_GO_PF.'post_types', true ) );
$order = get_post_meta( $post->ID, HELPDOCS_GO_PF.'order', true ) ? filter_var( get_post_meta( $post->ID, HELPDOCS_GO_PF.'order', true ), FILTER_SANITIZE_NUMBER_INT ) : 0;
$toc = get_post_meta( $post->ID, HELPDOCS_GO_PF.'toc', true ) ? filter_var( get_post_meta( $post->ID, HELPDOCS_GO_PF.'toc', true ), FILTER_VALIDATE_BOOLEAN ) : false;
$priority = sanitize_key( get_post_meta( $post->ID, HELPDOCS_GO_PF.'priority', true ) );
$api = sanitize_key( get_post_meta( $post->ID, HELPDOCS_GO_PF.'api', true ) );
// Get all choices
$all_site_locations = $this->site_location;
$all_page_locations = $this->page_location;
$all_post_types = get_post_types( [ '_builtin' => false ] );
$all_priorities = $this->priority;
// Location name changes
$site_location_names = apply_filters( HELPDOCS_GO_PF.'location_names', [
'edit-comments.php' => 'Comments',
'site-editor.php' => 'Editor',
'plugins.php' => 'Plugins',
'dev-debug-tools' => 'Dev Debug Tools',
'admin.php?page=dev-debug-tools&tab=logs' => 'Logs'
] );
// Get all screens
global $menu, $submenu;
// Iter the parent menu items
foreach ( $menu as $m ) {
// Skip separators
if ( str_starts_with( $m[2], 'separator' ) || $m[2] == 'hp_separator' || ( isset( $m[4] ) && strpos( $m[4], 'wp-menu-separator' ) !== false ) ) {
continue;
}
// Skip dashboard and help topics
if ( $m[2] == 'index.php' || $m[2] == helpdocs_plugin_options_short_path() ) {
continue;
}
// Skip post types
if ( str_starts_with( $m[2], 'edit.php' ) ) {
continue;
}
// Change option names
if ( array_key_exists( $m[2], $site_location_names ) ) {
$site_location_name = $site_location_names[ $m[2] ];
} else {
$site_location_name = $m[0];
}
// Strip html
$site_location_name = $this->strip_admin_menu_counters( $site_location_name );
// Add the parent location
if ( !array_key_exists( $m[2], $submenu ) ) {
// Get the url
$url = $this->get_admin_menu_item_url( $m[2] );
if ( is_null( $url ) ) {
$url = 'not found';
}
// Strip the url
$url = str_replace( get_home_url().'/'.HELPDOCS_ADMIN_URL.'/', '', $url );
// Add it
$all_site_locations[ $url ] = $site_location_name;
}
// Check for sub menu items
foreach ( $submenu as $k => $sub ) {
if ( $k == $m[2] ) {
// Iter the submenu items
foreach ( $sub as $s ) {
// Change option names
if ( array_key_exists( $s[2], $site_location_names ) ) {
$sublocation_name = $site_location_names[ $s[2] ];
} else {
$sublocation_name = $s[0];
}
// Strip html
$sublocation_name = $this->strip_admin_menu_counters( $sublocation_name );
// Get the url
$url = $this->get_admin_menu_item_url( $s[2] );
if ( is_null( $url ) ) {
$url = 'not found';
}
// Strip the url
$url = str_replace( get_home_url().'/'.HELPDOCS_ADMIN_URL.'/', '', $url );
// Add the child location
$all_site_locations[ $url ] = $site_location_name.' — '.$sublocation_name;
}
}
}
}
// Add a custom link option to the bottom
$all_site_locations[ 'custom' ] = 'Other/Custom Page (Beta)';
// Add some CSS
echo '';
// Start the form
echo '
'.wp_kses_post( $doc->post_content ).'
';
$sf = '';
}
$content = sanitize_text_field( $atts[ 'content' ] );
$content = str_replace( '{', '[[', $content );
$content = str_replace( '}', ']]', $content );
// Final
$text = $pf.$content.$sf;
// Click to copy?
if ( strtolower( sanitize_text_field( $atts[ 'click_to_copy' ] ) ) == 'false' ) {
return $text;
} else {
return helpdocs_click_to_copy( uniqid( 'shortcode_' ), $text, null, wp_strip_all_tags( $text ), true );
}
} // End display_shortcode_without_executing()
/**
* Add a link back to main documentation page on the edit screen
*
* @return void
*/
public function add_link_back_to_edit_screen() {
// // We only need to call this once
// if ( !isset( $_SESSION ) ) {
// session_start();
// }
// if ( !isset( $_SESSION[ 'admin_help_doc_permalink' ] ) ) {
// // We have added it
// $_SESSION[ 'admin_help_doc_permalink' ] = 'done';
// // Remove the session
// } else {
// unset( $_SESSION[ 'admin_help_doc_permalink' ] );
// }
// Only on our edit screen
global $post_type;
if ( is_admin() && $this->post_type == $post_type ) {
// Get the id
$doc_id = get_the_ID();
// Check if main doc page
$site_location = get_post_meta( $doc_id, HELPDOCS_GO_PF.'site_location', true );
if ( $site_location && $site_location == base64_encode( 'main' ) ) {
// The URL
$url = helpdocs_plugin_options_path( 'documentation' ).'&id='.absint( $doc_id );
echo '