PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / 4.4.10
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses v4.4.10
4.4.10 4.4.9.1 4.4.9 4.4.8 4.4.7 4.4.6 4.4.5 4.4.4 4.4.3 4.4.2 4.4.1 4.4.0 4.3.9.1 4.3.9 4.3.8 4.3.7 4.1.6.9 4.1.6.9.1 4.1.6.9.2 4.1.6.9.3 4.1.6.9.4 4.1.7 4.1.7.1 4.1.7.2 4.1.7.3 All 142 releases
← All changes | inc/user-item/class-lp-user-item-quiz.php +67 -49 4.1.7 → 4.4.10 View file →
@@ -155,21 +155,8 @@
155 155 return ! empty( $statuses[ $status ] ) ? $statuses[ $status ] : __( 'Not Started', 'learnpress' );
156 156 }
157 157
158 158 /**
159 - * Get current question ID (quiz).
160 - *
161 - * @param string $return - Optional.
162 - *
163 - * @return int|LP_Question
164 - */
165 - public function get_current_question( $return = '' ) {
166 - _deprecated_function( sprintf( '%s::%s', __CLASS__, __FUNCTION__ ), '4.0.0' );
167 -
168 - learn_press_error_log( sprintf( 'Deprecated %s::%s', __CLASS__, __FUNCTION__ ) );
169 - }
170 -
171 - /**
172 159 * Get ID of the course that this item assigned to.
173 160 *
174 161 * @return array|mixed
175 162 */
@@ -204,9 +191,9 @@
204 191 *
205 192 * @param string $prop
206 193 * @param bool $force - Optional. Force to refresh cache.
207 194 *
208 - * Clear cache on
195 + * Clear cache on
209 196 * @see LP_REST_Users_Controller::start_quiz() | retake quiz
210 197 *
211 198 * @return LP_Quiz_Results|bool|mixed
212 199 * @throws Exception
@@ -220,9 +207,9 @@
220 207 }
221 208
222 209 $lp_quiz_cache = LP_Quiz_Cache::instance();
223 210
224 - $key_cache = sprintf( '%d/user/%d/course/%d', $this->get_item_id(), $this->get_user_id(), $this->get_course_id() );
211 + $key_cache = $this->get_results_cache_key();
225 212 $result = $lp_quiz_cache->get_cache( $key_cache );
226 213
227 214 if ( false === $result || $force ) {
228 215 // $result = $this->_get_results();
@@ -242,8 +229,31 @@
242 229 return $prop ? $result[ $prop ] : new LP_Quiz_Results( $result );
243 230 }
244 231
245 232 /**
233 + * Key of the cache filled by @see LP_User_Item_Quiz::get_results.
234 + *
235 + * @return string
236 + */
237 + public function get_results_cache_key(): string {
238 + return sprintf( '%d/user/%d/course/%d', $this->get_item_id(), $this->get_user_id(), $this->get_course_id() );
239 + }
240 +
241 + /**
242 + * Drop the cached result of this quiz for this user.
243 + *
244 + * get_results() caches what it calculates, and that cache outlives the request wherever a
245 + * persistent object cache is installed. Anything that rewrites the stored result must clear
246 + * it, or the next read serves the result from before the write - a quiz submitted after the
247 + * in-progress result was cached comes back with every question still unanswered.
248 + *
249 + * @return void
250 + */
251 + public function clear_results_cache() {
252 + LP_Quiz_Cache::instance()->clear( $this->get_results_cache_key() );
253 + }
254 +
255 + /**
246 256 * Get user quiz graduation text for displaying purpose. [Passed, Failed, null]
247 257 *
248 258 * @since 4.0.0
249 259 *
@@ -258,26 +268,26 @@
258 268 /**
259 269 * Get Timestamp remaining when user doing quiz
260 270 *
261 271 * @author tungnx
262 - * @version 1.0.0
272 + * @version 1.0.1
263 273 * @sicne 4.1.4.1
264 274 * @return int
265 275 */
266 276 public function get_timestamp_remaining(): int {
267 277 $timestamp_remaining = - 1;
278 + $quiz = false;
279 + $user_quiz = false;
268 280
269 281 try {
270 282 $quiz = learn_press_get_quiz( $this->get_item_id() );
271 -
272 283 if ( ! $quiz || LP_ITEM_STARTED != $this->get_status() ) {
273 284 return $timestamp_remaining;
274 285 }
275 286
276 287 $parent_id = $this->get_parent_id();
288 + $duration = $quiz->get_duration()->get() . ' second';
277 289
278 - $duration = $quiz->get_duration()->get() . ' second';
279 -
280 290 $filter = new LP_User_Items_Filter();
281 291 $filter->parent_id = $parent_id;
282 292 $filter->item_id = $this->get_item_id();
283 293 $filter->user_id = get_current_user_id();
@@ -283,9 +293,9 @@
283 293 $filter->user_id = get_current_user_id();
284 294 $user_quiz = LP_User_Items_DB::getInstance()->get_user_course_item( $filter, true );
285 295 $course_start_time = $user_quiz->start_time;
286 296 $timestamp_expire = strtotime( $course_start_time . ' +' . $duration );
287 - $timestamp_current = strtotime( current_time( 'mysql', 1 ) );
297 + $timestamp_current = time();
288 298 $timestamp_remaining = $timestamp_expire - $timestamp_current;
289 299
290 300 if ( $timestamp_remaining < 0 ) {
291 301 $timestamp_remaining = 0;
@@ -293,9 +303,9 @@
293 303 } catch ( Throwable $e ) {
294 304
295 305 }
296 306
297 - return apply_filters( 'learnpress/course/block_duration_expire/timestamp_remaining', $timestamp_remaining );
307 + return apply_filters( 'learn-press/user-course-quiz/timestamp_remaining', $timestamp_remaining, $user_quiz, $quiz );
298 308 }
299 309
300 310 /**
301 311 * Get all attempts of a quiz.
@@ -348,11 +358,10 @@
348 358 * @throws Exception
349 359 * @version 4.0.0
350 360 */
351 361 public function calculate_results(): array {
352 - $quiz = learn_press_get_quiz( $this->get_item_id() );
353 - $last_results = LP_User_Items_Result_DB::instance()->get_result( $this->get_user_item_id() );
354 - $is_has_change = 0;
362 + $quiz = learn_press_get_quiz( $this->get_item_id() );
363 + $last_results = LP_User_Items_Result_DB::instance()->get_result( $this->get_user_item_id() );
355 364
356 365 if ( ! $last_results ) {
357 366 $last_results = array();
358 367 }
@@ -425,9 +434,8 @@
425 434
426 435 $result['question_count'] = count( $questions );
427 436
428 437 if ( $grade ) {
429 - $is_has_change = 1;
430 438 learn_press_update_user_item_field(
431 439 array(
432 440 'graduation' => $grade,
433 441 ),
@@ -437,12 +445,8 @@
437 445 );
438 446 }
439 447 }
440 448
441 - if ( $is_has_change ) {
442 - // LP_User_Items_Result_DB::instance()->update( $this->get_user_item_id(), wp_json_encode( $result ) );
443 - }
444 -
445 449 return $result;
446 450 }
447 451
448 452 /**
@@ -450,9 +454,9 @@
450 454 *
451 455 * @param array $answered [question_id => answered, 'instant_check' => 0]
452 456 *
453 457 * @return array
454 - * @version 1.0.0
458 + * @version 1.0.1
455 459 * @author tungnx
456 460 * @since 4.1.4.1
457 461 */
458 462 public function calculate_quiz_result( array $answered = array() ): array {
@@ -459,8 +463,9 @@
459 463 $result = array(
460 464 'questions' => array(),
461 465 'mark' => 0,
462 466 'user_mark' => 0,
467 + 'minus_point' => 0,
463 468 'question_count' => 0,
464 469 'question_empty' => 0,
465 470 'question_answered' => 0,
466 471 'question_wrong' => 0,
@@ -492,11 +497,11 @@
492 497 if ( ! $quiz ) {
493 498 throw new Exception();
494 499 }
495 500
496 - $question_ids = $quiz->get_questions();
501 + $question_ids = $quiz->get_question_ids();
497 502 $result['mark'] = $quiz->get_mark();
498 - $result['question_count'] = count( $question_ids );
503 + $result['question_count'] = $quiz->count_questions();
499 504 $result['time_spend'] = $this->get_time_interval( 'display' );
500 505 $result['passing_grade'] = $quiz->get_passing_grade();
501 506 $checked_questions = $this->get_checked_questions();
502 507
@@ -503,18 +508,16 @@
503 508 foreach ( $question_ids as $question_id ) {
504 509 $question = LP_Question::get_question( $question_id );
505 510 $point = floatval( $question->get_mark() );
506 511
507 - // if ( ! array_key_exists( 'instant_check', $answered ) || array_key_exists( $question_id, $answered ) ) {
508 512 $result['questions'][ $question_id ] = array();
509 513 $result['questions'][ $question_id ]['answered'] = $answered[ $question_id ] ?? '';
510 514
511 - // }
512 -
513 515 if ( isset( $answered[ $question_id ] ) ) { // User's answer
514 516 $result['question_answered']++;
515 517
516 518 $check = $question->check( $answered[ $question_id ] );
519 + $point = apply_filters( 'learn-press/user/calculate-quiz-result/point', $point, $question, $check );
517 520 if ( $check['correct'] ) {
518 521 $result['question_correct']++;
519 522 $result['user_mark'] += $point;
520 523
@@ -521,9 +524,10 @@
521 524 $result['questions'][ $question_id ]['correct'] = true;
522 525 $result['questions'][ $question_id ]['mark'] = $point;
523 526 } else {
524 527 if ( $quiz->get_negative_marking() ) {
525 - $result['user_mark'] -= $point;
528 + $result['user_mark'] -= $point;
529 + $result['minus_point'] += $point;
526 530 }
527 531 $result['question_wrong']++;
528 532
529 533 $result['questions'][ $question_id ]['correct'] = false;
@@ -529,10 +533,11 @@
529 533 $result['questions'][ $question_id ]['correct'] = false;
530 534 $result['questions'][ $question_id ]['mark'] = 0;
531 535 }
532 536 } elseif ( ! array_key_exists( 'instant_check', $answered ) ) { // User skip question
533 - if ( $quiz->get_negative_marking() && $quiz->get_minus_skip_questions() ) {
534 - $result['user_mark'] -= $point;
537 + if ( $quiz->get_minus_skip_questions() ) {
538 + $result['user_mark'] -= $point;
539 + $result['minus_point'] += $point;
535 540 }
536 541 $result['question_empty']++;
537 542
538 543 $result['questions'][ $question_id ]['correct'] = false;
@@ -566,13 +571,8 @@
566 571 $result['pass'] = 1;
567 572 } else {
568 573 $result['pass'] = 0;
569 574 }
570 -
571 - // $result['answered'] = $answered;
572 - // $results['status'] = $quiz->get_status();
573 - // $result['results'] = $result;
574 - // $result['attempts'] = $this->get_attempts();
575 575 } catch ( Throwable $e ) {
576 576
577 577 }
578 578
@@ -587,9 +587,9 @@
587 587 return LP_User_Items_Result_DB::instance()->get_result( $this->get_user_item_id() );
588 588 }
589 589
590 590 public function get_percent_result( $decimal = 2 ) {
591 - return apply_filters( 'learn-press/user/quiz-percent-result', sprintf( '%s%%', round( $this->get_result( 'result' ), $decimal ), $this->get_user_id(), $this->get_item_id() ) );
591 + return apply_filters( 'learn-press/user/quiz-percent-result', sprintf( '%s%%', round( $this->get_result( 'result' ), $decimal ) ), $this->get_user_id(), $this->get_item_id() );
592 592 }
593 593
594 594 public function get_time_interval( $context = '' ) {
595 595 $interval = parent::get_time_interval();
@@ -680,11 +680,15 @@
680 680
681 681 return $return;
682 682 }
683 683
684 + /**
685 + * @deprecated 4.2.0
686 + */
684 687 public function get_total_questions() {
688 + _deprecated_function( __METHOD__, '4.2.0' );
685 689 $quiz = learn_press_get_quiz( $this->get_item_id() );
686 - $questions = $quiz->get_questions();
690 + $questions = $quiz->get_question_ids();
687 691
688 692 return sizeof( $questions );
689 693 }
690 694
@@ -699,13 +703,15 @@
699 703 *
700 704 * @param string $return - Optional.
701 705 *
702 706 * @return LP_Duration
707 + * @deprecated 4.1.7.3
703 708 */
704 709 public function get_time_remaining( $return = 'object' ) {
705 - $time = parent::get_time_remaining( $return );
710 + _deprecated_function( __METHOD__, '4.1.7.3' );
711 + /*$time = parent::get_time_remaining( $return );
706 712
707 - return apply_filters( 'learn-press/quiz/time-remaining', $time, $this->get_item_id(), $this->get_course_id(), $this->get_user_id() );
713 + return apply_filters( 'learn-press/quiz/time-remaining', $time, $this->get_item_id(), $this->get_course_id(), $this->get_user_id() );*/
708 714 }
709 715
710 716 /**
711 717 * Get all questions user has already used "Check"
@@ -756,14 +762,14 @@
756 762 */
757 763 public function instant_check_question( int $question_id, $answered = null ): array {
758 764 $question = learn_press_get_question( $question_id );
759 765 if ( ! $question ) {
760 - throw new Exception( __( 'Question is invalid!', 'learnpress' ) );
766 + throw new Exception( __( 'The question is invalid!', 'learnpress' ) );
761 767 }
762 768
763 769 $can_check = $this->can_check_answer( $question_id );
764 770 if ( ! $can_check ) {
765 - throw new Exception( __( 'Cannot check answer the question.', 'learnpress' ) );
771 + throw new Exception( __( 'Cannot check the answer to the question.', 'learnpress' ) );
766 772 }
767 773
768 774 $answered_check = array(
769 775 'instant_check' => 1,
@@ -782,8 +788,9 @@
782 788
783 789 $result_answer = $this->calculate_quiz_result( $answered_check );
784 790
785 791 LP_User_Items_Result_DB::instance()->update( $this->get_user_item_id(), json_encode( $result_answer ) );
792 + $this->clear_results_cache();
786 793 $this->add_checked_question( $question_id );
787 794
788 795 $checked['answered'] = $answered;
789 796 $checked['mark'] = $result_answer['questions'][ $question_id ]['mark'];
@@ -795,10 +802,13 @@
795 802 /**
796 803 * @param int $question_id
797 804 *
798 805 * @return int
806 + * @deprecated 4.2.5
799 807 */
800 808 public function hint( $question_id ) {
809 + _deprecated_function( __METHOD__, '4.2.5' );
810 + return false;
801 811 $remain = $this->can_hint_answer();
802 812
803 813 if ( $remain ) {
804 814 if ( ! $this->has_hinted_question( $question_id ) ) {
@@ -876,10 +886,13 @@
876 886 /**
877 887 * Get all questions user has already used "Check"
878 888 *
879 889 * @return array
890 + * @deprecated 4.2.5
880 891 */
881 892 public function get_hint_questions() {
893 + return [];
894 + _deprecated_function( __METHOD__, '4.2.5' );
882 895 $value = $this->get_meta( '_lp_question_hint', true );
883 896
884 897 if ( $value ) {
885 898 $value = (array) $value;
@@ -889,9 +902,14 @@
889 902
890 903 return $value;
891 904 }
892 905
906 + /**
907 + * @deprecated 4.2.5
908 + */
893 909 public function get_count_hint() {
910 + _deprecated_function( __METHOD__, '4.2.5' );
911 + return 0;
894 912 return count( $this->get_hint_questions() );
895 913 }
896 914
897 915 /**