File Manager

Path: /usr/local/sitepad/editor/site-data/plugins/documentor/includes/

Viewing File: class-template-loader.php

<?php
/**
 * Template loader.
 *
 * @package documentor
 */

if(!defined('ABSPATH')){
	exit;
}

/**
 * Template Loader
 *
 * @class       Documentor_Template_Loader
 * @package     documentor
 */
class Documentor_Template_Loader{
	/**
		* Docs archive page ID
		*
		* @var int
	*/
	private static $docs_archive_id = 0;

	/**
		* Hook in methods.
	*/
	public static function init(){
		self::$docs_archive_id = documentor()->get_option('docs_page_id', 'documentor_settings', false);

		add_filter('template_include', array( __CLASS__, 'template_loader'));

		// To make the links like /docs/space/category/arctile-name to /docs/space/arctile-name
		add_filter('post_type_link', array(__CLASS__, 'permalink'), 10001, 4);
	}

	/**
		* Load a template.
		*
		* Handles template usage so that we can use our own templates instead of the themes.
		*
		* Templates are in the 'templates' folder. documentor looks for theme.
		* overrides in /theme/documentor/ by default.
		*
		* @param string $template - template name.
		* @return string
	*/
	public static function template_loader($template){
		if(is_embed()){
			return $template;
		}

		$default_file = self::get_template_loader_default_file();

		if($default_file){
			/**
			* Filter hook to choose which files to find before Documentor does it's own logic.
			*
			* @var array
			*/
			$search_files = self::get_template_loader_files($default_file);
			$template = locate_template($search_files);

			if(!$template){
				$template = documentor()->template_path . $default_file;
			}
		}

		return $template;
	}

