PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / 4.1.7.3.2
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses v4.1.7.3.2
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 / curds / class-lp-question-curd.php

class-lp-question-curd.php in LearnPress – WordPress LMS Plugin for Create and Sell Online Courses 4.1.7.3.2, at inc/curds/class-lp-question-curd.php

1,100 lines 28.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * Class LP_Question_CURD
5 *
6 * @author ThimPress
7 * @package LearnPress/Classes/CURD
8 * @since 3.0.0
9 */
10
11 /**
12 * Prevent loading this file directly
13 */
14 defined( 'ABSPATH' ) || exit();
15
16 if ( ! class_exists( 'LP_Question_CURD' ) ) {
17
18 /**
19 * Class LP_Question_CURD
20 */
21 class LP_Question_CURD extends LP_Object_Data_CURD implements LP_Interface_CURD {
22
23 /**
24 * LP_Question_CURD constructor.
25 */
26 public function __construct() {
27 $this->_error_messages = array(
28 'QUESTION_NOT_EXISTS' => __( 'The question does not exist.', 'learnpress' ),
29 );
30 }
31
32 /**
33 * Create question and can add to quiz.
34 *
35 * @param $args
36 *
37 * @return bool|int|LP_Question|WP_Error
38 */
39 public function create( &$args ) {
40 $args = wp_parse_args(
41 $args,
42 array(
43 'quiz_id' => 0,
44 'order' => - 1,
45 'id' => '',
46 'status' => 'publish',
47 'type' => 'true_or_false',
48 'title' => __( 'New Question', 'learnpress' ),
49 'content' => '',
50 'create_answers' => true,
51 )
52 );
53
54 // set question author for author of quiz
55 if ( ! empty( $args['quiz_id'] ) ) {
56 $user_id = get_post_field( 'post_author', $args['quiz_id'] );
57 } else {
58 $user_id = learn_press_get_current_user_id();
59 }
60
61 $question_id = wp_insert_post(
62 array(
63 'ID' => $args['id'],
64 'post_author' => $user_id,
65 'post_type' => LP_QUESTION_CPT,
66 'post_status' => $args['status'],
67 'post_title' => $args['title'],
68 'post_content' => $args['content'],
69 )
70 );
71
72 if ( $question_id ) {
73 // add default meta for new lesson
74 $default_meta = LP_Question::get_default_meta();
75
76 if ( is_array( $default_meta ) ) {
77 foreach ( $default_meta as $key => $value ) {
78 update_post_meta( $question_id, '_lp_' . $key, $value );
79 }
80 }
81 update_post_meta( $question_id, '_lp_type', $args['type'] );
82 // update user memory question types
83 get_user_meta( $user_id, '_learn_press_memorize_question_types', $args['type'] );
84
85 $question = LP_Question::get_question( $question_id, array( 'type' => $args['type'] ) );
86 $question->set_type( $args['type'] );
87
88 if ( $args['create_answers'] ) {
89 $question->create_default_answers();
90
91 // add question to quiz
92 if ( ! empty( $args['quiz_id'] ) ) {
93 $quiz_curd = new LP_Quiz_CURD();
94 $quiz_curd->add_question( $args['quiz_id'], $question_id, $args['order'] );
95 }
96 }
97
98 do_action( 'learn-press/after-create-question', $question );
99
100 return $question;
101 }
102
103 return $question_id;
104 }
105
106
107 public function update( &$question ) {
108 return $question;
109 // TODO: Implement update() method.
110 }
111
112 /**
113 * Delete all question's related data before run wp_delete_post(), hook to before delete question hook.
114 *
115 * @since 3.0.0
116 *
117 * @param object $question_id
118 */
119 public function delete( &$question_id ) {
120 // remove all answer of question from {$wpdb->prefix}learnpress_question_answers table
121 $this->clear( $question_id );
122
123 // quiz curd
124 $curd = new LP_Quiz_CURD();
125
126 // allow hook
127 do_action( 'learn-press/before-delete-question', $question_id );
128
129 // get the quizzes that a question is assigned to, return WP Post
130 $quiz = $this->get_quiz( $question_id );
131
132 // remove question from quiz
133 if ( $quiz ) {
134 $curd->remove_questions( $quiz->ID, $question_id );
135 }
136 }
137
138 /**
139 * Duplicate question.
140 *
141 * @since 3.0.0
142 *
143 * @param $question_id
144 * @param array $args
145 *
146 * @return mixed|WP_Error
147 */
148 public function duplicate( &$question_id, $args = array() ) {
149 if ( ! $question_id ) {
150 return new WP_Error( 'lp/question/curd/duplicate/err', 'Oops! ID not found' );
151 }
152
153 if ( learn_press_get_post_type( $question_id ) != LP_QUESTION_CPT ) {
154 return new WP_Error( 'lp/question/curd/duplicate/err', 'Op! The question does not exist' );
155 }
156
157 // ensure that user can create question
158 if ( ! current_user_can( 'edit_posts' ) ) {
159 return new WP_Error( 'lp/question/curd/duplicate/err', 'Sorry! You do not have permission to duplicate this question' );
160 }
161
162 // origin question
163 $question = LP_Question::get_question( $question_id );
164
165 // duplicate question
166 $new_question_id = learn_press_duplicate_post( $question_id, array( 'post_status' => 'publish' ) );
167
168 if ( ! $new_question_id || is_wp_error( $new_question_id ) ) {
169 return new WP_Error( 'lp/question/curd/duplicate/err', 'Sorry! Failed to duplicate the question!' );
170 } else {
171
172 // init new question
173 $new_question = LP_Question::get_question( $new_question_id );
174
175 // set data
176 $new_question->set_type( $question->get_type() );
177 $new_question->set_data( 'answer_options', $question->get_data( 'answer_options' ) );
178
179 // trigger change user memorize question types
180 $user_id = get_current_user_id();
181 update_user_meta( $user_id, '_learn_press_memorize_question_types', $new_question->get_type() );
182
183 // duplicate answer
184 $this->duplicate_answer( $question_id, $new_question_id );
185
186 do_action( 'learn-press/item/after-duplicate', $question_id, $new_question_id, $args );
187
188 return $new_question_id;
189 }
190 }
191
192 /**
193 * Duplicate answer question.
194 *
195 * @param $question_id | origin question
196 * @param $question_id_clone | new question
197 * @version 3.0.1
198 * @since 1.0.1
199 */
200 public function duplicate_answer( $question_id, $question_id_clone ) {
201 $lp_db = LP_Database::getInstance();
202 $lp_question_answers_db = LP_Question_Answers_DB::getInstance();
203
204 try {
205 // Get all answer of question
206 $filter_get_answer_options = new LP_Question_Answers_Filter();
207 $filter_get_answer_options->question_ids = [ $question_id ];
208 $answer_options = $lp_question_answers_db->get_question_asnwers( $filter_get_answer_options );
209
210 if ( $answer_options ) {
211 foreach ( $answer_options as $answer_option ) {
212 $question_answer_id = $answer_option->question_answer_id;
213
214 // Insert new question_answer
215 $insert_question_answer_rs = $lp_db->wpdb->insert(
216 $lp_db->tb_lp_question_answers,
217 array(
218 'question_id' => $question_id_clone,
219 'title' => ! empty( $answer_option->title ) ? $answer_option->title : '',
220 'value' => ! empty( $answer_option->value ) ? $answer_option->value : '',
221 'is_true' => ! empty( $answer_option->is_true ) ? $answer_option->is_true : '',
222 'order' => $answer_option->order,
223 ),
224 array( '%d', '%s', '%s', '%s', '%s' )
225 );
226
227 if ( ! $insert_question_answer_rs ) {
228 throw new Exception( __( 'Failed to duplicate answer', 'learnpress' ) );
229 }
230
231 // Get question_answer_id have just inserted
232 $filter_question_answer_id = new LP_Question_Answers_Filter();
233 $filter_question_answer_id->only_fields = [ 'MAX(question_answer_id)' ];
234 $filter_question_answer_id->question_ids = [ $question_id_clone ];
235 $filter_question_answer_id->return_string_query = true;
236 $question_answer_id_query = $lp_question_answers_db->get_question_asnwers( $filter_question_answer_id );
237 $question_answer_id_new = (int) $lp_question_answers_db->wpdb->get_var( $question_answer_id_query );
238
239 if ( ! $question_answer_id_new ) {
240 throw new Exception( __( 'Failed to duplicate answer', 'learnpress' ) );
241 }
242
243 // Duplicate answer meta
244 // Get answer meta by question_answer_id
245 $filter_get = new LP_Question_Answermeta_Filter();
246 $filter_get->collection = $lp_db->tb_lp_question_answermeta;
247 $filter_get->collection_alias = 'qam';
248 $filter_get->field_count = 'meta_id';
249 $filter_get->limit = -1;
250 $filter_get->where[] = $lp_db->wpdb->prepare( 'AND qam.learnpress_question_answer_id = %d', $question_answer_id );
251 $filter_get->fields = $lp_db->get_cols_of_table( $lp_db->tb_lp_question_answermeta );
252 $question_answermeta_rs = $lp_db->execute( $filter_get );
253
254 foreach ( $question_answermeta_rs as $question_answermeta ) {
255 $lp_db->wpdb->insert(
256 $lp_db->tb_lp_question_answermeta,
257 array(
258 'learnpress_question_answer_id' => $question_answer_id_new,
259 'meta_key' => $question_answermeta->meta_key,
260 'meta_value' => $question_answermeta->meta_value,
261 ),
262 array( '%d', '%s', '%s' )
263 );
264 }
265 }
266 }
267 } catch ( Throwable $e ) {
268 error_log( $e->getMessage() );
269 }
270 }
271
272 /**
273 * @param LP_Question $question
274 *
275 * @return bool
276 * @throws Exception
277 */
278 public function load( &$question ) {
279 // question id
280 $id = $question->get_id();
281
282 if ( ! $id || ! in_array( learn_press_get_post_type( $id ), array( 'revision', LP_QUESTION_CPT ) ) ) {
283 throw new Exception( sprintf( __( 'Invalid question with ID "%d".', 'learnpress' ), $id ) );
284 }
285
286 $question->set_data_via_methods(
287 array(
288 'explanation' => get_post_meta( $id, '_lp_explanation', true ),
289 'hint' => get_post_meta( $id, '_lp_hint', true ),
290 )
291 );
292 // $this->_load_answer_options( $question );
293 $this->_load_meta( $question );
294
295 return true;
296 }
297
298 /**
299 * @param $question | LP_Question
300 */
301 protected function _load_meta( &$question ) {
302 $type = get_post_meta( $question->get_id(), '_lp_type', true );
303 if ( ! learn_press_is_support_question_type( $type ) ) {
304 $type = 'true_or_false';
305 }
306 // $question->set_type( $type );
307
308 $mark = $this->_get_question_mark( $question->get_id() );
309 $question->set_data_via_methods(
310 array(
311 'mark' => $mark,
312 )
313 );
314 }
315
316 public function _get_question_mark( $question_id ) {
317
318 // Recheck _lp_mark @tungnx
319 $mark = get_post_meta( $question_id, '_lp_mark', true ) ? get_post_meta( $question_id, '_lp_mark', true ) : 0;
320
321 $mark = abs( $mark );
322 if ( ! $mark ) {
323 $mark = apply_filters( 'learn-press/question/default-mark', 1, $question_id );
324 update_post_meta( $question_id, '_lp_mark', $mark );
325 }
326
327 return $mark;
328 }
329
330 /**
331 * Get the quizzes that a question is assigned to.
332 *
333 * @since 3.0.0
334 *
335 * @param $question_id
336 *
337 * @return null|object WP_Post
338 */
339 public function get_quiz( $question_id ) {
340 global $wpdb;
341
342 $query = $wpdb->prepare(
343 "
344 SELECT post.* FROM {$wpdb->posts} post
345 INNER JOIN {$wpdb->prefix}learnpress_quiz_questions quiz ON post.ID = quiz.quiz_id
346 WHERE quiz.question_id = %d
347 ",
348 $question_id
349 );
350
351 // get single row
352 return $wpdb->get_row( $query );
353 }
354
355 /**
356 * Change question type.
357 *
358 * @param $question LP_Question
359 * @param $new_type
360 *
361 * @return bool|int|LP_Question
362 */
363 public function change_question_type( $question, $new_type ) {
364 if ( learn_press_get_post_type( $question->get_id() ) != LP_QUESTION_CPT ) {
365 return false;
366 }
367
368 $question_id = $question->get_id();
369 $old_type = $question->get_type();
370
371 /*if ( $old_type == $new_type ) {
372 return false;
373 }*/
374
375 $answer_options = $question->get_data( 'answer_options' );
376
377 update_post_meta( $question_id, '_lp_type', $new_type );
378 $question->set_type( $new_type );
379
380 $new_question = LP_Question::get_question( $question_id, array( 'force' => true ) );
381
382 if ( $new_question ) {
383 $user_id = get_current_user_id();
384 update_user_meta( $user_id, '_learn_press_memorize_question_types', $new_type );
385
386 if ( $old_type == 'multi_choice' && $new_type == 'single_choice' ) {
387 $func = '_convert_answers_multi_choice_to_single_choice';
388 } elseif ( ( $old_type == 'multi_choice' || $old_type == 'single_choice' ) && 'true_or_false' == $new_type ) {
389 $func = '_convert_answers_to_true_or_false';
390 } else {
391 // for rest, clear answer data and create default
392 $func = '_convert_default_answers';
393 }
394
395 if ( is_callable( array( $this, $func ) ) ) {
396 $answer_options = call_user_func_array(
397 array( $this, $func ),
398 array(
399 $question,
400 $new_question,
401 $answer_options,
402 )
403 );
404 }
405
406 LP_Object_Cache::set( 'answer-options-' . $question_id, $answer_options, 'learn-press/questions' );
407 $new_question->set_data( 'answer_options', $answer_options );
408
409 return $new_question;
410 }
411
412 return false;
413 }
414
415 /**
416 * Update answer title
417 *
418 * @param $question_id
419 * @param $answer
420 *
421 * @return bool|false|int
422 */
423 public function update_answer_title( $question_id, $answer ) {
424 if ( get_post_type( $question_id ) !== LP_QUESTION_CPT ) {
425 return false;
426 }
427
428 global $wpdb;
429
430 // question data
431 $data = array(
432 'data' => apply_filters(
433 'learn-press/question/update-answer-data',
434 array(
435 'title' => $answer['title'],
436 'value' => isset( $answer['value'] ) ? $answer['value'] : '',
437 'is_true' => isset( $answer['is_true'] ) ? $answer['is_true'] : '',
438 )
439 ),
440 'where' => array(
441 'question_answer_id' => $answer['question_answer_id'],
442 'question_id' => $question_id,
443 ),
444 );
445
446 $update = $wpdb->update(
447 $wpdb->learnpress_question_answers,
448 $data['data'],
449 $data['where'],
450 array( '%s', '%s', '%s' ),
451 array( '%d', '%d' )
452 );
453
454 // Update for Fill in Blanks.
455 if ( ! empty( $answer['blanks'] ) ) {
456 $blanks = $answer['blanks'];
457
458 if ( is_array( $blanks ) ) {
459 $question = LP_Question::get_question( $question_id );
460
461 foreach ( $blanks as $id => $blank ) {
462 $question->_blanks[ $blank['id'] ] = $blank;
463 }
464 }
465
466 learn_press_update_question_answer_meta( $answer['question_answer_id'], '_blanks', $blanks );
467 }
468
469 return $update;
470 }
471
472 /**
473 * Update correct answer.
474 *
475 * @param $question LP_Question
476 * @param $correct
477 *
478 * @return bool | LP_Question
479 */
480 public function change_correct_answer( $question, $correct ) {
481 if ( learn_press_get_post_type( $question->get_id() ) != LP_QUESTION_CPT ) {
482 return false;
483 }
484
485 global $wpdb;
486
487 $question_id = $question->get_id();
488 $question_type = $question->get_type();
489 $question_answers = $question->get_data( 'answer_options' );
490
491 $db_args = $answers = array();
492
493 foreach ( $question_answers as $index => $answer ) {
494
495 $answer_data = array(
496 'title' => $answer['title'],
497 'value' => isset( $answer['value'] ) ? stripslashes( $answer['value'] ) : '',
498 'is_true' => isset( $answer['is_true'] ) ? $answer['is_true'] : '',
499 );
500
501 // update correct for select answer
502 if ( $answer['question_answer_id'] == $correct['question_answer_id'] ) {
503 $answer_data['is_true'] = $correct['is_true'];
504 } else {
505 // untrue all rest answer with True or false and Single choice question
506 if ( in_array( $question_type, array( 'true_or_false', 'single_choice' ) ) ) {
507 $answer_data['is_true'] = '';
508 }
509 }
510
511 // question answers data to set cache
512 $answers[ $index ] = array(
513 'question_answer_id' => $answer['question_answer_id'],
514 'question_id' => $question_id,
515 'order' => $answer['order'],
516 'title' => $answer_data['title'],
517 'value' => $answer_data['value'],
518 'is_true' => $answer_data['is_true'],
519 );
520
521 // new answers data
522 $db_args[ $index ] = array(
523 'data' => array(
524 'title' => $answer_data['title'],
525 'value' => $answer_data['value'],
526 'is_true' => $answer_data['is_true'],
527 ),
528 'where' => array(
529 'question_answer_id' => $answer['question_answer_id'],
530 'question_id' => $question_id,
531 'order' => $answer['order'],
532 ),
533 );
534 }
535
536 // update db
537 foreach ( $db_args as $id => $arg ) {
538 $wpdb->update(
539 $wpdb->learnpress_question_answers,
540 $arg['data'],
541 $arg['where'],
542 array( '%s', '%s', '%s' ),
543 array( '%d', '%d', '%d' )
544 );
545 }
546
547 // set question answer data
548 $question->set_data( 'answer_options', $answers );
549
550 return $question;
551 }
552
553 /**
554 * Sort answers.
555 *
556 * @since 3.0.0
557 *
558 * @param $question_id
559 * @param array $order
560 *
561 * @return bool|LP_Question
562 */
563 public function sort_answers( $question_id, $order = array() ) {
564
565 if ( learn_press_get_post_type( $question_id ) !== LP_QUESTION_CPT ) {
566 return false;
567 }
568
569 if ( $order ) {
570 $question = LP_Question::get_question( $question_id );
571 $answers = $question->get_data( 'answer_options' );
572
573 global $wpdb;
574 $new_answers = array();
575 foreach ( $order as $index => $answer_id ) {
576 $wpdb->update(
577 $wpdb->learnpress_question_answers,
578 array( 'order' => $index + 1 ),
579 array( 'question_answer_id' => $answer_id )
580 );
581
582 $new_answers[ $answer_id ] = $answers[ $answer_id ];
583 }
584
585 $question->set_data( 'answer_options', $new_answers );
586
587 return $question;
588
589 }
590
591 return false;
592 }
593
594 /**
595 * Delete question answer.
596 *
597 * @param $question_id
598 * @param $answer_id
599 * @param $force
600 *
601 * @return bool|false|int
602 */
603 public function delete_answer( $question_id, $answer_id, $force = false ) {
604
605 if ( learn_press_get_post_type( $question_id ) !== LP_QUESTION_CPT ) {
606 return false;
607 }
608
609 $question = LP_Question::get_question( $question_id );
610
611 // exist answer options
612 $answers = $question->get_data( 'answer_options' );
613
614 global $wpdb;
615
616 // delete all answer in question
617 if ( $force ) {
618 $delete = $wpdb->delete(
619 $wpdb->learnpress_question_answers,
620 array( 'question_id' => $question_id )
621 );
622
623 if ( $delete ) {
624 $question->set_data( 'answer_options', '' );
625 }
626 } else {
627 $delete = $wpdb->delete(
628 $wpdb->learnpress_question_answers,
629 array( 'question_answer_id' => $answer_id )
630 );
631 if ( $delete ) {
632 unset( $answers[ $answer_id ] );
633 $question->set_data( 'answer_options', $answers );
634
635 $this->sort_answers( $question_id, array_keys( $answers ) );
636 }
637 }
638
639 return $delete;
640 }
641
642 /**
643 * Add new answer.
644 *
645 * @param $question_id
646 * @param $new_answer
647 *
648 * @return bool|false|int
649 */
650 public function new_answer( $question_id, $new_answer ) {
651 if ( learn_press_get_post_type( $question_id ) !== LP_QUESTION_CPT ) {
652 return false;
653 }
654
655 $question = LP_Question::get_question( $question_id );
656
657 // exist answer options
658 $answers = $question->get_data( 'answer_options' );
659 // number answer options
660 $number = count( $answers );
661
662 if ( $question->get_type() === 'sorting_choice' ) {
663 $new_answer['is_true'] = 'yes';
664 }
665
666 global $wpdb;
667
668 $new_answer = wp_parse_args(
669 $new_answer,
670 array(
671 'question_id' => $question_id,
672 'title' => '',
673 'value' => learn_press_random_value(),
674 'is_true' => '',
675 'order' => $number + 1,
676 )
677 );
678
679 $insert = $wpdb->insert(
680 $wpdb->learnpress_question_answers,
681 $new_answer,
682 learn_press_map_columns_format(
683 $new_answer,
684 array(
685 'question_id' => '%d',
686 'title' => '%s',
687 'value' => '%s',
688 'is_true' => '%s',
689 'order' => '%d',
690 )
691 )
692 );
693
694 if ( $insert ) {
695 $new_answer['question_answer_id'] = $wpdb->insert_id;
696
697 if ( is_array( $answers ) ) {
698 $answers = array_merge( $answers, array( $new_answer ) );
699 } else {
700 $answers = array( $new_answer );
701 }
702 $question->set_data( 'answer_options', $answers );
703 }
704
705 return $wpdb->insert_id;
706 }
707
708
709 /**
710 * Convert answers to true or false question.
711 *
712 * @since 3.0.0
713 *
714 * @param $question
715 * @param $new_question
716 * @param $answers
717 *
718 * @return mixed
719 */
720 protected function _convert_answers_to_true_or_false( $question, $new_question, $answers ) {
721 if ( is_array( $answers ) ) {
722 // array answer ids
723 $answer_ids = array_keys( $answers );
724
725 if ( sizeof( $answers ) > 2 ) {
726 global $wpdb;
727
728 foreach ( $answers as $key => $answer ) {
729 if ( array_search( $key, $answer_ids ) > 1 ) {
730 $wpdb->delete(
731 $wpdb->learnpress_question_answers,
732 array( 'question_answer_id' => $answer['question_answer_id'] )
733 );
734 }
735 }
736 $answers = array_slice( $answers, 0, 2, true );
737 }
738
739 $correct = 0;
740 foreach ( $answers as $key => $answer ) {
741 if ( $answer['is_true'] == 'yes' ) {
742 $correct += 1;
743 }
744 }
745
746 if ( ! $correct ) {
747 // for single choice deletes all correct, set first option is correct
748 $answers[ $answer_ids[0] ]['is_true'] = 'yes';
749 } elseif ( $correct == 2 ) {
750 // for multiple choice keeps all correct, remove all correct and keep first option
751 $answers[ $answer_ids[1] ]['is_true'] = 'no';
752 }
753 }
754
755 return $answers;
756 }
757
758 /**
759 *
760 * Convert answers for multi choice to single choice question.
761 *
762 * @since 3.0.0
763 *
764 * @param $question
765 * @param $new_question
766 * @param $answers
767 *
768 * @return array
769 */
770 protected function _convert_answers_multi_choice_to_single_choice( $question, $new_question, $answers ) {
771 if ( is_array( $answers ) ) {
772 // array answer ids
773 $answer_ids = array_keys( $answers );
774
775 $correct = 0;
776 foreach ( $answers as $key => $answer ) {
777 if ( $answer['is_true'] == 'yes' ) {
778 $correct += 1;
779 }
780 }
781
782 if ( ! $correct ) {
783 $answers[ $answer_ids[0] ]['is_true'] = 'yes';
784 } elseif ( $correct > 1 ) {
785 // remove all correct and keep first option
786 $answers[ $answer_ids[0] ]['is_true'] = 'no';
787 }
788 }
789
790 return $answers;
791 }
792
793 /**
794 * Convert default answers.
795 *
796 * @param $question LP_Question
797 * @param $new_question LP_Question
798 * @param $answers
799 *
800 * @return array
801 */
802 protected function _convert_default_answers( $question, $new_question, $answers ) {
803 $question_id = $question->get_id();
804 // clear all exists answer
805 $this->clear( $question_id );
806 // set default answer
807 $answer_options = $new_question->get_default_answers();
808
809 if ( is_array( $answer_options ) ) {
810 foreach ( $answer_options as $index => $answer ) {
811 $insert = array(
812 'question_id' => $question_id,
813 'title' => $answer['title'],
814 'value' => isset( $answer['value'] ) ? stripslashes( $answer['value'] ) : '',
815 'is_true' => ( $answer['is_true'] == 'yes' ) ? $answer['is_true'] : '',
816 'order' => $index + 1,
817 );
818 $new_answers[] = $this->add_answer( $new_question->get_type(), $insert );
819 };
820
821 return $new_answers;
822 }
823
824 return $answers;
825 }
826
827 /**
828 * Add question answer.
829 *
830 * @since 3.0.0
831 *
832 * @param string $question_type
833 * @param array $args
834 *
835 * @return array|bool
836 */
837 public function add_answer( $question_type = '', $args = array() ) {
838 global $wpdb;
839
840 $question = LP_Question::get_question( $args['question_id'], array( 'type' => $question_type ) );
841
842 $wpdb->insert(
843 $wpdb->learnpress_question_answers,
844 array(
845 'question_id' => $args['question_id'],
846 'title' => $args['title'],
847 'value' => $args['value'],
848 'is_true' => $args['is_true'],
849 'order' => $args['order'],
850 ),
851 array( '%d', '%s', '%s', '%s', '%d' )
852 );
853
854 $question_answer_id = $wpdb->insert_id;
855 if ( $question_answer_id ) {
856 // update question answer option data
857 $answer_options = $question->get_data( 'answer_options' ) ? $question->get_data( 'answer_options' ) : array();
858
859 $new_answer_option_data = array(
860 'question_answer_id' => $question_answer_id,
861 'question_id' => $args['question_id'],
862 'order' => $args['order'],
863 'title' => $args['title'],
864 'value' => $args['value'],
865 'is_true' => $args['is_true'],
866 );
867
868 if ( ! $answer_options ) {
869 $question->set_data( 'answer_options', array( $new_answer_option_data ) );
870 } else {
871 $answer_options[] = $new_answer_option_data;
872 $question->set_data( 'answer_options', $answer_options );
873 }
874
875 return $new_answer_option_data;
876 } else {
877 return false;
878 }
879 }
880
881 /**
882 * Delete question answer.
883 *
884 * @since 3.0.0
885 *
886 * @param $question_id
887 * @param $answer_id
888 *
889 * @return bool|false|int
890 */
891 public function delete_question_answer( $question_id, $answer_id ) {
892 if ( learn_press_get_post_type( $question_id ) !== LP_QUESTION_CPT || ! $answer_id ) {
893 return false;
894 }
895
896 global $wpdb;
897
898 $result = $wpdb->delete(
899 $wpdb->learnpress_question_answers,
900 array( 'question_answer_id' => $answer_id )
901 );
902
903 return $result;
904 }
905
906 /**
907 * Delete all question answers.
908 *
909 * @param $question_id
910 *
911 * @return bool|WP_Error
912 */
913 public function clear( $question_id ) {
914
915 if ( ! learn_press_get_question( $question_id ) ) {
916 return $this->get_error( 'QUESTION_NOT_EXISTS' );
917 }
918
919 do_action( 'learn-press/before-clear-question', $question_id );
920
921 global $wpdb;
922 $wpdb->delete( $wpdb->learnpress_question_answers, array( 'question_id' => $question_id ) );
923
924 return true;
925 }
926
927 /**
928 * Load answer options for the question from database.
929 * Load from cache if data is already loaded into cache.
930 * Otherwise, load from database and put to cache.
931 *
932 * @param int $question_id
933 *
934 * @return array
935 */
936 protected function _read_answers( $question_id ) {
937 global $wpdb;
938
939 $query = $wpdb->prepare(
940 "
941 SELECT question_answer_id, title, value, is_true
942 FROM {$wpdb->prefix}learnpress_question_answers
943 WHERE question_id = %d
944 ORDER BY `order` ASC
945 ",
946 $question_id
947 );
948
949 $answer_options = array();
950
951 $results = $wpdb->get_results( $query );
952
953 if ( $results ) {
954 foreach ( $results as $k => $v ) {
955 $answer_option = array(
956 'question_answer_id' => absint( $v->question_answer_id ),
957 'title' => $v->title,
958 'value' => $v->value,
959 'is_true' => $v->is_true,
960 'order' => $k + 1, // Need???
961 );
962
963 $answer_options[ $v->question_answer_id ] = $answer_option;
964 }
965 }
966
967 return $answer_options;
968 }
969
970 /**
971 * Load answer options for the question from database.
972 * Load from cache if data is already loaded into cache.
973 * Otherwise, load from database and put to cache.
974 *
975 * @param $question LP_Question
976 * @deprecated 4.1.7
977 */
978 /*protected function _load_answer_options( &$question ) {
979 $id = $question->get_id();
980 $answer_options = LP_Object_Cache::get( 'answer-options-' . $id, 'lp-questions' );
981
982 if ( false === $answer_options ) {
983 global $wpdb;
984 $query = $wpdb->prepare(
985 "
986 SELECT *
987 FROM {$wpdb->prefix}learnpress_question_answers
988 WHERE question_id = %d
989 ORDER BY `order` ASC
990 ",
991 $id
992 );
993
994 $answer_options = $this->load_answer_options( $question->get_id() );
995 }
996 $answer_options = apply_filters( 'learn-press/question/load-answer-options', $answer_options, $id );
997
998 if ( ! empty( $answer_options['question_answer_id'] ) && $answer_options['question_answer_id'] > 0 ) {
999 $this->_load_answer_option_meta( $answer_options );
1000 }
1001 LP_Object_Cache::set( 'answer-options-' . $id, $answer_options, 'lp-questions' );
1002
1003 $question->set_data( 'answer_options', $answer_options );
1004 }*/
1005
1006 /**
1007 * Load question answers
1008 *
1009 * @updated 3.1.0
1010 *
1011 * @param array|int $question_id
1012 *
1013 * @return array|bool
1014 */
1015 public function load_answer_options( $question_id ) {
1016 global $wpdb;
1017
1018 $return_id = 0;
1019
1020 if ( is_array( $question_id ) ) {
1021
1022 foreach ( $question_id as $q_id ) {
1023 $this->load_answer_options( $q_id );
1024 if ( ! $return_id ) {
1025 $return_id = $q_id;
1026 }
1027 }
1028 $question_id = $return_id;
1029 }
1030
1031 $answer_options = LP_Object_Cache::get( 'question-' . $question_id, 'question-answers' );
1032
1033 if ( false === $answer_options ) {
1034 $answer_options = $this->_read_answers( $question_id );
1035 LP_Object_Cache::set( 'question-' . $question_id, $answer_options, 'question-answers' );
1036 }
1037
1038 return $answer_options;
1039 }
1040
1041 /**
1042 * Load meta data for answer options.
1043 *
1044 * @param array $answer_options
1045 *
1046 * @return mixed;
1047 * @deprecated 4.1.7
1048 */
1049 /*protected function _load_answer_option_meta( &$answer_options ) {
1050 if ( ! $answer_options ) {
1051 return false;
1052 }
1053
1054 $answer_option_ids = wp_list_pluck( $answer_options, 'question_answer_id' );
1055 $format = array_fill( 0, sizeof( $answer_option_ids ), '%d' );
1056 $query = $wpdb->prepare(
1057 "
1058 SELECT *
1059 FROM {$wpdb->prefix}learnpress_question_answermeta
1060 WHERE learnpress_question_answer_id IN(" . join( ', ', $format ) . ')
1061 ',
1062 $answer_option_ids
1063 );
1064
1065 $metas = $wpdb->get_results( $query );
1066
1067 if ( $metas ) {
1068 foreach ( $metas as $meta ) {
1069 $key = $meta->meta_key;
1070 $option_key = $meta->learnpress_question_answer_id;
1071 if ( ! empty( $answer_options[ $option_key ] ) ) {
1072 if ( $key == 'checked' ) {
1073 $key = 'is_true';
1074 }
1075 $answer_options[ $option_key ][ $key ] = $meta->meta_value;
1076 }
1077 }
1078 }
1079
1080 return true;
1081 }*/
1082
1083 public function add_meta( &$object, $meta ) {
1084 // TODO: Implement add_meta() method.
1085 }
1086
1087 public function delete_meta( &$object, $meta ) {
1088 // TODO: Implement delete_meta() method.
1089 }
1090
1091 public function read_meta( &$object ) {
1092 // TODO: Implement read_meta() method.
1093 }
1094
1095 public function update_meta( &$object, $meta ) {
1096 // TODO: Implement update_meta() method.
1097 }
1098 }
1099 }
1100