Mini Shell
<?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;
}
/**
* 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( 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_enqueue_style( 'documentor');
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_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( '/' ),
);
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 );
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();
// 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
$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;
}
}
$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();
}
$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']) ? '?'.$_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;
}
// 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){
//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="'.documentor()->plugin_url.'assets/css/documentor-icon.css">';
}
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;
}
}
}
Zerion Mini Shell 1.0