PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / 4.4.5
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses v4.4.5
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 4.1.7.3.1 4.1.7.3.2 4.2.0 All 139 releases
learnpress / inc / quiz / class-lp-quiz.php

class-lp-quiz.php in LearnPress – WordPress LMS Plugin for Create and Sell Online Courses 4.4.5, at inc/quiz/class-lp-quiz.php

1,091 lines 25.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Class LP_Quiz.
4 *
5 * @author ThimPress
6 * @package LearnPress/Classes
7 * @version 3.0.0
8 */
9
10 defined( 'ABSPATH' ) || exit();
11
12 if ( ! class_exists( 'LP_Quiz' ) ) {
13
14 /**
15 * Class LP_Quiz
16 */
17 class LP_Quiz extends LP_Course_Item {
18
19
20 /**
21 * @var array
22 *
23 * @deprecated
24 */
25 protected static $_meta = array();
26
27 /**
28 * @var string
29 */
30 protected $_item_type = LP_QUIZ_CPT;
31
32 /**
33 * @var array
34 */
35 protected $_questions = array();
36
37 /**
38 * @var array
39 */
40 protected $_data = array(
41 // 'show_result' => 'no',
42 'passing_grade_type' => '',
43 'passing_grade' => 0,
44 // 'show_check_answer' => 'no',
45 // 'count_check_answer' => 0,
46 // 'show_hint' => 'no',
47 // 'count_hint' => 0,
48 // 'archive_history' => 'no',
49 // 'show_hide_question' => 'yes',
50 // 'preview' => 'no',
51 // 'minus_points' => 0,
52 'minus_skip_questions' => 'no',
53
54 'negative_marking' => 'no',
55 'instant_check' => 'no',
56 'retake_count' => 0,
57 'show_correct_review' => 'yes',
58 );
59
60 /**
61 * @var int
62 */
63 protected static $_loaded = 0;
64
65 /**
66 * Constructor gets the post object and sets the ID for the loaded course.
67 *
68 * @param mixed $the_quiz
69 * @param mixed $args
70 */
71 public function __construct( $the_quiz, $args = array() ) {
72 $this->_curd = new LP_Quiz_CURD();
73
74 if ( is_numeric( $the_quiz ) && $the_quiz > 0 ) {
75 $this->set_id( $the_quiz );
76 } elseif ( $the_quiz instanceof self ) {
77 $this->set_id( absint( $the_quiz->get_id() ) );
78 } elseif ( ! empty( $the_quiz->ID ) ) {
79 $this->set_id( absint( $the_quiz->ID ) );
80 }
81 if ( $this->get_id() > 0 ) {
82 $this->load();
83 }
84
85 self::$_loaded ++;
86 if ( self::$_loaded == 1 ) {
87 add_filter( 'debug_data', array( __CLASS__, 'log' ) );
88 }
89 }
90
91 /**
92 * Log debug data.
93 *
94 * @since 3.0.0
95 *
96 * @param $data
97 *
98 * @return array
99 */
100 public static function log( $data ) {
101 $data[] = __CLASS__ . '( ' . self::$_loaded . ' )';
102
103 return $data;
104 }
105
106 /**
107 * @param string $context
108 *
109 * @return string
110 */
111 public function get_heading_title( $context = '' ) {
112 return $this->get_title( $context );
113 }
114
115 /**
116 * Load quiz data
117 */
118 public function load() {
119 $this->_curd->load( $this );
120 }
121
122 /**
123 * Get default quiz meta.
124 *
125 * @since 3.0.0
126 *
127 * @return mixed
128 */
129 public static function get_default_meta() {
130 $meta = array(
131 'review' => 'no',
132 'duration' => '10 minute',
133 'passing_grade' => 80,
134 'negative_marking' => 'no',
135 'instant_check' => 'no',
136 'retake_count' => '0',
137 'pagination' => 1,
138 'show_correct_review' => 'yes',
139 );
140
141 return apply_filters( 'learn-press/quiz/default-meta', $meta );
142 }
143
144 /**
145 * Save quiz data.
146 *
147 * @return mixed
148 *
149 * @throws Exception
150 */
151 public function save() {
152 if ( $this->get_id() ) {
153 $return = $this->_curd->update( $this );
154 } else {
155 $return = $this->_curd->create( $this );
156 }
157
158 return $return;
159 }
160
161 public function get_negative_marking() {
162 return $this->get_data( 'negative_marking' ) === 'yes';
163 }
164
165 public function set_negative_marking( $set ) {
166 $this->_set_data( 'negative_marking', ! learn_press_is_negative_value( $set ) ? 'yes' : 'no' );
167 }
168
169 public function get_show_correct_review() {
170 return $this->get_data( 'show_correct_review' ) === 'yes';
171 }
172
173 public function set_show_correct_review( $set ) {
174 $this->_set_data( 'show_correct_review', $set );
175 }
176
177 public function get_instant_check() {
178 return $this->get_data( 'instant_check' ) === 'yes';
179 }
180
181 public function set_instant_check( $set ) {
182 $this->_set_data( 'instant_check', ! learn_press_is_negative_value( $set ) ? 'yes' : 'no' );
183 }
184
185 public function set_retake_count( $count ) {
186 $this->_set_data( 'retake_count', $count );
187 }
188
189 public function get_retake_count() {
190 return $this->get_data( 'retake_count' );
191 }
192
193 public function get_pagination() {
194 return ( $n = $this->get_data( 'pagination' ) ) > 1 ? $n : 0;
195 }
196
197 public function set_pagination( $set ) {
198 $this->_set_data( 'pagination', absint( $set ) );
199 }
200
201 /**
202 * @deprecated
203 *
204 * @param $show_result
205 */
206 public function set_show_result( $show_result ) {
207 _deprecated_function( __CLASS__ . '::' . __FUNCTION__, '4.0.0' );
208
209 $this->_set_data( 'show_result', $show_result );
210 }
211
212 /**
213 * @deprecated
214 *
215 * @return array|mixed
216 */
217 public function get_show_result() {
218
219 _deprecated_function( __CLASS__ . '::' . __FUNCTION__, '4.0.0' );
220
221 return $this->get_data( 'show_result' ) === 'yes';
222 }
223
224 /**
225 *
226 * @param $review_questions
227 */
228 public function set_review_questions( $review_questions ) {
229
230 $this->_set_data( 'review_questions', $review_questions );
231 }
232
233 /**
234 * Enable review quiz
235 *
236 * @return bool
237 */
238 public function get_review_questions(): bool {
239 return 'yes' === $this->get_data( 'review_questions', 'yes' );
240 }
241
242 /**
243 * @param $type
244 */
245 public function set_passing_grade_type( $type ) {
246 $this->_set_data( 'passing_grade_type', $type );
247 }
248
249 /**
250 * @return array|mixed
251 */
252 public function get_passing_grade_type() {
253 return $this->get_data( 'passing_grade_type', 'percentage' );
254 }
255
256 /**
257 * @param $value
258 */
259 public function set_passing_grade( $value ) {
260 $this->_set_data( 'passing_grade', $value );
261 }
262
263 /**
264 * @return array|mixed
265 */
266 public function get_passing_grade() {
267 $type = $this->get_passing_grade_type();
268 $value = get_post_meta( $this->get_id(), '_lp_passing_grade', true );
269 if ( empty( $value ) ) {
270 $value = 80;
271 }
272
273 switch ( $type ) {
274 case 'point':
275 break;
276 case 'percentage':
277 default:
278 $value = "{$value}%";
279 break;
280 }
281
282 return $value;
283 }
284
285 /**
286 * @deprecated
287 *
288 * @param $value
289 */
290 public function set_show_check_answer( $value ) {
291 _deprecated_function( __CLASS__ . '::' . __FUNCTION__, '4.0.0' );
292
293 $this->_set_data( 'show_check_answer', $value );
294 }
295
296 /**
297 * @deprecated
298 *
299 * @return int|bool
300 */
301 public function get_show_check_answer() {
302 _deprecated_function( __CLASS__ . '::' . __FUNCTION__, '4.0.0' );
303
304 return intval( $this->get_data( 'show_check_answer' ) );
305 }
306
307 /**
308 * @deprecated
309 *
310 * @param $count
311 */
312 public function set_count_check_answer( $count ) {
313 _deprecated_function( __CLASS__ . '::' . __FUNCTION__, '4.0.0' );
314
315 $this->_set_data( 'count_check_answer', $count );
316 }
317
318 /**
319 * @deprecated
320 *
321 * @return int
322 */
323 public function get_check_answer_count() {
324 _deprecated_function( __CLASS__ . '::' . __FUNCTION__, '4.0.0' );
325
326 return intval( $this->get_data( 'check_answer_count' ) );
327 }
328
329 /**
330 * @deprecated
331 *
332 * @param $value
333 */
334 public function set_show_hint( $value ) {
335 _deprecated_function( __CLASS__ . '::' . __FUNCTION__, '4.0.0' );
336
337 $this->_set_data( 'show_hint', $value );
338 }
339
340 /**
341 * @deprecated
342 *
343 * @return int
344 */
345 public function get_show_hint() {
346 _deprecated_function( __CLASS__ . '::' . __FUNCTION__, '4.0.0' );
347
348 return intval( $this->get_data( 'show_hint' ) );
349 }
350
351 /**
352 * @deprecated
353 *
354 * @param $count
355 */
356 public function set_count_hint( $count ) {
357 _deprecated_function( __CLASS__ . '::' . __FUNCTION__, '4.0.0' );
358
359 $this->_set_data( 'count_hint', $count );
360 }
361
362 /**
363 * Return true if hint answer is enabled.
364 *
365 * @deprecated
366 *
367 * @return bool
368 */
369 public function enable_show_hint() {
370 _deprecated_function( __CLASS__ . '::' . __FUNCTION__, '4.0.0' );
371
372 return apply_filters( 'learn-press/quiz/enable-show-hint', $this->get_data( 'show_hint' ) == 'yes', $this->get_id() );
373 }
374
375 /**
376 * @deprecated
377 *
378 * @param $value
379 */
380 public function set_archive_history( $value ) {
381 _deprecated_function( __CLASS__ . '::' . __FUNCTION__, '4.0.0' );
382
383 $this->_set_data( 'archive_history', $value );
384 }
385
386 /**
387 * Return true if archive history is enabled.
388 *
389 * @deprecated
390 *
391 * @return bool
392 */
393 public function enable_archive_history() {
394 _deprecated_function( __CLASS__ . '::' . __FUNCTION__, '4.0.0' );
395
396 return apply_filters( 'learn-press/quiz/enable-archive-history', $this->get_data( 'archive_history' ) == 'yes', $this->get_id() );
397 }
398
399 /**
400 * Return total mark of quiz by calculating total mark of all questions.
401 *
402 * @return int
403 */
404 public function get_mark() {
405 $mark = $this->get_data( 'mark', false );
406 if ( false === $mark || '' === $mark ) {
407 $questions = $this->get_question_ids();
408 $mark = 0;
409
410 foreach ( $questions as $question_id ) {
411 $question = LP_Question::get_question( $question_id );
412 if ( $question ) {
413 $mark += $question->get_mark();
414 }
415 }
416
417 $this->_set_data( 'mark', $mark );
418 }
419
420 return apply_filters( 'learn-press/quiz-mark', $mark, $this->get_id() );
421 }
422
423 /**
424 * Get duration of quiz
425 *
426 * @return LP_Duration
427 */
428 public function get_duration() {
429 $duration = parent::get_duration();
430
431 return apply_filters( 'learn-press/quiz-duration', $duration, $this->get_id() );
432 }
433
434 /**
435 * Get quiz questions.
436 *
437 * @param string $context
438 *
439 * @return mixed
440 * @editor tungnx
441 * @since 3.x.x
442 * @version 1.0.1
443 * @deprecated 4.2.0
444 */
445 public function get_questions( $context = 'display' ) {
446 _deprecated_function( __CLASS__ . '::' . __FUNCTION__, '4.2.0' );
447 $questions = array();
448 $ids = $this->_curd->read_question_ids( $this->get_id() );
449
450 if ( $ids ) {
451 foreach ( $ids as $id ) {
452 $questions[ $id ] = $id;
453 }
454 }
455
456 return apply_filters( 'learn-press/quiz/questions', $questions, $this->get_id(), $this->get_course_id(), $context );
457 }
458
459 /**
460 * Quiz editor get questions.
461 *
462 * @return mixed
463 */
464 public function quiz_editor_get_questions() {
465 // list questions
466 $questions = $this->get_question_ids( 'edit' );
467 // order questions in quiz
468 $question_order = learn_press_quiz_get_questions_order( $questions );
469
470 $result = array();
471
472 foreach ( $questions as $id ) {
473 $question = LP_Question::get_question( $id );
474
475 $answers = array();
476 // handle question answer
477 if ( is_array( $question->get_data( 'answer_options' ) ) ) {
478 foreach ( $question->get_data( 'answer_options' ) as $answer ) {
479 $answers[] = $answer;
480 }
481 }
482
483 $post = get_post( $id );
484 $result[] = apply_filters(
485 'learn-press/quiz-editor/question-data',
486 array(
487 'id' => $id,
488 'open' => false,
489 'title' => $post->post_title,
490 'type' => array(
491 'key' => $question->get_type(),
492 'label' => $question->get_type_label(),
493 ),
494 'answers' => apply_filters( 'learn-press/quiz-editor/question-answers-data', $answers, $id, $this->get_id() ),
495 'settings' => array(
496 'content' => $post->post_content,
497 'mark' => get_post_meta( $id, '_lp_mark', true ),
498 'explanation' => get_post_meta( $id, '_lp_explanation', true ),
499 'hint' => get_post_meta( $id, '_lp_hint', true ),
500 ),
501 'order' => $question_order[ $id ],
502 ),
503 $id,
504 $this->get_id()
505 );
506 }
507
508 return apply_filters( 'learn-press/quiz/quiz_editor_questions', $result, $this->get_id() );
509 }
510
511 /**
512 * Get quiz duration html.
513 *
514 * @return mixed
515 */
516 public function get_duration_html() {
517 $duration = $this->get_duration();
518 if ( $duration ) {
519 $duration = learn_press_seconds_to_time( $duration->get_seconds() );
520 } else {
521 $duration = __( 'Unlimited', 'learnpress' );
522 }
523
524 return apply_filters( 'learn_press_quiz_duration_html', $duration, $this );
525 }
526
527 /**
528 * Get number questions in quiz.
529 *
530 * @return int
531 */
532 public function count_questions(): int {
533 $size = 0;
534 $questions = $this->get_question_ids();
535
536 if ( $questions ) {
537 $size = sizeof( $questions );
538 }
539
540 return (int) apply_filters( 'learn-press/quiz/count-questions', $size, $this->get_id() );
541 }
542
543 /**
544 * Get all question's ids of the quiz.
545 *
546 * @param string $context
547 *
548 * @return int[]
549 * @editor tungnx
550 * @version 1.0.1
551 * @since 3.2.0
552 */
553 public function get_question_ids( string $context = 'display' ): array {
554 $question_ids = $this->_curd->read_question_ids( $this->get_id(), $context );
555 $question_ids = apply_filters( 'learn-press/quiz/get-question-ids', $question_ids, $this->get_id(), $this->get_course_id(), $context );
556 if ( ! is_array( $question_ids ) ) {
557 $question_ids = array();
558 }
559
560 return $question_ids;
561 }
562
563 /**
564 * Get number questions for user do it.
565 *
566 * @return mixed|null
567 */
568 public function get_number_questions_to_do() {
569 return apply_filters( 'learn-press/quiz/number-questions-show', $this->count_questions(), $this );
570 }
571
572 /**
573 * This quiz has any question?
574 *
575 * @return bool
576 */
577 public function has_questions() {
578 return $this->count_questions() > 0;
579 }
580
581 /**
582 * Get js localize script in frontend. [NOT USED]
583 *
584 * @return mixed
585 */
586 public function get_localize() {
587 $localize = array(
588 'confirm_finish_quiz' => array(
589 'title' => __( 'Finish quiz', 'learnpress' ),
590 'message' => __( 'Are you sure you want to finish this quiz?', 'learnpress' ),
591 ),
592 'confirm_retake_quiz' => array(
593 'title' => __( 'Retake quiz', 'learnpress' ),
594 'message' => __( 'Are you sure you want to retake this quiz?', 'learnpress' ),
595 ),
596 'quiz_time_is_over' => array(
597 'title' => __( 'Time\'s up!', 'learnpress' ),
598 'message' => __( 'The time is up! Your quiz will automatically come to an end', 'learnpress' ),
599 ),
600 'finished_quiz' => __( 'Congrats! You have finished this quiz', 'learnpress' ),
601 'retaken_quiz' => __( 'Congrats! You have re-taken this quiz. Please wait a moment and the page will reload', 'learnpress' ),
602 );
603
604 return apply_filters( 'learn_press_single_quiz_localize', $localize, $this );
605 }
606
607 /**
608 * __isset function.
609 *
610 * @param mixed $key
611 *
612 * @return bool
613 */
614 public function __isset( $key ) {
615 return metadata_exists( 'post', $this->get_id(), '_' . $key );
616 }
617
618 /**
619 * __get function.
620 *
621 * @param string $key
622 *
623 * @return mixed
624 * @deprecated 4.0.8
625 */
626 public function __get( $key ) {
627 _deprecated_function( __METHOD__, '4.0.8' );
628 /*echo '@deprecated[' . $key . ']';
629 learn_press_debug( debug_backtrace() );
630
631 return false;*/
632 }
633
634 /**
635 * @param $feature
636 *
637 * @return mixed
638 * @throws Exception
639 * @deprecated 3.0.8
640 */
641 public function has( $feature ) {
642 _deprecated_function( __FUNCTION__, '3.0.8' );
643
644 $args = func_get_args();
645 unset( $args[0] );
646 $method = 'has_' . preg_replace( '!-!', '_', $feature );
647 $callback = array( $this, $method );
648 if ( is_callable( $callback ) ) {
649 return call_user_func_array( $callback, $args );
650 } else {
651 throw new Exception( sprintf( __( 'The function %s doesn\'t exist', 'learnpress' ), $feature ) );
652 }
653 }
654
655 /**
656 * Return TRUE if quiz contain a question.
657 *
658 * @param int $question_id
659 *
660 * @return bool
661 */
662 public function has_question( $question_id ) {
663 $questions = $this->get_question_ids();
664
665 return apply_filters( 'learn-press/quiz/has-question', in_array( $question_id, $questions ), $question_id, $this->get_id() );
666 }
667
668 /**
669 * Get question permalink from it's ID.
670 * If permalink option is turn on, add name of question
671 * into quiz permalink. Otherwise, add it's ID into
672 * query var.
673 *
674 * @param int $question_id
675 *
676 * @return string
677 * @deprecated 4.2.0
678 */
679 public function get_question_link( $question_id = null ) {
680 _deprecated_function( __METHOD__, '4.2.0' );
681 /*$course = learn_press_get_course();
682 if ( ! $course ) {
683 return '';
684 }
685
686 $permalink = $course->get_item_link( $this->get_id() );
687 if ( '' != get_option( 'permalink_structure' ) && get_post_status( $this->get_id() ) != 'draft' ) {
688 if ( get_post_type( $question_id ) === LP_QUESTION_CPT ) {
689 $question_name = get_post_field( 'post_name', $question_id );
690 preg_match( '/\?/i', $permalink, $result );
691 if ( empty( $result ) ) {
692 $permalink = $permalink . $question_name;
693 } else {
694 $permalink = preg_replace( '/\?/i', '/' . $question_name . '/?', $permalink );
695 }
696 }
697 } else {
698 $permalink = esc_url_raw( add_query_arg( array( 'question', $question_id ), $permalink ) );
699 }
700
701 // @deprecated
702 $permalink = apply_filters( 'learn_press_quiz_question_permalink', $permalink, $question_id, $this );
703
704 return apply_filters( 'learn-press/quiz/question-permalink', $permalink, $question_id, $this->get_id() );*/
705 }
706
707 /**
708 * @param int $at
709 *
710 * @return bool
711 * @deprecated 4.1.6.9
712 */
713 /*public function get_question_at( $at = 0 ) {
714 $questions = $this->get_questions();
715
716 if ( $questions ) {
717 $questions = array_values( $questions );
718
719 return @$questions[ $at ];
720 }
721
722 return false;
723 }*/
724
725 /**
726 * Get prev question from a question.
727 *
728 * @param int $id
729 *
730 * @return bool
731 * @deprecated 4.1.6.9
732 */
733 /*public function get_prev_question( $id ) {
734 $prev = false;
735 $questions = $this->get_questions();
736
737 if ( $questions ) {
738 $questions = array_values( $questions );
739 $at = array_search( $id, $questions );
740
741 if ( 0 < $at ) {
742 $prev = $questions[ $at - 1 ];
743 }
744 }
745
746 return apply_filters( 'learn-press/quiz/prev-question-id', $prev, $this->get_id() );
747 }*/
748
749 /**
750 * Get next question from a question.
751 *
752 * @param int $id
753 *
754 * @return bool
755 * @deprecated 4.1.6.9
756 */
757 /*public function get_next_question( $id ) {
758 $next = false;
759 $questions = $this->get_questions();
760
761 if ( $questions ) {
762 $questions = array_values( $questions );
763 $at = array_search( $id, $questions );
764
765 if ( sizeof( $questions ) - 1 > $at ) {
766 $next = $questions[ $at + 1 ];
767 }
768 }
769
770 return apply_filters( 'learn-press/quiz/next-question-id', $next, $this->get_id() );
771 }*/
772
773 /**
774 * Get index number of a question.
775 *
776 * @param int $id
777 * @param int $start
778 *
779 * @return bool|mixed
780 * @deprecated 4.1.6.9
781 */
782 /*public function get_question_index( $id, $start = 0 ) {
783 $index = 0;
784 $questions = $this->get_questions();
785
786 if ( $questions ) {
787 $questions = array_values( $questions );
788 $index = array_search( $id, $questions );
789 }
790
791 return apply_filters( 'learn-press/quiz/question-index', intval( $start ) + $index, $this->get_id() );
792 }*/
793
794 /**
795 * Check question.
796 *
797 * @param $question_id
798 * @param $user_id
799 *
800 * @return bool
801 * @deprecated 4.2.0
802 */
803 public function check_question( $question_id, $user_id ) {
804 _deprecated_function( __METHOD__, '4.2.0' );
805 /*$question = LP_Question::get_question( $question_id );
806
807 if ( ! $question ) {
808 return false;
809 }
810
811 $user = learn_press_get_user( $user_id );
812
813 $history = $user->get_quiz_results( $this->get_id() );
814
815 if ( ! $history ) {
816 return false;
817 }
818
819 $checked = array();
820 $checked = array_filter( $checked );
821
822 if ( ! in_array( $question_id, $checked ) ) {
823 $checked[] = $question_id;
824 }
825
826 return true;*/
827
828 }
829
830 /**
831 * Get question position in quiz.
832 *
833 * @param $question
834 * @param int $user_id
835 *
836 * @return false|int|string
837 * @deprecated 4.2.0
838 */
839 public function get_question_position( $question, $user_id = 0 ) {
840 _deprecated_function( __METHOD__, '4.2.0' );
841 /*if ( ! $user_id ) {
842 $user_id = learn_press_get_current_user_id();
843 }
844
845 $user = learn_press_get_user( $user_id );
846 $results = $user->get_quiz_results( $this->get_id(), '', '' );
847
848 if ( $user && $results ) {
849 $questions = (array) $results->questions;
850
851 } else {
852 $questions = $this->get_question_ids();
853 }
854
855 $position = array_search( $question, $questions );
856
857 return $position;*/
858 }
859
860 /**
861 * @param int $user_id
862 * @param int $course_id
863 *
864 * @return bool|LP_Question
865 * @deprecated 4.0.0
866 */
867 public function get_current_question( $user_id = 0, $course_id = 0 ) {
868 _deprecated_function( sprintf( '%s::%s', __CLASS__, __FUNCTION__ ), '4.0.0' );
869
870 /*$user = learn_press_get_user( $user_id );
871 $id = $user->get_current_quiz_question( $this->get_id(), $course_id );
872
873 return LP_Question::get_question( $id );*/
874 }
875
876 /**
877 * @param string $return
878 *
879 * @return LP_Question|int
880 */
881 public function get_viewing_question( $return = '' ) {
882 global $lp_quiz_question;
883
884 return $return !== 'id' ? $lp_quiz_question : ( $lp_quiz_question ? $lp_quiz_question->get_id() : 0 );
885 }
886
887 /**
888 * @param mixed $the_quiz
889 * @param array $args
890 *
891 * @return LP_Quiz|bool
892 */
893 public static function get_quiz( $the_quiz = false, $args = array() ) {
894 if ( is_numeric( $the_quiz ) && isset( LP_Global::$quizzes[ $the_quiz ] ) ) {
895 return LP_Global::$quizzes[ $the_quiz ];
896 }
897
898 $the_quiz = self::get_quiz_object( $the_quiz );
899
900 if ( ! $the_quiz ) {
901 return false;
902 }
903
904 if ( isset( LP_Global::$quizzes[ $the_quiz->ID ] ) ) {
905 return LP_Global::$quizzes[ $the_quiz->ID ];
906 }
907
908 if ( ! empty( $args['force'] ) ) {
909 $force = ! ! $args['force'];
910 unset( $args['force'] );
911 } else {
912 $force = false;
913 }
914 $key_args = wp_parse_args(
915 $args,
916 array(
917 'id' => $the_quiz->ID,
918 'type' => $the_quiz->post_type,
919 )
920 );
921
922 $key = LP_Helper::array_to_md5( $key_args );
923
924 if ( $force ) {
925 LP_Global::$quizzes[ $key ] = false;
926 LP_Global::$quizzes[ $the_quiz->ID ] = false;
927 }
928
929 if ( empty( LP_Global::$quizzes[ $key ] ) ) {
930 $class_name = self::get_quiz_class( $the_quiz, $args );
931 if ( is_string( $class_name ) && class_exists( $class_name ) ) {
932 $quiz = new $class_name( $the_quiz->ID, $args );
933 } elseif ( $class_name instanceof LP_Course_Item ) {
934 $quiz = $class_name;
935 } else {
936 $quiz = new self( $the_quiz->ID, $args );
937 }
938 LP_Global::$quizzes[ $key ] = $quiz;
939 LP_Global::$quizzes[ $the_quiz->ID ] = $quiz;
940 }
941
942 return LP_Global::$quizzes[ $key ];
943 }
944
945 /**
946 * @param string $quiz_type
947 *
948 * @return string|false
949 */
950 private static function get_class_name_from_quiz_type( $quiz_type ) {
951 return LP_QUIZ_CPT === $quiz_type ? __CLASS__ : 'LP_Quiz_' . implode( '_', array_map( 'ucfirst', explode( '-', $quiz_type ) ) );
952 }
953
954 /**
955 * Get the lesson class name
956 *
957 * @param WP_Post $the_quiz
958 * @param array $args (default: array())
959 *
960 * @return string
961 */
962 private static function get_quiz_class( $the_quiz, $args = array() ) {
963 $quiz_id = absint( $the_quiz->ID );
964 $type = $the_quiz->post_type;
965
966 $class_name = self::get_class_name_from_quiz_type( $type );
967
968 // Filter class name so that the class can be overridden if extended.
969 return apply_filters( 'learn-press/quiz/object-class', $class_name, $type, $quiz_id );
970 }
971
972 /**
973 * Get the quiz object
974 *
975 * @param mixed $the_quiz
976 *
977 * @uses WP_Post
978 * @return WP_Post|bool false on failure
979 */
980 private static function get_quiz_object( $the_quiz ) {
981 if ( false === $the_quiz ) {
982 $the_quiz = get_post_type() === LP_QUIZ_CPT ? $GLOBALS['post'] : false;
983 } elseif ( is_numeric( $the_quiz ) ) {
984 $the_quiz = get_post( $the_quiz );
985 } elseif ( $the_quiz instanceof LP_Course_Item ) {
986 $the_quiz = get_post( $the_quiz->get_id() );
987 } elseif ( ! ( $the_quiz instanceof WP_Post ) ) {
988 $the_quiz = false;
989 }
990
991 return apply_filters( 'learn-press/quiz/post-object', $the_quiz );
992 }
993
994 public function set_show_hide_question( $show_or_hide ) {
995 $this->_set_data( 'show_hide_question', $show_or_hide );
996 }
997
998 /**
999 * Set quiz is preview or not.
1000 * using
1001 */
1002 public function set_preview( $preview ) {
1003 $this->_set_data( 'preview', $preview );
1004 }
1005
1006 /**
1007 * Set option skip question will be minus points
1008 *
1009 * @param $skip
1010 */
1011 public function set_minus_skip_questions( $skip ) {
1012 $this->_set_data( 'minus_skip_questions', $skip );
1013 }
1014
1015 /**
1016 * Get quiz is preview or not.
1017 * using
1018 */
1019 public function get_preview() {
1020 return 'yes' === $this->get_data( 'preview' );
1021 }
1022
1023 // public function get_minus_points() {
1024 // return $this->get_data( 'minus_points' );
1025 // }
1026
1027 /**
1028 * Get option skip question will be minus points
1029 *
1030 * @return bool
1031 */
1032 public function get_minus_skip_questions(): bool {
1033 return 'yes' === $this->get_data( 'minus_skip_questions', 'no' );
1034 }
1035
1036 /**
1037 * Get css classes of question displays in a list.
1038 *
1039 * @param int $question_id
1040 * @param null $position
1041 *
1042 * @return array
1043 * @deprecated 4.1.6.9
1044 */
1045 /*public function get_question_number_class( $question_id, $position = null ) {
1046 if ( null === $position ) {
1047 $position = $this->get_question_index( $question_id );
1048 }
1049
1050 $class = array( 'question-' . $position );
1051
1052 if ( $this->is_viewing_question( $question_id ) ) {
1053 $class[] = 'current';
1054 }
1055
1056 $user = learn_press_get_current_user();
1057 $quiz_data = $user->get_quiz_data( $this->get_id() );
1058
1059 if ( $quiz_data ) {
1060 if ( $quiz_data->is_skipped( $question_id ) ) {
1061 $class[] = 'skipped';
1062 }
1063 }
1064
1065 return $class;
1066 }*/
1067
1068 /**
1069 * @param mixed $offset
1070 *
1071 * @return bool|mixed
1072 * @deprecated 4.2.0
1073 */
1074 public function offsetGet( $offset ) {
1075 _deprecated_function( __CLASS__ . '::' . __METHOD__, '4.2.0' );
1076 return $this->offsetExists( $offset ) ? $this->_questions[ $offset ] : false;
1077 }
1078
1079 /**
1080 * @param mixed $offset
1081 *
1082 * @return bool
1083 * @deprecated 4.2.0
1084 */
1085 public function offsetExists( $offset ) {
1086 _deprecated_function( __CLASS__ . '::' . __METHOD__, '4.2.0' );
1087 /*return array_key_exists( $offset, $this->_questions );*/
1088 }
1089 }
1090 }
1091