PATH:
var
/
softaculous
/
sitepad
/
editor
/
site-data
/
plugins
/
documentor
<?php /** * Plugin Name: Documentor * Description: Online Documentation Engine for WordPress * Version: 1.0.0 * Author: softaculous * Author URI: https://softaculous.com * License: GPLv2 or later * License URI: https://www.gnu.org/licenses/gpl-2.0.html * Text Domain: documentor * * @package documentor */ if ( ! defined( 'ABSPATH' ) ) { exit; } define('DOCUMENTOR_VERSION', '1.0.0'); define('DOCUMENTOR_DIR', dirname(__FILE__)); define('DOCUMENTOR_URL', plugins_url('', __FILE__)); function documentor_autoloader($class){ if(!preg_match('/^Documentor\\\(.*)/is', $class, $m)){ return; } $m[1] = str_replace('\\', '/', $m[1]); // Loading the file if(file_exists(DOCUMENTOR_DIR.'/includes/'.strtolower($m[1]).'.php')){ include_once(DOCUMENTOR_DIR.'/includes/'.strtolower($m[1]).'.php'); } } spl_autoload_register(__NAMESPACE__.'\documentor_autoloader'); /** * Documentor class * * @class Documentor The class that holds the entire Documentor plugin */ class Documentor { /** * The single class instance. * * @var $instance */ private static $instance = null; /** * Path to the plugin directory * * @var $plugin_path */ public $plugin_path; /** * URL to the plugin directory * * @var $plugin_url */ public $plugin_url; /** * Theme templates directory path * * @var $theme_dir_path */ public $theme_dir_path; /** * Path to template folder * * @var $theme_dir_path */ public $template_path; /** * Post type name for documents * * @var $post_type */ public $post_type = 'docs'; /** * Current Page - is Docs Archive. Will be changed from Template Loader class * * @var $post_type */ public $is_archive = false; /** * Current Page - is Docs Single. Will be changed from Template Loader class * * @var $post_type */ public $is_single = false; /* * @var $version */ public $version = '1.0.1'; /** * Main Instance * Ensures only one instance of this class exists in memory at any one time. */ public static function instance() { if ( is_null( self::$instance ) ) { self::$instance = new self(); self::$instance->plugin_init(); } return self::$instance; } /** * Plugin init. */ public function plugin_init() { $this->plugin_path = plugin_dir_path( __FILE__ ); $this->plugin_url = plugin_dir_url( __FILE__ ); $this->theme_dir_path = 'documentor/'; $this->template_path = $this->plugin_path . '/templates/'; $this->include_dependencies(); $this->maybe_setup(); $this->add_image_sizes(); // Update checker add_action('plugins_loaded', array( $this, 'update_check')); // load textdomain. load_plugin_textdomain( 'documentor', false, basename( dirname( __FILE__ ) ) . '/languages' ); // custom post type register. add_action( 'init', array( $this, 'register_post_type' ) ); // Loads frontend scripts and styles. add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_scripts' ) ); register_deactivation_hook( __FILE__, array( $this, 'deactivation_hook' ) ); register_activation_hook( __FILE__, array( $this, 'activation_hook' ) ); } /** * Activation hook. */ public function activation_hook() { $author = get_role( 'author' ); $admin = get_role( 'administrator' ); /* Add documentor manager role */ $documentor_manager = add_role( 'documentor_manager', __( 'Documentor Manager', 'documentor' ), $author->capabilities ); $full_cap = array( 'read_doc', 'read_private_doc', 'read_private_docs', 'edit_doc', 'edit_docs', 'edit_others_docs', 'edit_private_docs', 'edit_published_docs', 'delete_doc', 'delete_docs', 'delete_others_docs', 'delete_private_docs', 'delete_published_docs', 'publish_docs', ); /** * Add full capacities to admin and docs manager roles */ foreach ( $full_cap as $cap ) { if ( null !== $admin ) { $admin->add_cap( $cap ); } if ( null !== $documentor_manager ) { $documentor_manager->add_cap( $cap ); } } // Create Docs page if not created. $settings = get_option( 'documentor_settings', array() ); if ( ! $settings || ! $settings['docs_page_id'] ) { $documentor_page = wp_insert_post( array( 'post_title' => 'Docs', 'post_type' => 'page', 'post_author' => get_current_user_id(), 'post_status' => 'publish', 'post_name' => 'docs', ) ); if ( ! is_wp_error( $documentor_page ) ) { $settings['docs_page_id'] = $documentor_page; update_option( 'documentor_settings', $settings ); } } // need to flush rules to reset permalinks. add_option( 'documentor_setup', 'pending' ); // Enable for pagelayer as well $pl = get_option('pl_support_ept'); if(empty($pl)){ $pl = ['post', 'page']; } if(defined('PAGELAYER_VERSION') && !in_array($this->post_type, $pl)){ $pl[] = $this->post_type; update_option('pl_support_ept', $pl); } include_once documentor()->plugin_path.'includes/template.php'; documentor_import_template_content( json_decode(documentor_get_conf(),true), documentor_get_content()); } /** * Deactivation hook. */ public function deactivation_hook() { /* Deactivation actions */ } /** * Update checker hook. */ public function update_check() { /* Update checker hook */ $current_version = get_option('documentor_version'); $version = (int) str_replace('.', '', $current_version); // No update required if($current_version == $this->version){ return true; } if($version < 101){ $args = array( 'post_type' => 'pagelayer-template', 'post_status' => array('publish'), 'meta_query' => array( array( 'key' => 'documentor_imported_content', ) ) ); $query = new WP_Query($args); if(empty($query->posts)){ include_once documentor()->plugin_path.'includes/template.php'; documentor_import_template_content( json_decode(documentor_get_conf(),true), documentor_get_content()); } } // Save the new Version update_option('documentor_version', $this->version); } /** * Maybe run setup code and rewrite rules. */ public function maybe_setup() { $documentor_archive_id = documentor()->get_option( 'docs_page_id', 'documentor_settings', false ); $docs_page = $documentor_archive_id ? get_post( $documentor_archive_id ) : false; $slug = $docs_page ? get_post_field( 'post_name', $docs_page ) : 'docs'; if ( get_option( 'documentor_setup', false ) === 'pending' || get_option( 'documentor_current_slug', 'docs' ) !== $slug ) { add_action( 'init', 'flush_rewrite_rules', 11, 0 ); add_action( 'admin_init', 'flush_rewrite_rules', 11, 0 ); delete_option( 'documentor_setup' ); update_option( 'documentor_current_slug', $slug ); } } /** * Add image sizes. */ public function add_image_sizes() { // custom image sizes. add_image_size( 'documentor_archive_sm', 20, 20, true ); add_image_size( 'documentor_archive', 40, 40, true ); add_filter( 'image_size_names_choose', array( $this, 'image_size_names_choose' ) ); } /** * Custom image sizes * * @param array $sizes - registered image sizes. * * @return array */ public function image_size_names_choose( $sizes ) { return array_merge( $sizes, array( 'documentor_archive_sm' => esc_html__( 'Archive Thumbnail Small (Documentor)', 'documentor' ), 'documentor_archive' => esc_html__( 'Archive Thumbnail (Documentor)', 'documentor' ), ) ); } /** * Include dependencies */ public function include_dependencies() { include_once documentor()->plugin_path . 'includes/class-template-loader.php'; include_once documentor()->plugin_path . 'includes/class-walker-docs.php'; include_once documentor()->plugin_path . 'includes/class-suggestion.php'; if ( is_admin() ) { include_once documentor()->plugin_path . 'includes/admin/class-admin.php'; } if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) { include_once documentor()->plugin_path . 'includes/class-ajax.php'; } } /** * Enqueue admin scripts * * Allows plugin assets to be loaded. * * @uses wp_enqueue_script() * @uses wp_localize_script() * @uses wp_enqueue_style */ public function enqueue_scripts() { $deps = array( 'jquery' ); wp_register_style( 'documentor', documentor()->plugin_url . 'assets/css/style.min.css', array(), $this->version ); if(get_post_type() === 'docs'){ wp_enqueue_style('documentor'); } if( documentor()->get_option( 'show_anchor_links', 'documentor_single', true ) ) { wp_register_script( 'anchor-js', documentor()->plugin_url . 'assets/vendor/anchor/anchor.min.js', array(), $this->version, true ); $deps[] = 'anchor-js'; } wp_register_script( 'documentor', documentor()->plugin_url . 'assets/js/script.min.js', $deps, $this->version, true ); if ( ! ( $this->is_archive || $this->is_single ) ) { return; } wp_style_add_data( 'documentor', 'rtl', 'replace' ); wp_style_add_data( 'documentor', 'suffix', '.min' ); if ( documentor()->get_option( 'show_anchor_links', 'documentor_single', true ) ) { wp_enqueue_script( 'anchor-js'); } wp_enqueue_script( 'documentor' ); wp_localize_script( 'documentor', 'documentor_vars', array( 'ajaxurl' => admin_url( 'admin-ajax.php' ), 'nonce' => wp_create_nonce( 'documentor-ajax' ), ) ); // Custom script for AJAX. $ajax = documentor()->get_option( 'ajax', 'documentor_single', true ); $custom_js = documentor()->get_option( 'ajax_custom_js', 'documentor_single', '' ); if ( $ajax && $custom_js ) { wp_add_inline_script( 'documentor', ' (function ($) { $(document).on("documentor_ajax_loaded", function (event, new_page) { ' . $custom_js . ' }); }(jQuery)); ' ); } if ( $ajax && $this->is_single) { wp_add_inline_script('documentor', 'jQuery(".pagelayer-content").addClass("documentor-single-ajax");'); } } /** * Register the post type * * @return void */ public function register_post_type() { $documentor_archive_id = documentor()->get_option( 'docs_page_id', 'documentor_settings', false ); $docs_page = $documentor_archive_id ? get_post( $documentor_archive_id ) : false; $labels = array( 'name' => $docs_page ? get_the_title( $docs_page ) : _x( 'Documentor', 'Post Type General Name', 'documentor' ), 'singular_name' => _x( 'Doc', 'Post Type Singular Name', 'documentor' ), 'menu_name' => __( 'Documentation', 'documentor' ), 'parent_item_colon' => __( 'Parent Doc', 'documentor' ), 'all_items' => __( 'All Documentations', 'documentor' ), 'view_item' => __( 'View Documentation', 'documentor' ), 'add_new_item' => __( 'Add Documentation', 'documentor' ), 'add_new' => __( 'Add New', 'documentor' ), 'edit_item' => __( 'Edit Documentation', 'documentor' ), 'update_item' => __( 'Update Documentation', 'documentor' ), 'search_items' => __( 'Search Documentation', 'documentor' ), 'not_found' => __( 'Not documentation found', 'documentor' ), 'not_found_in_trash' => __( 'Not found in Trash', 'documentor' ), ); $rewrite = array( 'slug' => $docs_page ? get_post_field( 'post_name', $docs_page ) : 'docs', 'with_front' => false, 'pages' => true, 'feeds' => true, ); $args = array( 'labels' => $labels, 'supports' => array( 'title', 'editor', 'thumbnail', 'revisions', 'page-attributes', 'comments' ), 'hierarchical' => true, 'public' => true, 'show_ui' => true, 'show_in_menu' => false, 'show_in_nav_menus' => true, 'show_in_admin_bar' => true, 'menu_position' => 5, 'menu_icon' => 'dashicons-media-document', 'can_export' => true, 'has_archive' => $docs_page ? urldecode( get_page_uri( $documentor_archive_id ) ) : 'docs', 'exclude_from_search' => false, 'publicly_queryable' => true, 'show_in_rest' => true, 'rewrite' => $rewrite, 'map_meta_cap' => true, 'capability_type' => array( 'doc', 'docs' ), ); register_post_type( $this->post_type, $args ); register_taxonomy( 'docs_hub', $this->post_type, [ 'label' => esc_html__('Document Hubs', 'documentor'), 'labels' => [ 'menu_name' => esc_html__('Document Hub', 'documentor'), 'search_items' => esc_html__('Search Hubs', 'documentor'), 'add_new_item' => esc_html__('Add New Hub', 'documentor'), 'new_item_name' => esc_html__('New Hub Name', 'documentor'), 'all_items' => esc_html__('All Hubs', 'documentor'), 'edit_item' => esc_html__('Edit Hub', 'documentor'), 'update_item' => esc_html__('Update Hub', 'documentor'), 'back_to_items' => esc_html__('← Back to Hubs', 'documentor'), ], 'rewrite' => [ 'slug' => 'docs_hub', 'with_front' => false, ], 'hierarchical' => true, 'publicly_queryable' => true, 'show_in_nav_menus' => false, 'show_in_rest' => true, 'show_admin_column' => true, 'meta_box_cb' => '\Documentor\FrontEnd::doc_hub_radio_metabox' ]); register_taxonomy( 'docs_category', $this->post_type, array( 'label' => esc_html__( 'Docs Categories', 'documentor' ), 'labels' => array( 'menu_name' => esc_html__( 'Categories', 'documentor' ), ), 'rewrite' => array( 'slug' => 'docs-category', ), 'hierarchical' => false, 'publicly_queryable' => false, 'show_in_nav_menus' => false, 'show_in_rest' => true, 'show_admin_column' => true, ) ); } /** * Get the value of a settings field * * @param string $option settings field name. * @param string $section the section name this field belongs to. * @param string $default default text if it's not found. * * @return mixed */ public function get_option( $option, $section, $default = '' ) { $options = get_option( $section ); if ( isset( $options[ $option ] ) ) { return 'off' === $options[ $option ] ? false : ( 'on' === $options[ $option ] ? true : $options[ $option ] ); } return $default; } /** * Get template part or docs templates * Looks at the theme directory first * * @param string $name template file name. * @param string $data template data. */ public function get_template_part( $name, $data = array() ) { $name = (string) $name; // lookup at documentor/name.php. $template = locate_template( array( documentor()->theme_dir_path . "{$name}.php", ) ); // fallback to plugin default template. if ( ! $template && $name && file_exists( documentor()->template_path . "{$name}.php" ) ) { $template = documentor()->template_path . "{$name}.php"; } if ( $template ) { $this->load_template( $template, $data ); } } /** * Load template with additional data. * * @param string $template_path - template path. * @param array $template_data - template data array. */ public function load_template( $template_path, $template_data ) { if ( isset( $template_data ) && is_array( $template_data ) ) { // phpcs:ignore extract( $template_data ); } if ( file_exists( $template_path ) ) { include $template_path; } } /** * Is Archive * * @return bool */ public function is_archive() { return $this->is_archive; } /** * Is Single * * @return bool */ public function is_single() { return $this->is_single; } /** * Get current document ID * * @return int */ public function get_current_doc_id() { global $post; if ( $post->post_parent ) { $ancestors = get_post_ancestors( $post->ID ); $root = count( $ancestors ) - 1; $parent = $ancestors[ $root ]; } else { $parent = $post->ID; } return apply_filters( 'documentor_current_doc_id', $parent ); } /** * Get document page title * * @return string */ public function get_docs_page_title() { $title = esc_html__( 'Documentation', 'documentor' ); $docs_page_id = documentor()->get_option( 'docs_page_id', 'documentor_settings' ); if ( $docs_page_id ) { $title = get_the_title( $docs_page_id ); } return apply_filters( 'documentor_page_title', $title ); } /** * Get document page content * * @return string */ public function get_docs_page_content() { $content = ''; $docs_page_id = documentor()->get_option( 'docs_page_id', 'documentor_settings' ); if ( $docs_page_id ) { $content = get_post_field( 'post_content', $docs_page_id ); } return apply_filters( 'documentor_page_content', $content ); } /** * Get breadcrumbs array * * @return array */ public function get_breadcrumbs_array() { global $post; $result = array(); $docs_page_id = documentor()->get_option( 'docs_page_id', 'documentor_settings' ); $result[] = array( 'label' => __( 'Home', 'documentor' ), 'url' => home_url( '/' ), ); // Get the root ancestor to find the hub $ancestors = get_ancestors($post->ID, 'docs'); $root_ancestor = !empty($ancestors) ? $ancestors[count($ancestors)-1] : $post->ID; // Get hub term from root ancestor $docs_hub = wp_get_object_terms($root_ancestor, 'docs_hub'); if(!empty($docs_hub) && !empty($docs_hub[0]) && $docs_hub[0] instanceof \WP_Term){ // Use the linked hub page URL instead of taxonomy URL $hub_page_id = get_term_meta($docs_hub[0]->term_id, 'documentor_hub_page_id', true); $hub_url = !empty($hub_page_id) ? get_permalink($hub_page_id) : get_term_link($docs_hub[0]); $result[] = array( 'label' => !empty($docs_hub[0]->name) ? $docs_hub[0]->name : __( 'Docs', 'documentor' ), 'url' => $hub_url, ); } else if ( $docs_page_id ) { $result[] = array( 'label' => get_the_title( $docs_page_id ) ? get_the_title( $docs_page_id ) : __( 'Docs', 'documentor' ), 'url' => get_permalink( $docs_page_id ), ); } if ( 'docs' === $post->post_type && $post->post_parent ) { $parent_id = $post->post_parent; $temp_crumbs = array(); while ( $parent_id ) { $page = get_post( $parent_id ); $temp_crumbs[] = array( 'label' => get_the_title( $page->ID ), 'url' => get_permalink( $page->ID ), ); $parent_id = $page->post_parent; } $temp_crumbs = array_reverse( $temp_crumbs ); // Add current post $temp_crumbs[] = array( 'label' => get_the_title( $post->ID ), ); foreach ( $temp_crumbs as $crumb ) { $result[] = $crumb; } } return apply_filters( 'documentor_breadcrumbs_array', $result ); } /** * Next doc ID for the current doc page * * @return int */ public function get_next_adjacent_doc_id() { global $post, $wpdb; $parent = pagelayer_is_live() || wp_doing_ajax('adjacent_links') ? '0' : $post->post_parent; $menu_order = pagelayer_is_live() || wp_doing_ajax('adjacent_links') ? 1 : $post->menu_order; $next_query = "SELECT ID FROM $wpdb->posts WHERE post_parent = $parent and post_type = 'docs' and post_status = 'publish' and menu_order > $menu_order ORDER BY menu_order ASC LIMIT 0, 1"; // phpcs:ignore return (int) $wpdb->get_var( $next_query ); } /** * Previous doc ID for the current doc page * * @return int */ public function get_previous_adjacent_doc_id() { global $post, $wpdb; $parent = pagelayer_is_live() || wp_doing_ajax('adjacent_links') ? '0' : $post->post_parent; $menu_order = pagelayer_is_live() || wp_doing_ajax('adjacent_links') ? 1 : $post->menu_order; $prev_query = "SELECT ID FROM $wpdb->posts WHERE post_parent = $parent and post_type = 'docs' and post_status = 'publish' and menu_order < $menu_order ORDER BY menu_order DESC LIMIT 0, 1"; // phpcs:ignore return (int) $wpdb->get_var( $prev_query ); } } // Documentor /** * Initialize the plugin * * @return \Documentor */ function documentor() { return Documentor::instance(); } documentor(); // To find posts when we submit /docs/space/arctile-name instead of /docs/space/category/arctile-name add_filter('request', 'documentor_query_vars'); function documentor_query_vars($vars){// Handle direct links //print_r($vars);die(); $doc = documentor(); // Pagelayer draft edit requests can come through a linked hub page URL like: // /hub-page/?post_type=docs&p=172&pagelayer-live=1 // In that case WordPress receives both the docs post ID and the hub page slug. // Strip the page query vars so the docs post can resolve by ID. if( !empty($vars['post_type']) && $vars['post_type'] === $doc->post_type && !empty($vars['p']) && !empty($vars['pagename']) ){ $hub_page = get_page_by_path(sanitize_text_field(wp_unslash($vars['pagename']))); if($hub_page instanceof \WP_Post){ $linked_hub_id = get_post_meta($hub_page->ID, '_documentor_linked_hub_id', true); if(!empty($linked_hub_id)){ unset($vars['pagename']); $vars['p'] = (int) $vars['p']; return $vars; } } } // When search is submitted from a hub page (e.g., /hub-page/?s=word&post_type=docs), // the pagename (from page rewrite) conflicts with post_type=docs (from query param), // causing a 404. Strip pagename so WordPress handles it as a proper docs search. if( !empty($vars['s']) && !empty($vars['post_type']) && $vars['post_type'] === $doc->post_type && !empty($vars['pagename']) ){ $hub_page = get_page_by_path($vars['pagename']); if($hub_page instanceof \WP_Post){ $linked_hub_id = get_post_meta($hub_page->ID, '_documentor_linked_hub_id', true); if(!empty($linked_hub_id)){ $vars['documentor_search_hub'] = (int) $linked_hub_id; unset($vars['pagename']); unset($vars['name']); return $vars; } } } // Handle hub-based URLs: /hub-slug/doc-name if(!empty($vars['docs_hub']) && !empty($vars['name']) && empty($vars['post_type'])){ $vars['post_type'] = documentor()->post_type; } // Must be docs if(empty($vars['post_type']) || $vars['post_type'] != documentor()->post_type || empty($vars['name'])){ return $vars; } if(!empty($_GET['debug'])){ //print_r($vars);die(); } $docs_archive_id = documentor()->get_option( 'docs_page_id', 'documentor_settings', false ); $permalink = get_permalink($docs_archive_id); $docs = explode('/', $vars['docs']); // Find the post by name only (no tax_query, as hub may be on ancestor) $args = array( 'name' => $vars['name'], 'post_type' => 'docs', 'post_status' => 'publish', 'numberposts' => 10 ); $posts = get_posts($args); //print_r($post); // Did we get it ? if(empty($posts)){ // Ok lets try to see if we get with another method $tmp = explode('/', str_replace('_', '-', $vars['name'])); $args['name'] = $tmp[count($tmp)-1]; $posts = get_posts($args); // If we still didnt get it, then lets return original vars if(empty($posts)){ return $vars; } } // If we have hub context, filter posts by checking hub inheritance if(!empty($vars['docs_hub']) && count($posts) > 0){ $hub_matched = array(); foreach($posts as $p){ $post_hub = documentor_get_post_hub($p->ID); if($post_hub && $post_hub->slug === $vars['docs_hub']){ $hub_matched[] = $p; } } if(!empty($hub_matched)){ $posts = $hub_matched; } } $post = $posts[0]; // If we have 2 parts, then find the closest as well if(count($docs) > 1){ // If we found more than 1 results foreach($posts as $p){ $url = get_permalink($p); $_section = trim(str_replace($permalink, '', $url), '/'); $parts = explode('/', $_section); if($parts[0] == $docs[0]){ $post = $p; break; } } } if(!empty($_GET['debug'])){ //print_r($post);die(); } // For hub-based URLs, skip redirect logic and just resolve the post if(!empty($vars['docs_hub'])){ // This bypasses all slug resolution and tells WordPress exactly which post to load by ID. $vars['p'] = $post->ID; unset($vars['name']); unset($vars['docs']); return $vars; } $url = get_permalink($post); $_section = trim(str_replace($permalink, '', $url), '/'); //echo $url."\n"; //echo $_section.' - '.$vars['name']."\n";die(); // If the LINK is not same as the original, then redirect if($_section != trim($vars['name'], '/')){ //die('redirecting !'); wp_redirect($url.(!empty($_SERVER['QUERY_STRING']) ? '?'. sanitize_text_field(wp_unslash($_SERVER['QUERY_STRING'])) : '')); die(); } $section = get_page_uri($post); //echo $section."\n"; $vars['name'] = $vars['docs'] = trim($section, '/'); //print_r($vars); //die($section); return $vars; } /** * Get the docs_hub term for a post, checking ancestors if not directly assigned. * * @param int $post_id Post ID * @return WP_Term|null The hub term or null if not found */ function documentor_get_post_hub($post_id){ // Check if post has docs_hub directly $terms = wp_get_post_terms($post_id, 'docs_hub'); if(!empty($terms) && !is_wp_error($terms)){ return $terms[0]; } // Walk up ancestors to find hub $ancestors = get_ancestors($post_id, 'docs'); if(!empty($ancestors) && is_array($ancestors)){ foreach($ancestors as $ancestor_id){ $terms = wp_get_post_terms($ancestor_id, 'docs_hub'); if(!empty($terms) && !is_wp_error($terms)){ return $terms[0]; } } } return null; } // No pagelayer content template should render add_action( 'template_redirect', 'documentor_no_pagelayer_content', 101); function documentor_no_pagelayer_content(){ global $wp_query, $pagelayer; $docs = documentor(); if(empty($wp_query->query['post_type']) || $wp_query->query['post_type'] !== $docs->post_type || !is_search()){ return; } $pagelayer->template_post = null; } //Show pagination add_action('pre_get_posts', 'documentor_show_posts'); function documentor_show_posts($query){ if((is_admin() && !wp_doing_ajax()) || !$query->is_main_query()){ return; } $is_hub_page = false; // Check if this is a physical Page secretly linked to a Hub if($query->is_page()){ $page_id = $query->get_queried_object_id(); $meta = get_post_meta($page_id, '_documentor_linked_hub_id', true); if(!empty($meta)){ $is_hub_page = true; } } if($query->is_tax('docs_hub') || $is_hub_page){ // Force WP to treat this as the Docs Archive $query->set('post_type', array('docs')); $query->query_vars['post_type'] = array('docs'); // Tell WordPress this is NOT a standard page anymore $query->set('page_id', ''); $query->set('pagename', ''); $query->set('name', ''); // Force the Archive boolean flags $query->is_post_type_archive = true; $query->is_archive = true; $query->is_singular = false; $query->is_page = false; } //Return if the action is not 'search' if(!($query->is_search())){ return; } if(@$query->query['post_type'] !== documentor()->post_type){ return; } $query->query_vars['posts_per_page'] = 50; $query->query_vars['paged'] = (get_query_var('paged') ? get_query_var('paged') : 1); } // All post types are editable by Pagelayer add_filter('pagelayer_supported_post_type', 'documentor_supported_post_type', 10, 1); function documentor_supported_post_type($types){ if(!in_array('docs', $types)){ $types[] = 'docs'; } return $types; } // Add shortcode in Pagelayer shortcode loader // Loads the shortcodes add_action( 'pagelayer_load_custom_widgets', 'documentor_load_shortcodes' ); function documentor_load_shortcodes(){ include_once documentor()->plugin_path.'includes/shortcode_functions.php'; include_once documentor()->plugin_path.'includes/shortcodes.php'; } // Load editor js and css add_action( 'pagelayer_custom_editor_enqueue', 'documentor_custom_editor_enqueue' ); function documentor_custom_editor_enqueue(){ global $wp_query, $pagelayer; $docs = documentor(); // Enqueue JS wp_register_script('documentor-editor', documentor()->plugin_url.'assets/js/widgets.js', array('jquery'), documentor()->version); wp_enqueue_script('documentor-editor'); if(empty($wp_query->query['post_type']) || !($wp_query->query['post_type'] == $docs->post_type || $wp_query->query['post_type'] == $pagelayer->builder['name'])){ return; } // Enqueue frontend js and CSS wp_enqueue_style( 'documentor'); if ( documentor()->get_option( 'show_anchor_links', 'documentor_single', true ) ) { wp_enqueue_script( 'anchor-js'); } wp_enqueue_script( 'documentor' ); } // Load editor js and css add_action( 'pagelayer_live_body_head', 'documentor_icon_enqueue' ); function documentor_icon_enqueue(){ echo '<link rel="stylesheet" href="'.esc_url(documentor()->plugin_url).'assets/css/documentor-icon.css">'; } add_action('wp_head', '\Documentor\FrontEnd::override_pagelayer_return_url', 1000); add_action('init', 'documentor_languages'); function documentor_languages(){ global $pagelayer; $lang = @file_get_contents( documentor()->plugin_url .'/languages/en.json'); $lang = @json_decode($lang, true); foreach($lang as $k => $v){ if(!isset($pagelayer->l[$k])){ $pagelayer->l[$k] = $v; } } } // Adds rewrite rules so that doc hub urls could load docs in place of 404. function documentor_add_doc_hub_rewrite_rules(){ $terms = get_terms([ 'taxonomy' => 'docs_hub', 'hide_empty' => false ]); if(empty($terms) || is_wp_error($terms)){ return; } $term_slugs = wp_list_pluck($terms, 'slug'); //print_r($term_slugs);die(); $regex = '^(' . implode('|', $term_slugs) . ')/(.+?)/?$'; add_rewrite_rule($regex, 'index.php?post_type=docs&name=$matches[2]&docs=$matches[2]&docs_hub=$matches[1]', 'top'); } add_action('init', 'documentor_add_doc_hub_rewrite_rules'); add_filter('post_type_link', '\Documentor\FrontEnd::filter_mixed_docs_permalink', 10002, 2); // This is the line hidden inside /wp-includes/general-template.php add_filter('document_title_parts', '\Documentor\FrontEnd::display_page_title'); // Change the visual page header title for Hubs add_filter('post_type_archive_title', '\Documentor\FrontEnd::override_archive_title'); // Force all hub links to use the clean page URL instead of the Taxonomy URL add_filter('term_link', '\Documentor\FrontEnd::bridge_hub_links', 10, 3); // Redirect anyone who visits the Hub URL to the page linked to it add_action('template_redirect', '\Documentor\FrontEnd::bridge_hub_redirect'); add_action('pagelayer_builder_template_redirect', '\Documentor\FrontEnd::load_hubs_template', 20); add_filter('pagelayer_remove_meta_boxes', '\Documentor\FrontEnd::remove_pl_hub_metabox'); /** * Flush rewrite rules when doc hub assignment changes. * * Only flushes when: * - A hub is first assigned to a doc (0 -> hub_id) * - Hub is changed (hub_id_a -> hub_id_b) * - Hub is removed (hub_id -> 0) * * @param array $terms - An array of object term IDs or slugs. * @param int $tt_ids - term taxonomy ID * @param string $taxonomy - taxonomy slug * @param int $object_id - post ID * @param bool $append - Whether to append new terms to the old terms. * @param array $old_tt_ids - previous term taxonomy IDs */ function documentor_flush_on_hub_assignment($object_id, $terms, $tt_ids, $taxonomy, $append, $old_tt_ids){ if('docs_hub' !== $taxonomy){ return; } // Making sure we are doing it only for the a docs post type $post = get_post($object_id); if(empty($post) || $post->post_type !== 'docs'){ return; } $new_hub_id = !empty($tt_ids) ? intval($tt_ids[0]) : 0; $old_hub_id = !empty($old_tt_ids) ? intval($old_tt_ids[0]) : 0; // Flush only if the hub has been changed if($new_hub_id !== $old_hub_id){ flush_rewrite_rules(); } } // Flush rewrite rules when doc hub assignment changes. add_action('set_object_terms', 'documentor_flush_on_hub_assignment', 10, 6);
[-] index.php
[edit]
[+]
assets
[-] readme.md
[edit]
[+]
includes
[+]
templates
[+]
..
[+]
languages
[-] documentor.php
[edit]
[-] LICENSE.txt
[edit]