	/**
		* Get the default filename for a template.
		*
		* @return string
		*/
	private static function get_template_loader_default_file(){
		$default_file = '';

		// Detect if the current page is linked to a Hub
		$is_hub_page = false;
		$linked_hub_id = 0;
		$is_editor = (isset($_GET['pagelayer-live']) || wp_doing_ajax());

		// Safely get the page ID
		$current_page_id = get_queried_object_id();
		$post_id = isset($_REQUEST['post_id']) ? intval($_REQUEST['post_id']) : 0;
		if(empty($current_page_id) && $is_editor && $post_id > 0){
			$current_page_id = $post_id;
		}

		if($current_page_id > 0){
			$meta = get_post_meta(get_queried_object_id(), '_documentor_linked_hub_id', true);
			if(!empty($meta)){
				$is_hub_page = true;
				$linked_hub_id = intval($meta);
			}
		}

		if(is_singular('docs') || ($is_hub_page && $is_editor)){
			$default_file = 'single.php';
			documentor()->is_single = true;

		} else if(
			is_post_type_archive('docs') || 
			self::$docs_archive_id && 
			is_page(self::$docs_archive_id) || 
			is_tax('docs_hub') || 
			$is_hub_page
		){

			$default_file = 'archive.php';
			documentor()->is_archive = true;

			// Add query for page docs.
			global $wp_query;
			$args = array(
				'post_type' => 'docs',
				'posts_per_page' => -1, // phpcs:ignore
				'post_parent' => 0,
				'orderby' => array(
					'menu_order' => 'ASC',
					'date' => 'DESC',
				),
			);

			// Apply specific database filtering if the user is viewing a Hub taxonomy page
			if(is_tax('docs_hub') || $is_hub_page){
				$hub_id = is_tax('docs_hub') ? get_queried_object_id() : $linked_hub_id;

				// Find all categories that the admin has explicitly mapped to this Hub
				$matching_cats = get_terms([
					'taxonomy' => 'docs_category',
					'meta_query' => [
						[
							'key' => 'documentor_associated_hubs',
							'value' => $hub_id,
							'compare' => '='
						]
					],

					'fields' => 'ids'
				]);

				// Start building a query to fetch docs explicitly assigned to this Hub
				$tax_query = ['relation' => 'OR'];
				$tax_query[] = ['taxonomy' => 'docs_hub', 'field' => 'term_id', 'terms' => $hub_id];

				// Also include docs that belong to the mapped categories (if they don't have another explicit Hub assigned)
				if(!empty($matching_cats) && !is_wp_error($matching_cats)){
					$tax_query[] = [
						'relation' => 'AND',
						['taxonomy' => 'docs_category', 'field' => 'term_id', 'terms' => $matching_cats],
						['taxonomy' => 'docs_hub', 'operator' => 'NOT EXISTS']
					];
				}

				$args['tax_query'] = $tax_query;
			}

			// prepare args for search page.
			if(!is_admin() && is_search()){
				$default_file = 'search.php';

				unset($args['posts_per_page']);
				unset($args['post_parent'] );

				$args['s'] = get_search_query();

				// phpcs:ignore
				$parent = isset($_GET['child_of']) ? sanitize_text_field(wp_unslash($_GET['child_of'])) : false;
				$parent = intval($parent);

				// we need to get all docs IDs and the use it in WP_Query as we need get also all childrens.
				if($parent){
					$post__in = array($parent => $parent);
					$children_docs = get_pages(
						array(
							'child_of'  => $parent,
							'post_type' => 'docs',
							'depth'     => -1,
						)
					);
					if($children_docs){
						$post__in = array_merge($post__in, wp_list_pluck($children_docs, 'ID'));
					}
					$args['post__in'] = $post__in;
				}
			}

			// make order by term.
			if('archive.php' === $default_file){
				
				$categories = get_terms(
					array(
						'taxonomy'   => 'docs_category',
						'hide_empty' => false,
						'order_by' => 'name',
						'order' => 'DESC',
					)
				);

				// we need to make query and loop over items and sort it by term.
				if(!empty($categories)){
					$docs_by_cat = array(
						0 => array(),
					);

					// get all available terms in array.
					foreach($categories as $cat){
						$docs_by_cat[$cat->slug] = array();
					}

					// Prepare a raw database fetch for the documents
					$parent_docs_args = [
							'post_type' => 'docs',
							'parent' => 0,
							'sort_column' => 'menu_order',
					];

					// Ensure we respect the Hub filtering rules we built earlier
					if(isset($args['tax_query'])){
						$parent_docs_args['tax_query'] = $args['tax_query'];
					}

					$parent_docs = get_pages($parent_docs_args);

					if($parent_docs){
						// set all doc IDs to array by terms.
							foreach($parent_docs as $doc){
								$term = get_the_terms($doc, 'docs_category');
								$term_slug = 0;

								if((is_tax('docs_hub') || $is_hub_page) && !empty($term) && !is_wp_error($term) && !empty($matching_cats)){
									foreach($term as $t){
										if(in_array($t->term_id, $matching_cats)){
											$term_slug = $t->slug;
											break;
										}
									}
								} elseif($term && ! empty($term)){
									// just grab the first category slug if not on a Hub
									$term_slug = $term[0]->slug;
								}

								// Fallback to the first category if the slug wasn't set during the Hub check
								if($term_slug === 0 && $term && !empty($term)){
									$term_slug = $term[0]->slug;
							}

							// Drop the document ID into its designated category bucket
							$docs_by_cat[ $term_slug ][] = $doc->ID;
						}

						// add posts IDs in post__in.
						if(count($docs_by_cat) >= 2 || is_tax('docs_hub') || $is_hub_page){
							$args['post__in'] = array();
							foreach ($docs_by_cat as $docs){
								$args['post__in'] = array_merge($args['post__in'], $docs);
							}

							// If the filter removes everything, force "No Results"
							if(empty($args['post__in'])) {
								$args['post__in'] = array(0); 
							}

							$args['orderby'] = 'post__in';
						}
					}
				}
			}

			$wp_query = new WP_Query($args); // phpcs:ignore

		}

		return $default_file;
	}

	/**
	* Get an array of filenames to search for a given template.
	*
	* @param  string $default_file The default file name.
	* @return string[]
	*/
	private static function get_template_loader_files($default_file){
		$search_files = apply_filters('documentor_template_loader_files', array(), $default_file);

		if(is_page_template()){
			$search_files[] = get_page_template_slug();
		}

		$search_files[] = '/documentor/' . $default_file;
		return array_unique($search_files);
	}

	// Change the post permalink
	public static function permalink($post_link, $post, $leavename, $sample){
		
		// Only for docs type
		if($post->post_type == documentor()->post_type){
			//die(home_url('/docs').' - '.$post_link);
			
			$url = get_permalink(self::$docs_archive_id);
			
			// We need to clean extra parts in the docs
			$section = str_replace($url, '', $post_link);
			$section = str_replace(home_url(), '', $section); //in case the url dosent have custom post type
			$section = explode('/', trim($section, '/'));
			$count = count($section);
						
			//This is to reduce the URL length.
			if($count > 2){
				for($i = 1; $i < ($count - 1); $i++){
					unset($section[$i]);
				}
			}
			
			$post_link = $url.implode('/', $section);
			//die($post_link);
		}
		
		return $post_link;
	}
}

Documentor_Template_Loader::init();