File Manager
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();