Skip to content

Commit

Permalink
Merge pull request #2562 from actuallyakash/akash/quiz-resume
Browse files Browse the repository at this point in the history
Some more features for quiz resume.
  • Loading branch information
brianhogg authored Apr 3, 2024
2 parents a2a22a9 + 0e53043 commit 9dcbc25
Show file tree
Hide file tree
Showing 6 changed files with 131 additions and 8 deletions.
11 changes: 11 additions & 0 deletions assets/js/llms-quiz.js
Original file line number Diff line number Diff line change
Expand Up @@ -472,6 +472,12 @@
self.previous_question();
} );

// Bind exit event for quiz.
$( '#llms-quiz-nav' ).on( 'click', '#llms-exit-quiz', function( e ) {
e.preventDefault();
window.location.reload();
} );

if ( 'quiz_resume' === action ) {
data = {
action: 'quiz_resume',
Expand Down Expand Up @@ -515,6 +521,11 @@
self.start_quiz_timer( r.data.time_limit );
}

// Adding Exit Button in Layout if quiz is resumable.
if ( self.resumable ) {
$( '#llms-quiz-nav' ).append( '<button class="button llms-button-secondary" id="llms-exit-quiz" name="llms_exit_quiz">' + LLMS.l10n.translate( 'Exit Quiz' ) + '</button>' );
}

self.load_question( r.data.html );

} else if ( r.message ) {
Expand Down
4 changes: 4 additions & 0 deletions assets/scss/admin/_llms-table.scss
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,10 @@
}
}

.llms-clear-resumable-attempts {
float: left;
}

.llms-table-pagination {
float: right;
}
Expand Down
47 changes: 46 additions & 1 deletion includes/abstracts/abstract.llms.admin.table.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* @package LifterLMS/Abstracts/Classes
*
* @since 3.2.0
* @version 7.3.0
* @version [version]
*/

defined( 'ABSPATH' ) || exit;
Expand Down Expand Up @@ -566,6 +566,7 @@ public function get_table_filters_html() {
* @since 3.2.0
* @since 3.17.8 Unknown.
* @since 3.37.7 Use correct argument order for implode to fix php 7.4 deprecation.
* @since [version] Added button for clearing resumable attempts.
*
* @return string
*/
Expand Down Expand Up @@ -714,6 +715,10 @@ public function get_tfoot_html() {
<tfoot>
<tr>
<th colspan="<?php echo $this->get_columns_count(); ?>">
<?php if ( $this->has_resumable_attempts() ) : ?>
<?php echo $this->get_clear_resumable_attempts_button(); ?>
<?php endif; ?>

<?php if ( $this->is_exportable ) : ?>
<div class="llms-table-export">
<button class="llms-button-primary small" name="llms-table-export">
Expand Down Expand Up @@ -750,6 +755,46 @@ public function get_tfoot_html() {
return ob_get_clean();
}

/**
* Check if any quiz has resumable attempts.
*
* @since [version]
*
* @return bool
*/
public function has_resumable_attempts() {
if ( 'quizzes' === llms_filter_input( INPUT_GET, 'tab' ) && 'attempts' === llms_filter_input( INPUT_GET, 'stab' ) ) {
$admin_quiz_attempts = new LLMS_Controller_Admin_Quiz_Attempts();
$quizzes = $admin_quiz_attempts->get_resumable_attempts( $this->quiz_id );
return ! empty( $quizzes );
}
return false;
}

/**
* Get the HTML for the button to clear resumable attempts.
*
* @since [version]
*
* @return string
*/
public function get_clear_resumable_attempts_button() {
ob_start();
?>
<div class="llms-clear-resumable-attempts">
<form action="" method="POST">
<button class="llms-button-primary small" name="llms_quiz_resumable_attempt_action" type="submit" value="llms_clear_resumable_attempts">
<i class="fa fa-trash-o" aria-hidden="true"></i>
<?php _e( 'Clear resumable attempts', 'lifterlms' ); ?>
</button>
<input type="hidden" name="llms_quiz_id" value="<?php echo $this->quiz_id; ?>">
<?php wp_nonce_field( 'llms_quiz_attempt_actions', '_llms_quiz_attempt_nonce' ); ?>
</form>
</div>
<?php
return ob_get_clean();
}

/**
* Get a thead element for the table.
*
Expand Down
16 changes: 12 additions & 4 deletions includes/class.llms.query.quiz.attempt.php
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
<?php
/**
* Query LifterLMS Students for a given course / membership
* Query LifterLMS Students for a given course / membership.
*
* @package LifterLMS/Classes
*
* @since 3.16.0
* @version 6.0.0
* @version [version]
*/

defined( 'ABSPATH' ) || exit;
Expand Down Expand Up @@ -41,10 +41,11 @@ class LLMS_Query_Quiz_Attempt extends LLMS_Database_Query {
protected $id = 'quiz_attempt';

/**
* Retrieve default arguments for a student query
* Retrieve default arguments for a student query.
*
* @since 3.16.0
* @since 4.2.0 Added `exclude` default arg.
* @since [version] Added `can_be_resumed` default arg.
*
* @return array
*/
Expand All @@ -62,6 +63,7 @@ protected function get_default_args() {
'status_exclude' => array(),
'attempt' => null,
'exclude' => array(),
'can_be_resumed' => null,
);

$args = wp_parse_args( $args, parent::get_default_args() );
Expand Down Expand Up @@ -153,11 +155,12 @@ protected function prepare_query() {
}

/**
* SQL "where" clause for the query
* SQL "where" clause for the query.
*
* @since 3.16.0
* @since 3.35.0 Better SQL preparation.
* @since 4.2.0 Added `exclude` arg logic.
* @since [version] Added `can_be_resumed` arg logic.
*
* @return string
*/
Expand Down Expand Up @@ -200,6 +203,11 @@ protected function sql_where() {
$sql .= " AND status NOT IN ({$prepared})";
}

$can_be_resumed = $this->get( 'can_be_resumed' );
if ( '' !== $can_be_resumed ) {
$sql .= $wpdb->prepare( ' AND can_be_resumed = %d', $can_be_resumed );
}

return apply_filters( $this->get_filter( 'where' ), $sql, $this );

}
Expand Down
53 changes: 51 additions & 2 deletions includes/controllers/class.llms.controller.admin.quiz.attempts.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* @package LifterLMS/Controllers/Classes
*
* @since 3.16.0
* @version 5.9.0
* @version [version]
*/

defined( 'ABSPATH' ) || exit;
Expand All @@ -28,13 +28,14 @@ public function __construct() {
}

/**
* Run actions on form submission
* Run actions on form submission.
*
* @since 3.16.0
* @since 3.16.9 Unknown.
* @since 3.35.0 Sanitize `$_POST` data.
* @since 4.4.4 Made sure to exit after redirecting on attempt deletion.
* @since 5.9.0 Stop using deprecated `FILTER_SANITIZE_STRING`.
* @since [version] Added `llms_quiz_resumable_attempt_action` action and single resumable attempt delete.
*
* @return void
*/
Expand Down Expand Up @@ -68,9 +69,57 @@ public function maybe_run_actions() {
exit();
} elseif ( 'llms_attempt_grade' === $action && ( isset( $_POST['remarks'] ) || isset( $_POST['points'] ) ) ) {
$this->save_grade( $attempt );
} elseif ( 'llms_disable_resume_attempt' === $action ) {
$attempt->set( 'can_be_resumed', false );
$attempt->save();
}
}

// Clear all resumable attempts.
if ( isset( $_POST['llms_quiz_resumable_attempt_action'] ) ) {

$action = llms_filter_input( INPUT_POST, 'llms_quiz_resumable_attempt_action' );

if ( 'llms_clear_resumable_attempts' === $action ) {

$quiz_id = llms_filter_input( INPUT_POST, 'llms_quiz_id' );

if ( ! current_user_can( 'edit_post', $quiz_id ) ) {
return;
}

$resumable_attempts = $this->get_resumable_attempts( $quiz_id );

// Clear all resumable attempts.
foreach ( $resumable_attempts as $attempt_id ) {
$attempt = new LLMS_Quiz_Attempt( $attempt_id );
$attempt->set( 'can_be_resumed', false );
$attempt->save();
}
}
}
}

/**
* Get resumable attempts for a quiz.
*
* @since [version]
*
* @param int $quiz_id Quiz ID.
*/
public function get_resumable_attempts( $quiz_id ) {

// Query to get all resumable attempts.
$query = new LLMS_Query_Quiz_Attempt(
array(
'quiz_id' => $quiz_id,
'can_be_resumed' => true,
'status' => 'incomplete',
)
);

return wp_list_pluck( $query->get_results(), 'id' );

}

/**
Expand Down
8 changes: 7 additions & 1 deletion templates/admin/reporting/tabs/quizzes/attempt.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
* @since 3.16.0
* @since 3.17.3 Unknown.
* @since 5.3.0 Do not show the "Start a review" button, if there are no existing questions to review.
* @since [version] Add information on whether the attempt can be resumed or not.
* @since [version] Add information on whether the attempt can be resumed or not and disable resume attempt button.
*
* @param LLMS_Quiz_Attempt $attempt Quiz attempt object.
*/
Expand Down Expand Up @@ -159,6 +159,12 @@
</span>
</button>
<?php endif; ?>
<?php if ( $attempt->can_be_resumed() ) : // Show the clear resume attempt button only if quiz can be resumed. ?>
<button class="llms-button-secondary large" name="llms_quiz_attempt_action" type="submit" value="llms_disable_resume_attempt">
<i class="fa fa-ban" aria-hidden="true"></i>
<?php _e( 'Disable Resume Attempt', 'lifterlms' ); ?>
</button>
<?php endif; ?>
<button class="llms-button-danger large" name="llms_quiz_attempt_action" type="submit" value="llms_attempt_delete">
<i class="fa fa-trash-o" aria-hidden="true"></i>
<?php _e( 'Delete Attempt', 'lifterlms' ); ?>
Expand Down

0 comments on commit 9dcbc25

Please sign in to comment.