<?php
if ( ! defined( 'ABSPATH' ) ) {
exit; // security check, don't load file outside WP
}
/**
* Sensei Template Class
*
* Handles all Template loading and redirecting functionality.
*
* @package Views
* @author Automattic
*
* @since 1.9.0
*/
class Sensei_Templates {
/**
* Load the template files from within sensei/templates/ or the the theme if overrided within the theme.
*
* @since 1.9.0
* @param string $slug
* @param string $name default: ''
*
* @return void
*/
public static function get_part( $slug, $name = '' ) {
$template = '';
$plugin_template_url = Sensei()->template_url;
$plugin_template_path = Sensei()->plugin_path() . '/templates/';
// Look in yourtheme/slug-name.php and yourtheme/sensei/slug-name.php
if ( $name ) {
$template = locate_template( array( "{$slug}-{$name}.php", "{$plugin_template_url}{$slug}-{$name}.php" ) );
}
// Get default slug-name.php
if ( ! $template && $name && file_exists( $plugin_template_path . "{$slug}-{$name}.php" ) ) {
$template = $plugin_template_path . "{$slug}-{$name}.php";
}
// If template file doesn't exist, look in yourtheme/slug.php and yourtheme/sensei/slug.php
if ( ! $template ) {
$template = locate_template( array( "{$slug}.php", "{$plugin_template_url}{$slug}.php" ) );
}
if ( $template ) {
load_template( $template, false );
}
}
/**
* Get the template.
*
* @since 1.9.0
*
* @param $template_name
* @param array $args
* @param string $template_path
* @param string $default_path
*/
public static function get_template( $template_name, $args = array(), $template_path = '', $default_path = '' ) {
if ( $args && is_array( $args ) ) {
extract( $args );
}
$located = self::locate_template( $template_name, $template_path, $default_path );
if ( ! empty( $located ) ) {
/**
* Fires before the template part is loaded.
*
* @hook sensei_before_template_part
*
* @param {string} $template_name The name of the template.
* @param {string} $template_path The path to the template.
* @param {string} $located The located template.
*/
do_action( 'sensei_before_template_part', $template_name, $template_path, $located );
include $located;
/**
* Fires after the template part is loaded.
*
* @hook sensei_after_template_part
*
* @param {string} $template_name The name of the template.
* @param {string} $template_path The path to the template.
* @param {string} $located The located template.
*/
do_action( 'sensei_after_template_part', $template_name, $template_path, $located );
}
}
/**
* Check if the template file exists. A wrapper for WP locate_template.
*
* @since 1.9.0
*
* @param $template_name
* @param string $template_path
* @param string $default_path
*
* @return mixed|void
*/
public static function locate_template( $template_name, $template_path = '', $default_path = '' ) {
if ( ! $template_path ) {
$template_path = Sensei()->template_url;
}
if ( ! $default_path ) {
$default_path = Sensei()->plugin_path() . 'templates/';
}
// Look within passed path within the theme - this is priority
$template = locate_template(
array(
$template_path . $template_name,
$template_name,
)
);
// Get default template
if ( ! $template ) {
$template = $default_path . $template_name;
}
// return nothing for file that do not exist
if ( ! file_exists( $template ) ) {
$template = '';
}
/**
* Filter located template.
*
* @hook sensei_locate_template
*
* @param {string} $template The located template.
* @param {string} $template_name The template name.
* @param {string} $template_path The template path.
* @return {string} Filetered located template.
*/
$template = apply_filters( 'sensei_locate_template', $template, $template_name, $template_path );
// Return what we found
return $template;
}
/**
* Determine which Sensei template to load based on the
* current page context.
*
* @since 1.0
*
* @param string $template
* @return string $template
*/
public static function template_loader( $template = '' ) {
global $wp_query, $email_template;
$find = array( 'sensei.php' );
$file = '';
/**
* Filters if Sensei templates and content wrappers should be used. For development purposes.
*
* @access private
*
* @since 3.6.0
*
* @hook sensei_use_sensei_template
*
* @param {bool} $use_templates Whether to use Sensei templates for the request.
* @return {bool} Whether to use Sensei templates for the request.
*/
if ( ! apply_filters( 'sensei_use_sensei_template', true ) && ! isset( $email_template ) ) {
return $template;
}
if ( isset( $email_template ) && $email_template ) {
$file = 'emails/' . $email_template;
$find[] = $file;
$find[] = Sensei()->template_url . $file;
} elseif ( Sensei_Unsupported_Themes::get_instance()->is_handling_request() ) {
/*
* If our unsupported theme renderer is handling the request, we do
* not need to find a custom template.
*/
$file = null;
} elseif ( is_single() && get_post_type() == 'course' ) {
// possible backward compatible template include if theme overrides content-single-course.php
// this template was removed in 1.9.0 and code all moved into the main single-course.php file
self::locate_and_load_template_overrides( Sensei()->template_url . 'content-single-course.php', true );
$file = 'single-course.php';
$find[] = $file;
$find[] = Sensei()->template_url . $file;
} elseif ( is_single() && get_post_type() == 'lesson' ) { // check
// possible backward compatible template include if theme overrides content-single-lesson.php
// this template was removed in 1.9.0 and code all moved into the main single-lesson.php file
self::locate_and_load_template_overrides( Sensei()->template_url . 'content-single-lesson.php', true );
$file = 'single-lesson.php';
$find[] = $file;
$find[] = Sensei()->template_url . $file;
} elseif ( is_single() && get_post_type() == 'quiz' ) { // check
// possible backward compatible template include if theme overrides content-single-quiz.php
// this template was removed in 1.9.0 and code all moved into the main single-quiz.php file
self::locate_and_load_template_overrides( Sensei()->template_url . 'content-single-quiz.php', true );
$file = 'single-quiz.php';
$find[] = $file;
$find[] = Sensei()->template_url . $file;
} elseif ( is_single() && get_post_type() == 'sensei_message' ) { // check
// possible backward compatible template include if theme overrides content-single-message.php
// this template was removed in 1.9.0 and code all moved into the main single-message.php file
self::locate_and_load_template_overrides( Sensei()->template_url . 'content-single-message.php', true );
$file = 'single-message.php';
$find[] = $file;
$find[] = Sensei()->template_url . $file;
} elseif ( is_post_type_archive( 'course' )
|| is_page( Sensei()->get_page_id( 'courses' ) )
|| is_tax( 'course-category' ) ) {
// possible backward compatible template include if theme overrides 'taxonomy-course-category'
// this template was removed in 1.9.0 and replaced by archive-course.php
self::locate_and_load_template_overrides( Sensei()->template_url . 'taxonomy-course-category.php' );
$file = 'archive-course.php';
$find[] = $file;
$find[] = Sensei()->template_url . $file;
} elseif ( is_post_type_archive( 'sensei_message' ) ) {
$file = 'archive-message.php';
$find[] = $file;
$find[] = Sensei()->template_url . $file;
} elseif ( is_tax( 'lesson-tag' ) || is_post_type_archive( 'lesson' ) ) {
// possible backward compatible template include if theme overrides 'taxonomy-lesson-tag.php'
// this template was removed in 1.9.0 and replaced by archive-lesson.php
self::locate_and_load_template_overrides( Sensei()->template_url . 'taxonomy-lesson-tag.php' );
$file = 'archive-lesson.php';
$find[] = $file;
$find[] = Sensei()->template_url . $file;
} elseif ( isset( $wp_query->query_vars['learner_profile'] ) ) {
// Override for sites with static home page
$wp_query->is_home = false;
$file = 'learner-profile.php';
$find[] = $file;
$find[] = Sensei()->template_url . $file;
} elseif ( isset( $wp_query->query_vars['course_results'] ) ) {
// Override for sites with static home page
$wp_query->is_home = false;
$file = 'course-results.php';
$find[] = $file;
$find[] = Sensei()->template_url . $file;
} elseif ( is_author()
&& Sensei_Teacher::is_a_teacher( get_query_var( 'author' ) )
&& ! user_can( get_query_var( 'author' ), 'manage_options' ) ) {
$file = 'teacher-archive.php';
$find[] = $file;
$find[] = Sensei()->template_url . $file;
} // Load the template file
// if file is present set it to be loaded otherwise continue with the initial template given by WP
if ( $file ) {
$template = locate_template( $find );
if ( ! $template ) {
$template = Sensei()->plugin_path() . '/templates/' . $file;
}
}
return $template;
}
/**
* This function loads the no-permissions template for users with no access
* if a Sensei template was loaded.
*
* This function doesn't determine the permissions. Permissions must be determined
* before loading this function as it only gets the template.
*
* This function also checks the user theme for overrides to ensure the right template
* file is returned.
*
* @since 1.9.0
*/
public static function get_no_permission_template() {
// possible backward compatible template loading
// this template was removed in 1.9.0 and code all moved into the no-permissions.php file
self::locate_and_load_template_overrides( Sensei()->template_url . 'content-no-permissions.php', true );
$file = 'no-permissions.php';
$find = [];
$find[] = $file;
$find[] = Sensei()->template_url . $file;
$template = locate_template( $find );
if ( ! $template ) {
$template = Sensei()->plugin_path() . '/templates/' . $file;
}
// set a global constant so that we know that we're in this template
define( 'SENSEI_NO_PERMISSION', true );
return $template;
}
/**
* This function is specifically created for loading template files from the theme.
*
* This function checks if the user has overwritten the templates like in their theme. If they have it in their theme it will load the header and the footer
* around the singular content file from their theme and exit.
*
* If none is found this function will do nothing. If a template is found this funciton
* will exit execution of the script an not continue.
*
* @since 1.9.0
* @param string $template
* @param bool $load_header_footer should the file be wrapped in between header and footer? Default: true
*/
public static function locate_and_load_template_overrides( $template = '', $load_header_footer = false ) {
$found_template = locate_template( array( $template ) );
if ( $found_template ) {
if ( $load_header_footer ) {
get_sensei_header();
include $found_template;
get_sensei_footer();
} else {
include $found_template;
}
exit;
}
}
/**
* A generic function for echoing the post title
*
* @since 1.9.0
* @param WP_Post $post
*/
public static function the_title( $post ) {
// ID passed in
if ( is_numeric( $post ) ) {
$post = get_post( $post );
}
/**
* Filter the template html tag for the title
*
* @since 1.9.0
*
* @hook sensei_the_title_html_tag
*
* @param {string} $title_html_tag HTML tag for title, default is 'h3'.
* @return {string} Filtered HTML tag for title.
*/
$title_html_tag = apply_filters( 'sensei_the_title_html_tag', 'h3' );
/**
* Filter the title classes
*
* @since 1.9.0
*
* @hook sensei_the_title_classes
*
* @param {string} $title_classes Title classes, defaults to `{$post_type}-title`.
* @return {string} Filtered title classes.
*/
$title_classes = apply_filters( 'sensei_the_title_classes', $post->post_type . '-title' );
$html = '';
$html .= '<' . $title_html_tag . ' class="' . $title_classes . '" >';
$html .= '<a href="' . get_permalink( $post->ID ) . '" >';
/**
* Alters the course title
*
* @since 1.9.16
*
* @hook sensei_course_the_title
*
* @param {string} $course_title The Course Title.
* @return {string} Filtered course title.
*/
$course_title = (string) apply_filters( 'sensei_course_the_title', $post->post_title );
$html .= $course_title;
$html .= '</a>';
$html .= '</' . $title_html_tag . '>';
echo wp_kses_post( $html );
}
/**
* Fire the sensei_complete_course action.
*
* This is just a backwards compatible function to add the action
* to a template. This should not be used as the function from this
* hook will be added directly to my-courses page via one of the hooks there.
*
* @since 1.9.0
*/
public static function fire_sensei_complete_course_hook() {
/**
* Fires when a course is completed.
*
* @hook sensei_complete_course
*/
do_action( 'sensei_complete_course' );
} //fire_sensei_complete_course_hook
/**
* Fire the frontend message hook
*
* @since 1.9.0
*/
public static function fire_frontend_messages_hook() {
/**
* Fires when the frontend messages are displayed.
*
* @hook sensei_frontend_messages
*/
do_action( 'sensei_frontend_messages' );
}
}