Instantly share code, notes, and snippets.
Last active
November 15, 2019 14:30
-
Star
0
(0)
You must be signed in to star a gist -
Fork
0
(0)
You must be signed in to fork a gist
-
Save actual-saurabh/7659fb5bfa21f3275510372fd71c4c33 to your computer and use it in GitHub Desktop.
Companion code for Navigation Model Tutorial/Recipe https://make.lifterlms.com/2019/11/15/improving-course-navigation-user-experience-part-3-implementing-the-navigation-model/
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Contains Navigation Action Class | |
*/ | |
defined( 'ABSPATH' ) || exit; | |
/** | |
* Class for calculating navigation actions | |
*/ | |
class LLMS_Nav_Actions { | |
/** | |
* Whether a lesson is free | |
* | |
* @var bool | |
*/ | |
private $is_free = false; | |
/** | |
* The current student's ID | |
* | |
* @var int | |
*/ | |
private $student_id = 0; | |
/** | |
* The current lesson | |
* | |
* @var LLMS_Lesson | |
*/ | |
private $lesson = false; | |
/** | |
* Information about current actions | |
* | |
* @var array | |
*/ | |
private $actions = array( | |
'previous' => array( | |
'key' => '', | |
'label' => '', | |
), | |
'next_primary' => array( | |
'key' => '', | |
'label' => '', | |
), | |
'next_secondary' => array(), | |
'assignment_id' => false, | |
'assignment_complete' => true, | |
'quiz_id'=> false, | |
'quiz_complete' => true, | |
'previous_id' => false, | |
'next_id' => false, | |
); | |
/** | |
* Dynamic labels for current actions | |
* | |
* @var array | |
*/ | |
private $labels = array(); | |
/** | |
* Previous lesson's ID | |
* | |
* @var bool|int False if no previous lesson | |
*/ | |
private $previous_id = false; | |
/** | |
* Next lesson's ID | |
* | |
* @var bool|int False if no next lesson | |
*/ | |
private $next_id = false; | |
/** | |
* Whether a lesson is complete | |
* | |
* @var bool | |
*/ | |
private $completed = false; | |
/** | |
* Whether lesson completion is allowed | |
* | |
* @var bool | |
*/ | |
private $completion_allowed = true; | |
/** | |
* Whether lesson has a quiz | |
* | |
* @var bool | |
*/ | |
private $has_quiz = false; | |
/** | |
* Whether lesson has an assignment | |
* | |
* @var bool | |
*/ | |
private $has_assignment = false; | |
/** | |
* Whether attached quiz is complete | |
* | |
* @var bool | |
*/ | |
private $quiz_complete = true; | |
/** | |
* Whether attached assignment is complete | |
* | |
* @var bool | |
*/ | |
private $assignment_complete = true; | |
/** | |
* Returns currently available actions. | |
* | |
* @param LLMS_Lesson $lesson The current lesson object | |
*/ | |
public function get_actions( $lesson ) { | |
// bail early if we can't initialise actions. | |
if ( ! $this->init( $lesson ) ) { | |
return false; | |
} | |
// set up adjacent lessons. | |
$this->setup_adjacents(); | |
// is the current user enrolled in this course? | |
$student_is_enrolled = llms_is_user_enrolled( $this->student_id, $lesson->get( 'parent_course' ) ); | |
// this is a free lesson being viewed by unenrolled users, visitors and and non-admin users | |
if ( $this->is_free && ! $student_is_enrolled && ! current_user_can( 'edit_post', $lesson_id )) { | |
// there are no secondary actions for free lessons, we're done! | |
return $this->actions; | |
} | |
/* | |
* at this point, the previous action is set up and done. | |
* the primary next action is either set to the next lesson or to the course (for the last lesson). | |
*/ | |
// setup completion actions | |
$this->setup_completion_actions(); | |
// if there are no quizzes or assignments, there are no more actions to set up and we are done! | |
if ( ! $this->has_completion_barriers() ) { | |
return $this->actions; | |
} | |
// setup quiz/assignment related actions. | |
$this->setup_barrier_actions(); | |
// we're done. all actions are setup | |
return $this->actions; | |
} | |
/** | |
* Initialises information needed for the class | |
* | |
* @param LLMS_Lesson $lesson Lesson object | |
*/ | |
private function init( $lesson ) { | |
// we can start setting up lesson information. | |
$this->lesson = $lesson; | |
// if the lesson is a free lesson. | |
$this->is_free = $this->lesson->is_free(); | |
// get the current student's id. | |
$student_id = get_current_user_id(); | |
// don't show to visitors if it isn't a free lesson even though it should never reach here. | |
if ( 0 === $student_id && false === $is_free ) { | |
return false; | |
} | |
// assign student ID to property | |
$this->student_id = $student_id; | |
// assign ID to a convenient variable. | |
$this->lesson_id = $this->lesson->get( 'id' ); | |
// initialise action labels. | |
$this->init_labels(); | |
// successfully initialised. | |
return true; | |
} | |
/** | |
* Initialises action labels | |
*/ | |
private function init_labels() { | |
// initialise action labels. | |
$this->labels = array( | |
'course' => array( | |
'previous' => __( 'Back to Course', 'lifterlms-navigation-lab' ), | |
'next_primary' => __( 'Back to Course', 'lifterlms-navigation-lab' ), | |
'next_secondary' => __( 'Back to Course without Completing', 'lifterlms-navigation-lab' ), | |
), | |
'lesson' => array( | |
'previous' => __( 'Previous Lesson', 'lifterlms-navigation-lab' ), | |
'next_primary' => __( 'Next Lesson', 'lifterlms-navigation-lab' ), | |
'next_secondary' => __( 'Next Lesson without Completing', 'lifterlms-navigation-lab' ), | |
), | |
// will never be a secondary next action or a previous action | |
'mark-complete' => array( | |
'next_primary' => __( 'Mark Complete & Go to Next Lesson', 'lifterlms-navigation-lab' ), | |
'next_primary_last' => __( 'Mark Complete & Complete Course', 'lifterlms-navigation-lab' ), | |
), | |
// will never be a primary next action or a previous action | |
'mark-incomplete' => array( | |
'next_secondary' => __('Mark Incomplete', 'lifterlms-navigation-lab' ), | |
), | |
// will never be a previous action | |
'quiz' => array( | |
'next_primary' => __( 'Take Quiz', 'lifterlms-navigation-lab' ), | |
'next_secondary' => __( 'Retake Quiz', 'lifterlms-navigation-lab' ), | |
), | |
// will never be a previous action | |
'assignment' => array( | |
'next_primary' => __( 'Complete Assignment', 'lifterlms-navigation-lab' ), | |
'next_secondary' => __( 'Complete Assignment', 'lifterlms-navigation-lab' ), | |
'next_secondary_complete' => __( 'Redo Assignment', 'lifterlms-navigation-lab' ), | |
), | |
); | |
} | |
/** | |
* Sets up basic previous/next lesson actions | |
*/ | |
private function setup_adjacents() { | |
$adjacents = array( 'previous', 'next' ); | |
foreach ( $adjacents as $adjacent ) { | |
// setup property name ('previous_id or next_id) | |
$adjacent_id = "{$adjacent}_id"; | |
// setup lesson method to call (get_previous_lesson or get_next_lesson) | |
$adjacent_method = "get_{$adjacent}_lesson"; | |
// setup property (previous_id or next_id) | |
$this->$adjacent_id = $this->actions[ $adjacent_id ] = $this->lesson->$adjacent_method(); | |
// whether it's going to be back to course or the previous/next lesson | |
$action_key = $this->get_adjacent_action_key( $this->$adjacent_id ); | |
// set up action accordingly | |
$this->actions[ $adjacent ]= $this->create_action( $adjacent, $action_key ); | |
// unset loop variables | |
unset( $adjacent_id ); | |
unset( $adjacent_method ); | |
unset( $action_key ); | |
} | |
} | |
/** | |
* Sets up the previous/next action key between course or lesson. | |
* | |
* @param bool|int $adjacent_id The id of the previous or next lesson. False on first or last lessons. | |
*/ | |
private function get_adjacent_action_key( $adjacent_id = false ) { | |
// this is the first lesson. | |
if ( ! $adjacent_id ) { | |
return 'course'; | |
} | |
// all other lessons.! llms_is_user_enrolled( get_current_user_id(), $lesson->get( 'parent_course' ) ) && ! current_user_can( 'edit_post', $lesson->get( 'id' ) ) | |
return 'lesson'; | |
} | |
/** | |
* Sets up mark complete/incomplete actions | |
*/ | |
private function setup_completion_actions() { | |
// setup lesson's completion status for the student | |
$this->setup_completion_info(); | |
// if complete | |
if ( $this->completed ) { | |
// the primary next action stays as navigation to next lesson as set up already. | |
// if a student is allowed to mark a lesson incomplete and retake it. | |
$retake_allowed = ( 'yes' === get_option( 'lifterlms_retake_lessons', 'no' ) || apply_filters( 'lifterlms_retake_lesson_' . $this->lesson->get( 'parent_course' ), false ) ); | |
// no action to add of modify if retaking a complete lesson isn't allowed. | |
if ( ! $retake_allowed ) { | |
return; | |
} | |
// only if retaking is allowed, set the mark-incomplete secondary action | |
$this->actions['next_secondary'][] = $this->create_action( 'next_secondary', 'mark-incomplete' ); | |
// otherwise, without a quiz or assignment there is no secondary action; only navigation to the next lesson. | |
return; | |
} | |
/* Lesson is incomplete, which means instead of the already set up next lesson or back to course action | |
* a mark complete button has to become the primary action. | |
* So, we need to swap the existing primary action to secondary | |
*/ | |
$this->swap_existing_primary_action(); | |
// setup the label depending on whether this is the last lesson | |
$label_key = $this->next_id ? 'next_primary' : 'next_primary_last'; | |
// set the primary next action to mark complete. this is default unless there's a quiz or assignment. | |
$this->actions['next_primary']= $this->create_action( 'next_secondary', 'mark-complete', $label_key ); | |
} | |
/** | |
* Sets up completion related information | |
*/ | |
private function setup_completion_info() { | |
// get the student object. | |
// see https://github.com/gocodebox/lifterlms/blob/3.36.5/includes/models/model.llms.student.php | |
$this->student = llms_get_student( $this->student_id ); | |
// if the lesson is already complete | |
$this->completed = $this->lesson->is_complete( $this->student_id ); | |
// only if a lesson is incomplete, check if there's a restriction. | |
if ( ! $this->completed ) { | |
// is completion restricted for any reason ( a required quiz or assignment is still to be completed ). | |
$this->completion_allowed = llms_allow_lesson_completion( $this->student_id, $this->lesson_id ); | |
} | |
} | |
/** | |
* Swaps existing primary action to a secondary one | |
*/ | |
private function swap_existing_primary_action() { | |
// get the primary action | |
$secondary_action = $this->actions['next_primary']; | |
// switch primary label of whatever that action is for the secondary | |
$secondary_action['label'] = $this->labels[ $secondary_action['key'] ]['next_secondary']; | |
$this->actions['next_secondary'][] = $secondary_action; | |
} | |
/** | |
* Checks if a lesson has a quiz or assignment attached | |
*/ | |
private function has_completion_barriers() { | |
// at this point, the primary and secondary next actions are set up for lessons that donot have quizzes or assignments. | |
// check if the lesson even has a quiz. | |
$this->has_quiz = $this->lesson->has_quiz(); | |
// if the assignment plugin is loaded, we can check that; if not, there can't be an assignment. | |
$this->has_assignment = function_exists( 'llms_lesson_has_assignment' ) ? llms_lesson_has_assignment( $this->lesson ) : false; | |
// if there's no quiz or assignment, there are no barriers to completion action | |
if ( ! $this->has_quiz && ! $this->has_assignment ) { | |
return false; | |
} | |
// otherwise there is a barrier and we need to setup more actions | |
return true; | |
} | |
/** | |
* Sets up quiz/assignment related actions | |
*/ | |
private function setup_barrier_actions() { | |
// setup quiz and assignment info | |
$this->setup_barrier_info(); | |
/* at this point, if the lesson is complete, next lesson action would be the primary action. | |
* if the lesson is incomplete, mark-complete would be the primary action and | |
* the next lesson action is already setup as the secondary action. | |
*/ | |
// if there's a quiz that hasn't been completed. | |
if ( $this->has_quiz && ! $this->quiz_complete ) { | |
// quiz becomes the primary next action instead of mark complete or next lesson | |
$this->actions['next_primary'] = $this->create_action( 'next_primary', 'quiz' ); | |
// maybe set an assignment as the secondary action. | |
$this->maybe_setup_assignment_incomplete_secondary_action(); | |
} | |
// there's either a completed quiz or no quiz at all. | |
if ( $this->has_quiz && $this->quiz_complete || ! $this->has_quiz ) { | |
$this->maybe_setup_quiz_secondary_action(); | |
/* We consider quizzes on a higher priority than assignments if both are present. | |
* This means that assignments could only become a primary action if a quiz is complete or there's no quiz | |
*/ | |
$this->maybe_setup_assignment_primary_action(); | |
} | |
$this->maybe_setup_assignment_complete_secondary_action(); | |
} | |
/** | |
* Sets up quiz and assignment related information | |
*/ | |
private function setup_barrier_info() { | |
/* at this point, the lesson either has a quiz or an assignment attached. it maybe complete or incomplete. | |
* so, we have multiple next actions whose the priority (primary or secondary) and order we now need to set up. | |
*/ | |
if ( $this->has_assignment ) { | |
$this->setup_assignment_info(); | |
} | |
if ( $this->has_quiz ) { | |
$this->setup_quiz_info(); | |
} | |
} | |
/** | |
* Sets up assignment related information | |
*/ | |
private function setup_assignment_info() { | |
$assignment = llms_lesson_get_assignment( $this->lesson ); | |
// setup assignment id for our action | |
$this->actions['assignment_id'] = $assignment_id = $assignment->get( 'id' ); | |
// get assignment submission | |
$submission = llms_student_get_assignment_submission( $assignment_id, $this->student_id ); | |
// is passing required? | |
$assignment_passing_required = llms_parse_bool( $this->lesson->get( 'require_assignment_passing_grade' ) ); | |
// if there is no submission | |
if ( $submission ) { | |
// passing is not required but there's no submissions yet. | |
// at least one attempt (passing or otherwise) is required!. | |
if ( ! $assignment_passing_required && ! $submission->is_complete() ) { | |
$this->actions['assignment_complete'] = false; | |
// passing is required and there's no attempts or the best attempt is not passing. | |
} elseif ( $assignment_passing_required && ! $submission->is_passing() ) { | |
$this->actions['assignment_complete'] = false; | |
} | |
} | |
$this->assignment_complete = $this->actions['assignment_complete']; | |
} | |
/** | |
* Sets up quiz related information | |
*/ | |
private function setup_quiz_info() { | |
// set up quiz ID. | |
$this->actions['quiz_id'] = $quiz_id = $this->lesson->get( 'quiz' ); | |
// get current student's best attempt. | |
$attempt = $this->student->quizzes()->get_best_attempt( $quiz_id ); | |
// is passing required? | |
$quiz_passing_required = llms_parse_bool( $this->lesson->get( 'require_passing_grade' ) ); | |
// passing is not required but there's not attempts yet | |
// at least one attempt (passing or otherwise) is required! | |
if ( ! $quiz_passing_required && ! $attempt ) { | |
$this->actions['quiz_complete'] = false; | |
// passing is required and there's no attempts or the best attempt is not passing | |
} elseif ( $quiz_passing_required && ( ! $attempt || ! $attempt->is_passing() ) ) { | |
$this->actions['quiz_complete'] = false; | |
} | |
$this->quiz_complete = $this->actions['quiz_complete']; | |
} | |
/** | |
* Conditionally sets up the quiz action as a secondary next action | |
*/ | |
private function maybe_setup_quiz_secondary_action() { | |
// bail if there's no quiz or the quiz isn't complete | |
if ( ! $this->has_quiz || ! $this->quiz_complete ) { | |
return; | |
} | |
// quiz is completed, don't change the primary action, make it the first secondary action | |
$quiz_action = $this->create_action( 'next_secondary', 'quiz' ); | |
// make it the first secondary action, before the next lesson and/or mark-incomplete action | |
$this->actions['next_secondary'][]= $quiz_action; | |
} | |
/** | |
* Conditionally sets up the assignment action as the primary next action | |
*/ | |
private function maybe_setup_assignment_primary_action() { | |
// nothing to do if there's no assignment or if it is complete | |
if ( ! $this->has_assignment || $this->assignment_complete ) { | |
return; | |
} | |
// make it the primary action | |
$this->actions['next_primary'] = $this->create_action( 'next_primary', 'assignment' ); | |
} | |
/** | |
* Conditionally sets up an incomplete assignment action as a secondary next action | |
*/ | |
private function maybe_setup_assignment_incomplete_secondary_action() { | |
// if there's an incomplete assignment as well. | |
if ( ! $this->has_assignment || $this->assignment_complete ) { | |
return; | |
} | |
// setup the assignment action | |
$assignment_action = $this->create_action( 'next_secondary', 'assignment' ); | |
// since it is incomplete, make it the first secondary action, before the next lesson and/or mark-incomplete action | |
array_unshift( $this->actions['next_secondary'], $assignment_action ); | |
} | |
/** | |
* Conditionally sets up a complete assignments action as a secondary next action | |
*/ | |
private function maybe_setup_assignment_complete_secondary_action() { | |
/* nothing to do if there's no assignment or if it is inccomplete | |
* in which case, it's already set up as a primary action | |
*/ | |
if ( ! $this->has_assignment || ! $this->assignment_complete ) { | |
return; | |
} | |
// make it the primary action | |
$this->actions['next_secondary'][] = $this->create_action( 'next_secondary', 'assignment', 'next_secondary_last' ); | |
} | |
/** | |
* Creates the action information with label | |
*/ | |
private function create_action( $type, $action_key, $label_key = false ) { | |
if ( empty( $type ) || empty( $action_key ) ) { | |
return; | |
} | |
if ( ! $label_key ) { | |
$label_key = $type; | |
} | |
$action = array( | |
'key' => $action_key, | |
'label' => $this->labels[ $action_key ][ $label_key ], | |
); | |
return $action; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Renders a navigation action. | |
* | |
* @param LLMS_Lesson $lesson The Lesson object | |
* @param string $action The current action | |
* @param bool|int $adjacent_id The previous or next lesson's ID | |
* @param bool $show_title Whether to display a title. False for secondary actions | |
* @param bool|int $barrier_id ID of a quiz or assignment, false if a lesson doesn't have them | |
* @param bool $barrier_status Completion status of an attached quiz or assignment | |
*/ | |
function _llms_nav_action_component( $lesson, $action, $adjacent_id = false, $show_title = false, $barrier_id = false, $barrier_status = true ) { | |
$action_key = $action['key']; | |
$action_label = $action['label']; | |
// don't show a title for secondary actions | |
if ( false === $show_title ) { | |
$action_title = ''; | |
} else{ | |
// if the action is back to course, display the course title | |
if ( 'course' === $action_key || ! $adjacent_id ) { | |
$title_id = $lesson->get_parent_course(); | |
} else if ( in_array( $action_key, array( 'assignment', 'quiz' ) ) ) { | |
// for quizzes and assignments, show their title instead of the next lesson | |
$title_id = $barrier_id; | |
} else { | |
// by default show the title of the adjacent lesson | |
$title_id = $adjacent_id; | |
} | |
$action_title = get_the_title( $title_id ); | |
} | |
switch ( $action_key ){ | |
case 'course': | |
llms_get_template( | |
'navigation/course-preview.php', | |
array( | |
'lesson' => $lesson, | |
'show_title' => $show_title, | |
'action_title' => $action_title, | |
'action_label' => $action_label, | |
) | |
); | |
break; | |
case 'lesson': | |
llms_get_template( | |
'navigation/lesson-preview.php', | |
array( | |
'adjacent_id' => $adjacent_id, | |
'show_title' => $show_title, | |
) | |
); | |
break; | |
case 'mark-complete': | |
case 'mark-incomplete': | |
$completion_action = str_replace( 'mark-', '', $action_key ); | |
llms_get_template( | |
'navigation/lesson-completion-button.php', | |
array( | |
'lesson' => $lesson, | |
'completion_action' => $completion_action, | |
'show_title' => $show_title, | |
'action_title' => $action_title, | |
'action_label' => $action_label, | |
) | |
); | |
break; | |
case 'quiz': | |
case 'assignment': | |
$action_link = esc_url( get_permalink( $barrier_id ) ); | |
$action_label = apply_filters( "lifterlms_start_{$action_key}_button_text", $action_label, $barrier_id, $lesson ); | |
$action_status_class = $barrier_status ? 'llms-complete' : 'llms-incomplete'; | |
llms_get_template( | |
'navigation/lesson-barrier-button.php', | |
array( | |
'lesson' => $lesson, | |
'action_key' => $action_key, | |
'show_title' => $show_title, | |
'action_title' => $action_title, | |
'action_label' => $action_label, | |
'action-link' => $action_link, | |
'action_status_class' => $action_status_class, | |
) | |
); | |
break; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
defined( 'ABSPATH' ) || exit; | |
// get global $post object. | |
global $post; | |
// get the LifterLMS object. | |
// see https://github.com/gocodebox/lifterlms/blob/3.36.5/includes/models/model.llms.lesson.php | |
$lesson = llms_get_post( $post ); | |
// bail, if this is not a LifterLMS lesson. | |
if ( ! $lesson || ! is_a( $lesson, 'LLMS_Lesson' ) ) { | |
return; | |
} | |
$nav_actions = llms_nav_get_actions( $lesson ); | |
?> | |
<nav class="llms-course-navigation"> | |
<div class="llms-course-nav-step llms-previous-step"> | |
<div class="llms-nav-action llms-prev-action"> | |
<?php llms_nav_action_component_previous( $lesson, $nav_actions ); ?> | |
</div> | |
</div> | |
<div class="llms-course-nav-step llms-next-step"> | |
<div class="llms-nav-action llms-next-action llms-next-action-primary"> | |
<?php llms_nav_action_component_next_primary( $lesson, $nav_actions ); ?> | |
</div> | |
<?php | |
if ( isset( $nav_actions[ 'next_secondary' ] ) ) { | |
foreach ( $nav_actions[ 'next_secondary' ] as $next_secondary ) { | |
?> | |
<div class="llms-nav-action llms-next-action llms-next-action-secondary"> | |
<?php llms_nav_action_component_next_secondary( $lesson, $nav_actions, $next_secondary ); ?> | |
</div> | |
<?php | |
} | |
} | |
?> | |
</div> | |
</nav> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Fetches navigation actions | |
* | |
* @param LLMS_Lesson The lesson object | |
*/ | |
function llms_nav_get_actions( $lesson ) { | |
$nav_actions = new LLMS_Nav_Actions(); | |
$actions = $nav_actions->get_actions( $lesson ); | |
return $actions; | |
} | |
/** | |
* Renders a navigation action. | |
* | |
* @param LLMS_Lesson $lesson The Lesson object | |
* @param string $action The current action | |
* @param bool|int $adjacent_id The previous or next lesson's ID | |
* @param bool $show_title Whether to display a title. False for secondary actions | |
* @param bool|int $barrier_id ID of a quiz or assignment, false if a lesson doesn't have them | |
* @param bool $barrier_status Completion status of an attached quiz or assignment | |
*/ | |
function _llms_nav_action_component( $lesson, $action, $adjacent_id = false, $show_title = false, $barrier_id = false, $barrier_status = true ) { | |
$action_key = $action['key']; | |
$action_label = $action['label']; | |
// don't show a title for secondary actions | |
if ( false === $show_title ) { | |
$action_title = ''; | |
} else{ | |
// if the action is back to course, display the course title | |
if ( 'course' === $action_key || ! $adjacent_id ) { | |
$title_id = $lesson->get_parent_course(); | |
} else if ( in_array( $action_key, array( 'assignment', 'quiz' ) ) ) { | |
// for quizzes and assignments, show their title instead of the next lesson | |
$title_id = $barrier_id; | |
} else { | |
// by default show the title of the adjacent lesson | |
$title_id = $adjacent_id; | |
} | |
$action_title = get_the_title( $title_id ); | |
} | |
switch ( $action_key ) { | |
case 'course': | |
?> | |
<div class="llms-nav-course llms-nav-action-wrapper"> | |
<a class="llms-lesson-link" href="<?php echo get_permalink( $lesson->get_parent_course() ); ?>"> | |
<section class="llms-main"> | |
<h6 class="llms-pre-text"><?php echo $action_label ?></h6> | |
<?php if ( $show_title ): ?> | |
<h5 class="llms-h5 llms-lesson-title"><?php echo $action_title; ?></h5> | |
<?php endif; ?> | |
</section> | |
</a> | |
</div> | |
<?php | |
break; | |
case 'lesson': | |
$adjacent_lesson = new LLMS_Lesson( $adjacent_id ); | |
$restrictions = llms_page_restricted( $adjacent_id, get_current_user_id() ); | |
$data_msg = $restrictions['is_restricted'] ? ' data-tooltip-msg="' . esc_html( strip_tags( llms_get_restriction_message( $restrictions ) ) ) . '"' : ''; | |
?> | |
<div class="llms-adjacent-lesson<?php echo $adjacent_lesson->get_preview_classes(); ?> llms-nav-action-wrapper"> | |
<a class="llms-lesson-link<?php echo $restrictions['is_restricted'] ? ' llms-lesson-link-locked' : ''; ?>" href="<?php echo ( ! $restrictions['is_restricted'] ) ? get_permalink( $adjacent_id ) : '#llms-lesson-locked'; ?>"<?php echo $data_msg; ?>> | |
<section class="llms-main"> | |
<h6 class="llms-pre-text"><?php echo $action_label; ?></h6> | |
<?php if ( $show_title ): ?> | |
<h5 class="llms-h5 llms-lesson-title"><?php echo get_the_title( $adjacent_id ); ?></h5> | |
<?php endif; ?> | |
</section> | |
</a> | |
</div> | |
<?php | |
break; | |
case 'mark-complete': | |
case 'mark-incomplete': | |
$completion_action = str_replace( 'mark-', '', $action_key ); | |
?> | |
<form action="" class="llms-<?php echo $completion_action; ?>-lesson-form llms-nav-action-wrapper" method="POST" name="mark_<?php echo $completion_action; ?>"> | |
<?php do_action( "lifterlms_before_mark_{$completion_action}_lesson" ); ?> | |
<input type="hidden" name="mark-<?php echo $completion_action; ?>" value="<?php echo esc_attr( $lesson->get( 'id' ) ); ?>" /> | |
<input type="hidden" name="action" value="mark_<?php echo $completion_action; ?>" /> | |
<?php wp_nonce_field( "mark_{$completion_action}" ); ?> | |
<button id="llms_mark_<?php echo $completion_action; ?>" class="llms-button-action auto button" name="mark_<?php echo $completion_action; ?>" type="submit"> | |
<section class="llms-main"> | |
<h6 class="llms-pre-text"><?php echo apply_filters( "lifterlms_mark_lesson_{$completion_action}_button_text", $action_label, $lesson ); ?></h6> | |
<?php if ( $show_title ): ?> | |
<h5 class="llms-h5 llms-lesson-title"><?php echo $action_title; ?></h5> | |
<?php endif; ?> | |
</section> | |
</button> | |
<?php do_action( "lifterlms_after_mark_{$completion_action}_lesson" ); ?> | |
</form> | |
<?php | |
break; | |
case 'quiz': | |
case 'assignment': | |
$action_link = esc_url( get_permalink( $barrier_id ) ); | |
$action_label = apply_filters( "lifterlms_start_{$action_key}_button_text", $action_label, $barrier_id, $lesson ); | |
$action_status_class = $barrier_status ? 'llms-complete' : 'llms-incomplete'; | |
?> | |
<div class="llms-nav-action-wrapper llms-nav-barrier <?php echo $action_status_class; ?>"> | |
<?php do_action( "llms_before_start_{$action_key}_button" ); ?> | |
<a class="llms-button-action auto button" id="llms_start_<?php echo $action_key; ?>" href="<?php echo $action_link; ?>"> | |
<section class="llms-main"> | |
<h6 class="llms-pre-text"><?php echo $action_label; ?></h6> | |
<?php if ( $show_title ): ?> | |
<h5 class="llms-h5 llms-lesson-title"><?php echo $action_title; ?></h5> | |
<?php endif; ?> | |
</section> | |
</a> | |
<?php do_action( "llms_after_start_{$action_key}_button" ); ?> | |
</div> | |
<?php | |
break; | |
} | |
} | |
/** | |
* Renders next navigation actions | |
* | |
* @param LLMS_Lesson $lesson The lesson object | |
* @param string $action The specific navigation action | |
* @param string $type The type of next navigation action, primary or secondary | |
* @param array $nav_actions Array of navigation actions and related information | |
*/ | |
function _llms_nav_action_component_next( $lesson, $action, $type, $nav_actions ) { | |
$barrier_id = false; | |
$barrier_status = true; | |
$action_key = $action['key']; | |
if ( in_array( $action_key, array( 'quiz', 'assignment') ) ) { | |
$barrier_id = $nav_actions[ "{$action_key}_id" ]; | |
$barrier_status = $nav_actions[ "{$action_key}_complete" ]; | |
} | |
$next_id = $nav_actions['next_id']; | |
$show_title = ( 'next_secondary' !== $type ) ? true : false; | |
_llms_nav_action_component( $lesson, $action, $next_id, $show_title, $barrier_id, $barrier_status ); | |
} | |
/** | |
* Renders the previous navigation action | |
* | |
* @param LLMS_Lesson $lesson The lesson object | |
* @param array $nav_actions Array of navigation actions and related information | |
*/ | |
function llms_nav_action_component_previous( $lesson, $nav_actions ) { | |
$previous_id = $nav_actions['previous_id']; | |
$action = $nav_actions['previous']; | |
_llms_nav_action_component( $lesson, $action, $previous_id, true ); | |
} | |
/** | |
* Renders the primary next navigation action | |
* | |
* @param LLMS_Lesson $lesson The lesson object | |
* @param array $nav_actions Array of navigation actions and related information | |
*/ | |
function llms_nav_action_component_next_primary( $lesson, $nav_actions ) { | |
$action = $nav_actions['next_primary']; | |
_llms_nav_action_component_next( $lesson, $action, 'next_primary', $nav_actions ); | |
} | |
/** | |
* Renders the secondary next navigation action | |
* | |
* @param LLMS_Lesson $lesson The lesson object | |
* @param array $nav_actions Array of navigation actions and related information | |
* @param string $action The specific navigation action | |
*/ | |
function llms_nav_action_component_next_secondary( $lesson, $nav_actions, $action ) { | |
_llms_nav_action_component_next( $lesson, $action, 'next_secondary', $nav_actions ); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
.llms-course-navigation{ | |
display: flex; | |
justify-content: space-between; | |
align-items: stretch; | |
.llms-course-nav-step { | |
flex-basis: 50%; | |
padding: 0 10px; | |
.llms-nav-action{ | |
a, .button, button{ | |
background: #e6e6e6; | |
color:#b3b3b3; | |
display: block; | |
width: 100%; | |
padding:20px; | |
text-decoration:none; | |
font-size:1rem; | |
transition: all 0.5s ease; | |
position:relative; | |
h6.llms-pre-text { | |
color:inherit; | |
font-size: 0.9rem; | |
margin:0; | |
padding:0; | |
font-weight:bold; | |
line-height: 1; | |
} | |
h5.llms-lesson-title{ | |
color: #808080; | |
font-size: 1.4rem; | |
margin:0; | |
padding:0; | |
margin-top:5px; | |
font-weight: normal; | |
line-height:1.2rem; | |
} | |
&:hover{ | |
background: #4d4d4d; | |
h5.llms-lesson-title{ | |
color:#e6e6e6; | |
} | |
} | |
} | |
} /*.llms-course-nav-step */ | |
&.llms-previous-step{ | |
padding-left:0; | |
text-align:left; | |
a, .button, button{ | |
&:before{ | |
content:"\2190"; | |
width:30px; | |
display:none; | |
height:30px; | |
position: absolute; | |
left:10px; | |
top:30px; | |
font-weight:700; | |
font-size: 1.2rem; | |
text-align:center; | |
line-height:30px; | |
} | |
&:hover{ | |
padding-left:40px; | |
&:before{ | |
display:block; | |
animation: appear 0.6s ease; | |
} | |
} | |
} | |
.llms-nav-course a:before{ | |
content:"\21a9"; | |
} | |
} | |
&.llms-next-step{ | |
padding-right:0; | |
text-align:right; | |
.llms-nav-action{ | |
a, .button, button{ | |
text-align:right; | |
&:after{ | |
content:"\2192"; | |
width:30px; | |
display:none; | |
height:30px; | |
position: absolute; | |
right:10px; | |
top:30px; | |
font-weight:700; | |
font-size: 1.2rem; | |
text-align:center; | |
line-height:30px; | |
} | |
&:hover:after{ | |
display:block; | |
animation: appear 0.6s ease; | |
} | |
&#llms_mark_complete:after{ | |
content:"\2713"; | |
} | |
&#llms_mark_incomplete:after{ | |
content:"\2718"; | |
} | |
&#llms_start_quiz:after{ | |
content: "\bb"; | |
} | |
&#llms_start_assignment:after{ | |
content: "\2611"; | |
} | |
} | |
&.llms-next-action-primary{ | |
a, .button, button{ | |
background: #0073bb; | |
color:#99c7e4; | |
h5.llms-lesson-title { | |
color: #e6f1f8; | |
} | |
&:hover{ | |
padding-right:40px; | |
background: #003a5e; | |
h5.llms-lesson-title{ | |
color:#fff; | |
} | |
} | |
} | |
} | |
&.llms-next-action-secondary{ | |
a, .button, button{ | |
margin-top:5px; | |
padding: 10px; | |
background: transparent; | |
color: #0073bb; | |
&:after{ | |
top:0; | |
right:0; | |
} | |
&:hover{ | |
padding-right:30px; | |
background: #99c7e4; | |
color:#003a5e; | |
} | |
} | |
} /*.llms-next-action-secondary */ | |
} /*.llms-nav-action */ | |
.llms-nav-course a:after{ | |
content:"\21aa"; | |
} | |
} /*.llms-step */ | |
} /*.llms-course-nav-step */ | |
} /*.llms-course-navigation */ | |
@keyframes appear { | |
0% { opacity: 0; -transform: translateX(-100%); } | |
100% { opacity: 1; transform: translateX(0); } | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
.llms-course-navigation{ | |
display: flex; | |
justify-content: space-between; | |
align-items: stretch; | |
.llms-course-nav-step { | |
flex-basis: 50%; | |
padding: 0 10px; | |
.llms-nav-action{ | |
a, .button, button{ | |
background: #e6e6e6; | |
color: #808080; | |
display: block; | |
width: 100%; | |
padding:20px; | |
text-decoration:none; | |
font-size:1rem; | |
transition: all 0.5s ease; | |
h6.llms-pre-text { | |
color:#b3b3b3; | |
font-size: 0.9rem; | |
margin:0; | |
padding:0; | |
font-weight:bold; | |
line-height: 1; | |
} | |
h5.llms-lesson-title{ | |
color:inherit; | |
font-size: 1.4rem; | |
margin:0; | |
padding:0; | |
margin-top:5px; | |
font-weight: normal; | |
line-height:1.2rem; | |
} | |
&:hover{ | |
background: #4d4d4d; | |
h5.llms-lesson-title{ | |
color:#e6e6e6; | |
} | |
} | |
} | |
} /*.llms-course-nav-step */ | |
&.llms-previous-step{ | |
padding-left:0; | |
text-align:left; | |
a, .button, button{ | |
&:hover{ | |
padding-left:40px; | |
} | |
} | |
} | |
&.llms-next-step{ | |
padding-right:0; | |
text-align:right; | |
.llms-nav-action{ | |
a, .button, button{ | |
text-align:right; | |
} | |
&.llms-next-action-primary{ | |
a, .button, button{ | |
background: #0073bb; | |
color: #e6f1f8; | |
h6.llms-pre-text { | |
color:#99c7e4; | |
} | |
&:hover{ | |
padding-right:40px; | |
background: #003a5e; | |
h5.llms-lesson-title{ | |
color:#fff; | |
} | |
} | |
} | |
} | |
&.llms-next-action-secondary{ | |
a, .button, button{ | |
margin-top:5px; | |
padding: 10px; | |
background: transparent; | |
h6.llms-pre-text { | |
color: #0073bb; | |
} | |
&:hover{ | |
padding-right:20px; | |
background: #99c7e4; | |
h6.llms-pre-text { | |
color:#003a5e; | |
} | |
} | |
} | |
} /*.llms-next-action-secondary */ | |
} /*.llms-nav-action */ | |
} /*.llms-step */ | |
} /*.llms-course-nav-step */ | |
} /*.llms-course-navigation */ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
.llms-course-navigation{ | |
display: flex; | |
justify-content: space-between; | |
align-items: stretch; | |
.llms-course-nav-step { | |
flex-basis: 50%; | |
padding: 0 10px; | |
.llms-nav-action{ | |
a, .button, button{ | |
background: #e6e6e6; | |
color: #808080; | |
display: block; | |
width: 100%; | |
padding:20px; | |
text-decoration:none; | |
font-size:1rem; | |
transition: all 0.5s ease; | |
h6.llms-pre-text { | |
color:#b3b3b3; | |
font-size: 0.9rem; | |
margin:0; | |
padding:0; | |
font-weight:bold; | |
line-height: 1; | |
} | |
h5.llms-lesson-title{ | |
color:inherit; | |
font-size: 1.4rem; | |
margin:0; | |
padding:0; | |
margin-top:5px; | |
font-weight: normal; | |
line-height:1.2rem; | |
} | |
&:hover{ | |
background: #4d4d4d; | |
h5.llms-lesson-title{ | |
color:#e6e6e6; | |
} | |
} | |
} | |
} /*.llms-course-nav-step */ | |
&.llms-previous-step{ | |
padding-left:0; | |
text-align:left; | |
} | |
&.llms-next-step{ | |
padding-right:0; | |
text-align:right; | |
.llms-nav-action{ | |
a, .button, button{ | |
text-align:right; | |
} | |
&.llms-next-action-primary{ | |
a, .button, button{ | |
background: #0073bb; | |
color: #e6f1f8; | |
h6.llms-pre-text { | |
color:#99c7e4; | |
} | |
&:hover{ | |
background: #003a5e; | |
h5.llms-lesson-title{ | |
color:#fff; | |
} | |
} | |
} | |
} | |
&.llms-next-action-secondary{ | |
a, .button, button{ | |
margin-top:5px; | |
padding: 10px; | |
background: transparent; | |
h6.llms-pre-text { | |
color: #0073bb; | |
} | |
&:hover{ | |
background: #99c7e4; | |
h6.llms-pre-text { | |
color:#003a5e; | |
} | |
} | |
} | |
} /*.llms-next-action-secondary */ | |
} /*.llms-nav-action */ | |
} /*.llms-step */ | |
} /*.llms-course-nav-step */ | |
} /*.llms-course-navigation */ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment