Version Description
16 October, 2019 =
Fixed: quiz question sortable sorting item
Improved: quiz draggable answer drop accessibility
Fixed: prevented fatal error in single quiz question with no option and trying to finish quiz.
Download this release
Release Info
Developer | themeum |
Plugin | Tutor LMS – eLearning and online course solution |
Version | 1.4.4 |
Comparing to | |
See all releases |
Code changes from version 1.4.3 to 1.4.4
- assets/js/tutor-front.js +21 -3
- classes/Quiz.php +67 -62
- classes/Utils.php +2 -1
- readme.txt +7 -1
- tutor.php +2 -2
assets/js/tutor-front.js
CHANGED
@@ -515,7 +515,7 @@ jQuery(document).ready(function($){
|
|
515 |
function init_quiz_builder() {
|
516 |
if (jQuery().sortable) {
|
517 |
$(".tutor-quiz-answers-wrap").sortable({
|
518 |
-
|
519 |
start: function (e, ui) {
|
520 |
ui.placeholder.css('visibility', 'visible');
|
521 |
},
|
@@ -526,8 +526,7 @@ jQuery(document).ready(function($){
|
|
526 |
|
527 |
$(".quiz-draggable-rand-answers, .quiz-answer-matching-droppable").sortable({
|
528 |
connectWith: ".quiz-answer-matching-droppable",
|
529 |
-
placeholder: "drop-hover"
|
530 |
-
|
531 |
}).disableSelection();
|
532 |
}
|
533 |
}
|
@@ -591,6 +590,25 @@ jQuery(document).ready(function($){
|
|
591 |
$that.closest('.tutor-quiz-answers-wrap').find('.characters_remaining').html(remaining);
|
592 |
});
|
593 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
594 |
/**
|
595 |
* Add to cart in guest mode, show login form
|
596 |
*
|
515 |
function init_quiz_builder() {
|
516 |
if (jQuery().sortable) {
|
517 |
$(".tutor-quiz-answers-wrap").sortable({
|
518 |
+
handle: ".answer-sorting-bar",
|
519 |
start: function (e, ui) {
|
520 |
ui.placeholder.css('visibility', 'visible');
|
521 |
},
|
526 |
|
527 |
$(".quiz-draggable-rand-answers, .quiz-answer-matching-droppable").sortable({
|
528 |
connectWith: ".quiz-answer-matching-droppable",
|
529 |
+
placeholder: "drop-hover",
|
|
|
530 |
}).disableSelection();
|
531 |
}
|
532 |
}
|
590 |
$that.closest('.tutor-quiz-answers-wrap').find('.characters_remaining').html(remaining);
|
591 |
});
|
592 |
|
593 |
+
/**
|
594 |
+
*
|
595 |
+
* @type {jQuery}
|
596 |
+
*
|
597 |
+
* Improved Quiz draggable answers drop accessibility
|
598 |
+
* Answers draggable wrap will be now same height.
|
599 |
+
*
|
600 |
+
* @since v.1.4.4
|
601 |
+
*/
|
602 |
+
var countDraggableAnswers = $('.quiz-draggable-rand-answers').length;
|
603 |
+
if (countDraggableAnswers){
|
604 |
+
$('.quiz-draggable-rand-answers').each(function(){
|
605 |
+
var $that = $(this);
|
606 |
+
var draggableDivHeight = $that.height();
|
607 |
+
|
608 |
+
$that.css({"height": draggableDivHeight});
|
609 |
+
});
|
610 |
+
}
|
611 |
+
|
612 |
/**
|
613 |
* Add to cart in guest mode, show login form
|
614 |
*
|
classes/Quiz.php
CHANGED
@@ -209,91 +209,96 @@ class Quiz {
|
|
209 |
}
|
210 |
|
211 |
$quiz_answers = tutor_utils()->avalue_dot('quiz_question', $attempt_answers);
|
|
|
212 |
$total_marks = 0;
|
213 |
-
foreach ($quiz_answers as $question_id => $answers){
|
214 |
-
$question = tutor_utils()->get_quiz_question_by_id($question_id);
|
215 |
-
$question_type = $question->question_type;
|
216 |
|
217 |
-
|
218 |
-
$given_answer = '';
|
219 |
|
220 |
-
|
|
|
|
|
221 |
|
222 |
-
|
223 |
-
|
224 |
|
225 |
-
|
226 |
|
227 |
-
|
228 |
-
|
229 |
-
if (maybe_serialize($get_original_answers) == $given_answer){
|
230 |
-
$is_answer_was_correct = true;
|
231 |
-
}
|
232 |
|
233 |
-
|
234 |
|
235 |
-
|
236 |
-
|
|
|
|
|
|
|
237 |
|
238 |
-
|
239 |
-
$gap_answer = (array) explode('|', $get_original_answer->answer_two_gap_match);
|
240 |
|
241 |
-
|
242 |
-
|
243 |
-
$is_answer_was_correct = true;
|
244 |
-
}
|
245 |
|
246 |
-
|
|
|
247 |
|
248 |
-
|
|
|
|
|
|
|
249 |
|
250 |
-
|
251 |
|
252 |
-
|
253 |
-
$given_answer = maybe_serialize($given_answer);
|
254 |
|
255 |
-
|
256 |
-
$get_original_answers = array_map('sanitize_text_field', $get_original_answers);
|
257 |
|
258 |
-
|
259 |
-
|
260 |
-
}
|
261 |
|
262 |
-
|
263 |
-
|
264 |
|
265 |
-
|
266 |
-
|
267 |
-
|
268 |
-
$is_answer_was_correct = false;
|
269 |
|
270 |
-
|
271 |
-
'
|
272 |
|
273 |
-
|
274 |
-
|
275 |
-
|
276 |
-
|
277 |
-
|
278 |
-
|
279 |
-
|
280 |
-
|
281 |
-
|
282 |
-
|
283 |
-
|
284 |
-
|
285 |
-
|
286 |
-
|
287 |
-
|
288 |
-
|
289 |
-
|
290 |
-
|
291 |
-
|
292 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
293 |
}
|
294 |
|
295 |
$attempt_info = array(
|
296 |
-
'total_answered_questions' => count($quiz_answers),
|
297 |
'earned_marks' => $total_marks,
|
298 |
'attempt_status' => 'attempt_ended',
|
299 |
'attempt_ended_at' => date("Y-m-d H:i:s"),
|
209 |
}
|
210 |
|
211 |
$quiz_answers = tutor_utils()->avalue_dot('quiz_question', $attempt_answers);
|
212 |
+
|
213 |
$total_marks = 0;
|
|
|
|
|
|
|
214 |
|
215 |
+
if ( tutils()->count($quiz_answers)) {
|
|
|
216 |
|
217 |
+
foreach ( $quiz_answers as $question_id => $answers ) {
|
218 |
+
$question = tutor_utils()->get_quiz_question_by_id( $question_id );
|
219 |
+
$question_type = $question->question_type;
|
220 |
|
221 |
+
$is_answer_was_correct = false;
|
222 |
+
$given_answer = '';
|
223 |
|
224 |
+
if ( $question_type === 'true_false' || $question_type === 'single_choice' ) {
|
225 |
|
226 |
+
$given_answer = $answers;
|
227 |
+
$is_answer_was_correct = (bool) $wpdb->get_var( "SELECT is_correct FROM {$wpdb->prefix}tutor_quiz_question_answers WHERE answer_id = {$answers} " );
|
|
|
|
|
|
|
228 |
|
229 |
+
} elseif ( $question_type === 'multiple_choice' ) {
|
230 |
|
231 |
+
$given_answer = maybe_serialize( $answers );
|
232 |
+
$get_original_answers = (array) $wpdb->get_col( "SELECT answer_id FROM {$wpdb->prefix}tutor_quiz_question_answers WHERE belongs_question_id = {$question->question_id} AND belongs_question_type = '{$question_type}' AND is_correct = 1 ;" );
|
233 |
+
if ( maybe_serialize( $get_original_answers ) == $given_answer ) {
|
234 |
+
$is_answer_was_correct = true;
|
235 |
+
}
|
236 |
|
237 |
+
} elseif ( $question_type === 'fill_in_the_blank' ) {
|
|
|
238 |
|
239 |
+
$given_answer = (array) array_map( 'sanitize_text_field', $answers );
|
240 |
+
$given_answer = maybe_serialize( $given_answer );
|
|
|
|
|
241 |
|
242 |
+
$get_original_answer = $wpdb->get_row( "SELECT * FROM {$wpdb->prefix}tutor_quiz_question_answers WHERE belongs_question_id = {$question->question_id} AND belongs_question_type = '{$question_type}' ;" );
|
243 |
+
$gap_answer = (array) explode( '|', $get_original_answer->answer_two_gap_match );
|
244 |
|
245 |
+
$gap_answer = array_map( 'sanitize_text_field', $gap_answer );
|
246 |
+
if ( $given_answer == maybe_serialize( $gap_answer ) ) {
|
247 |
+
$is_answer_was_correct = true;
|
248 |
+
}
|
249 |
|
250 |
+
} elseif ( $question_type === 'open_ended' || $question_type === 'short_answer' ) {
|
251 |
|
252 |
+
$given_answer = wp_kses_post( $answers );
|
|
|
253 |
|
254 |
+
} elseif ( $question_type === 'ordering' || $question_type === 'matching' || $question_type === 'image_matching' ) {
|
|
|
255 |
|
256 |
+
$given_answer = (array) array_map( 'sanitize_text_field', tutor_utils()->avalue_dot( 'answers', $answers ) );
|
257 |
+
$given_answer = maybe_serialize( $given_answer );
|
|
|
258 |
|
259 |
+
$get_original_answers = (array) $wpdb->get_col( "SELECT answer_id FROM {$wpdb->prefix}tutor_quiz_question_answers WHERE belongs_question_id = {$question->question_id} AND belongs_question_type = '{$question_type}' ORDER BY answer_order ASC ;" );
|
260 |
+
$get_original_answers = array_map( 'sanitize_text_field', $get_original_answers );
|
261 |
|
262 |
+
if ( $given_answer == maybe_serialize( $get_original_answers ) ) {
|
263 |
+
$is_answer_was_correct = true;
|
264 |
+
}
|
|
|
265 |
|
266 |
+
} elseif ( $question_type === 'image_answering' ) {
|
267 |
+
echo '<pre>';
|
268 |
|
269 |
+
$image_inputs = tutor_utils()->avalue_dot( 'answer_id', $answers );
|
270 |
+
$image_inputs = (array) array_map( 'sanitize_text_field', $image_inputs );
|
271 |
+
$given_answer = maybe_serialize( $image_inputs );
|
272 |
+
$is_answer_was_correct = false;
|
273 |
+
|
274 |
+
$db_answer = $wpdb->get_col( "SELECT answer_title FROM {$wpdb->prefix}tutor_quiz_question_answers WHERE belongs_question_id = {$question_id} AND belongs_question_type =
|
275 |
+
'image_answering' ORDER BY answer_order asc ;" );
|
276 |
+
|
277 |
+
if ( is_array( $db_answer ) && count( $db_answer ) ) {
|
278 |
+
$is_answer_was_correct = ( strtolower( maybe_serialize( array_values( $image_inputs ) ) ) == strtolower( maybe_serialize( $db_answer ) ) );
|
279 |
+
}
|
280 |
+
}
|
281 |
+
|
282 |
+
$question_mark = $is_answer_was_correct ? $question->question_mark : 0;
|
283 |
+
$total_marks += $question_mark;
|
284 |
+
|
285 |
+
$answers_data = array(
|
286 |
+
'user_id' => $user_id,
|
287 |
+
'quiz_id' => $attempt->quiz_id,
|
288 |
+
'question_id' => $question_id,
|
289 |
+
'quiz_attempt_id' => $attempt_id,
|
290 |
+
'given_answer' => $given_answer,
|
291 |
+
'question_mark' => $question->question_mark,
|
292 |
+
'achieved_mark' => $question_mark,
|
293 |
+
'minus_mark' => 0,
|
294 |
+
'is_correct' => $is_answer_was_correct ? 1 : 0,
|
295 |
+
);
|
296 |
+
$wpdb->insert( $wpdb->prefix . 'tutor_quiz_attempt_answers', $answers_data );
|
297 |
+
}
|
298 |
}
|
299 |
|
300 |
$attempt_info = array(
|
301 |
+
'total_answered_questions' => tutils()->count($quiz_answers),
|
302 |
'earned_marks' => $total_marks,
|
303 |
'attempt_status' => 'attempt_ended',
|
304 |
'attempt_ended_at' => date("Y-m-d H:i:s"),
|
classes/Utils.php
CHANGED
@@ -501,6 +501,7 @@ class Utils {
|
|
501 |
$where_post_status = "AND $wpdb->posts.post_status IN({$statuses}) ";
|
502 |
}
|
503 |
|
|
|
504 |
$querystr = "
|
505 |
SELECT $wpdb->posts.*
|
506 |
FROM $wpdb->posts
|
@@ -508,7 +509,7 @@ class Utils {
|
|
508 |
|
509 |
WHERE 1 = 1 {$where_post_status}
|
510 |
AND $wpdb->posts.post_type = '{$course_post_type}'
|
511 |
-
|
512 |
ORDER BY $wpdb->posts.post_date DESC";
|
513 |
|
514 |
$pageposts = $wpdb->get_results($querystr, OBJECT);
|
501 |
$where_post_status = "AND $wpdb->posts.post_status IN({$statuses}) ";
|
502 |
}
|
503 |
|
504 |
+
//AND $wpdb->posts.post_date < NOW()
|
505 |
$querystr = "
|
506 |
SELECT $wpdb->posts.*
|
507 |
FROM $wpdb->posts
|
509 |
|
510 |
WHERE 1 = 1 {$where_post_status}
|
511 |
AND $wpdb->posts.post_type = '{$course_post_type}'
|
512 |
+
|
513 |
ORDER BY $wpdb->posts.post_date DESC";
|
514 |
|
515 |
$pageposts = $wpdb->get_results($querystr, OBJECT);
|
readme.txt
CHANGED
@@ -5,7 +5,7 @@ Tags: lms, course, elearning, education, learning management system
|
|
5 |
Requires at least: 4.5
|
6 |
Tested up to: 5.2
|
7 |
Requires PHP: 5.4.0
|
8 |
-
Stable tag: 1.4.
|
9 |
License: GPLv3
|
10 |
License URI: https://www.gnu.org/licenses/gpl-3.0.html
|
11 |
|
@@ -241,6 +241,12 @@ Tutor enables you to use any third party plugins without facing any compatibilit
|
|
241 |
|
242 |
== Changelog ==
|
243 |
|
|
|
|
|
|
|
|
|
|
|
|
|
244 |
= 1.4.3 - 11 October, 2019 =
|
245 |
|
246 |
* Added: Reset Password, Tutor LMS native login system
|
5 |
Requires at least: 4.5
|
6 |
Tested up to: 5.2
|
7 |
Requires PHP: 5.4.0
|
8 |
+
Stable tag: 1.4.4
|
9 |
License: GPLv3
|
10 |
License URI: https://www.gnu.org/licenses/gpl-3.0.html
|
11 |
|
241 |
|
242 |
== Changelog ==
|
243 |
|
244 |
+
= 1.4.4 - 16 October, 2019 =
|
245 |
+
|
246 |
+
* Fixed: quiz question sortable sorting item
|
247 |
+
* Improved: quiz draggable answer drop accessibility
|
248 |
+
* Fixed: prevented fatal error in single quiz question with no option and trying to finish quiz.
|
249 |
+
|
250 |
= 1.4.3 - 11 October, 2019 =
|
251 |
|
252 |
* Added: Reset Password, Tutor LMS native login system
|
tutor.php
CHANGED
@@ -4,7 +4,7 @@ Plugin Name: Tutor LMS
|
|
4 |
Plugin URI: https://www.themeum.com/product/tutor-lms/
|
5 |
Description: Tutor is a complete solution for creating a Learning Management System in WordPress way. It can help you to create small to large scale online education site very conveniently. Power features like report, certificate, course preview, private file sharing make Tutor a robust plugin for any educational institutes.
|
6 |
Author: Themeum
|
7 |
-
Version: 1.4.
|
8 |
Author URI: http://themeum.com
|
9 |
Requires at least: 4.5
|
10 |
Tested up to: 5.2
|
@@ -17,7 +17,7 @@ if ( ! defined( 'ABSPATH' ) )
|
|
17 |
/**
|
18 |
* Defined the tutor main file
|
19 |
*/
|
20 |
-
define('TUTOR_VERSION', '1.4.
|
21 |
define('TUTOR_FILE', __FILE__);
|
22 |
|
23 |
/**
|
4 |
Plugin URI: https://www.themeum.com/product/tutor-lms/
|
5 |
Description: Tutor is a complete solution for creating a Learning Management System in WordPress way. It can help you to create small to large scale online education site very conveniently. Power features like report, certificate, course preview, private file sharing make Tutor a robust plugin for any educational institutes.
|
6 |
Author: Themeum
|
7 |
+
Version: 1.4.4
|
8 |
Author URI: http://themeum.com
|
9 |
Requires at least: 4.5
|
10 |
Tested up to: 5.2
|
17 |
/**
|
18 |
* Defined the tutor main file
|
19 |
*/
|
20 |
+
define('TUTOR_VERSION', '1.4.4');
|
21 |
define('TUTOR_FILE', __FILE__);
|
22 |
|
23 |
/**
|