| @@ -24,9 +24,9 @@ | ||
| 24 | 24 | * LP_Question_CURD constructor. |
| 25 | 25 | */ |
| 26 | 26 | public function __construct() { |
| 27 | 27 | $this->_error_messages = array( |
| 28 | - 'QUESTION_NOT_EXISTS' => __( 'Question does not exist.', 'learnpress' ), | |
| 28 | + 'QUESTION_NOT_EXISTS' => __( 'The question does not exist.', 'learnpress' ), | |
| 29 | 29 | ); |
| 30 | 30 | } |
| 31 | 31 | |
| 32 | 32 | /** |
| @@ -84,16 +84,16 @@ | ||
| 84 | 84 | |
| 85 | 85 | $question = LP_Question::get_question( $question_id, array( 'type' => $args['type'] ) ); |
| 86 | 86 | $question->set_type( $args['type'] ); |
| 87 | 87 | |
| 88 | + // add question to quiz | |
| 89 | + if ( ! empty( $args['quiz_id'] ) ) { | |
| 90 | + $quiz_curd = new LP_Quiz_CURD(); | |
| 91 | + $quiz_curd->add_question( $args['quiz_id'], $question_id, $args['order'] ); | |
| 92 | + } | |
| 93 | + | |
| 88 | 94 | if ( $args['create_answers'] ) { |
| 89 | 95 | $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 | 96 | } |
| 97 | 97 | |
| 98 | 98 | do_action( 'learn-press/after-create-question', $question ); |
| 99 | 99 | |
| @@ -146,18 +146,18 @@ | ||
| 146 | 146 | * @return mixed|WP_Error |
| 147 | 147 | */ |
| 148 | 148 | public function duplicate( &$question_id, $args = array() ) { |
| 149 | 149 | if ( ! $question_id ) { |
| 150 | - return new WP_Error( __( '<p>Op! ID not found</p>', 'learnpress' ) ); | |
| 150 | + return new WP_Error( 'lp/question/curd/duplicate/err', 'Oops! ID not found' ); | |
| 151 | 151 | } |
| 152 | 152 | |
| 153 | 153 | if ( learn_press_get_post_type( $question_id ) != LP_QUESTION_CPT ) { |
| 154 | - return new WP_Error( __( '<p>Op! The question does not exist</p>', 'learnpress' ) ); | |
| 154 | + return new WP_Error( 'lp/question/curd/duplicate/err', 'Op! The question does not exist' ); | |
| 155 | 155 | } |
| 156 | 156 | |
| 157 | 157 | // ensure that user can create question |
| 158 | 158 | if ( ! current_user_can( 'edit_posts' ) ) { |
| 159 | - return new WP_Error( __( '<p>Sorry! You don\'t have permission to duplicate this question</p>', 'learnpress' ) ); | |
| 159 | + return new WP_Error( 'lp/question/curd/duplicate/err', 'Sorry! You do not have permission to duplicate this question' ); | |
| 160 | 160 | } |
| 161 | 161 | |
| 162 | 162 | // origin question |
| 163 | 163 | $question = LP_Question::get_question( $question_id ); |
| @@ -165,9 +165,9 @@ | ||
| 165 | 165 | // duplicate question |
| 166 | 166 | $new_question_id = learn_press_duplicate_post( $question_id, array( 'post_status' => 'publish' ) ); |
| 167 | 167 | |
| 168 | 168 | if ( ! $new_question_id || is_wp_error( $new_question_id ) ) { |
| 169 | - return new WP_Error( __( '<p>Sorry! Failed to duplicate question!</p>', 'learnpress' ) ); | |
| 169 | + return new WP_Error( 'lp/question/curd/duplicate/err', 'Sorry! Failed to duplicate the question!' ); | |
| 170 | 170 | } else { |
| 171 | 171 | |
| 172 | 172 | // init new question |
| 173 | 173 | $new_question = LP_Question::get_question( $new_question_id ); |
| @@ -182,9 +182,9 @@ | ||
| 182 | 182 | |
| 183 | 183 | // duplicate answer |
| 184 | 184 | $this->duplicate_answer( $question_id, $new_question_id ); |
| 185 | 185 | |
| 186 | - do_action( 'learn-press/after-duplicate', $question_id, $new_question_id, $args ); | |
| 186 | + do_action( 'learn-press/item/after-duplicate', $question_id, $new_question_id, $args ); | |
| 187 | 187 | |
| 188 | 188 | return $new_question_id; |
| 189 | 189 | } |
| 190 | 190 | } |
| @@ -192,31 +192,81 @@ | ||
| 192 | 192 | /** |
| 193 | 193 | * Duplicate answer question. |
| 194 | 194 | * |
| 195 | 195 | * @param $question_id | origin question |
| 196 | - * @param $new_question_id | new question | |
| 197 | - * @TODO tungnx: check duplicate question typ fill_in_blank - must clone row in learnpress_question_answermeta | |
| 196 | + * @param $question_id_clone | new question | |
| 197 | + * @version 3.0.1 | |
| 198 | + * @since 1.0.1 | |
| 198 | 199 | */ |
| 199 | - public function duplicate_answer( $question_id, $new_question_id ) { | |
| 200 | - global $wpdb; | |
| 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(); | |
| 201 | 203 | |
| 202 | - $query = $wpdb->prepare( " SELECT * FROM $wpdb->learnpress_question_answers WHERE question_id = %d", $question_id ); | |
| 203 | - $answer_options = $wpdb->get_results( $query ); | |
| 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_answers( $filter_get_answer_options ); | |
| 204 | 209 | |
| 205 | - if ( $answer_options ) { | |
| 206 | - foreach ( $answer_options as $option ) { | |
| 207 | - $wpdb->insert( | |
| 208 | - $wpdb->learnpress_question_answers, | |
| 209 | - array( | |
| 210 | - 'question_id' => $new_question_id, | |
| 211 | - 'title' => ! empty( $option->title ) ? $option->title : '', | |
| 212 | - 'value' => ! empty( $option->value ) ? $option->value : '', | |
| 213 | - 'is_true' => ! empty( $option->is_true ) ? $option->is_true : '', | |
| 214 | - 'order' => $option->order, | |
| 215 | - ), | |
| 216 | - array( '%d', '%s', '%s', '%s', '%s' ) | |
| 217 | - ); | |
| 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_answers( $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 | + } | |
| 218 | 266 | } |
| 267 | + } catch ( Throwable $e ) { | |
| 268 | + error_log( $e->getMessage() ); | |
| 219 | 269 | } |
| 220 | 270 | } |
| 221 | 271 | |
| 222 | 272 | /** |
| @@ -232,14 +282,10 @@ | ||
| 232 | 282 | if ( ! $id || ! in_array( learn_press_get_post_type( $id ), array( 'revision', LP_QUESTION_CPT ) ) ) { |
| 233 | 283 | throw new Exception( sprintf( __( 'Invalid question with ID "%d".', 'learnpress' ), $id ) ); |
| 234 | 284 | } |
| 235 | 285 | |
| 236 | - $question->set_data_via_methods( | |
| 237 | - array( | |
| 238 | - 'explanation' => get_post_meta( $id, '_lp_explanation', true ), | |
| 239 | - 'hint' => get_post_meta( $id, '_lp_hint', true ), | |
| 240 | - ) | |
| 241 | - ); | |
| 286 | + $question->set_explanation( get_post_meta( $id, '_lp_explanation', true ) ); | |
| 287 | + $question->set_hint( get_post_meta( $id, '_lp_hint', true ) ); | |
| 242 | 288 | // $this->_load_answer_options( $question ); |
| 243 | 289 | $this->_load_meta( $question ); |
| 244 | 290 | |
| 245 | 291 | return true; |
| @@ -255,13 +301,9 @@ | ||
| 255 | 301 | } |
| 256 | 302 | // $question->set_type( $type ); |
| 257 | 303 | |
| 258 | 304 | $mark = $this->_get_question_mark( $question->get_id() ); |
| 259 | - $question->set_data_via_methods( | |
| 260 | - array( | |
| 261 | - 'mark' => $mark, | |
| 262 | - ) | |
| 263 | - ); | |
| 305 | + $question->set_mark( $mark ); | |
| 264 | 306 | } |
| 265 | 307 | |
| 266 | 308 | public function _get_question_mark( $question_id ) { |
| 267 | 309 | |
| @@ -307,24 +349,26 @@ | ||
| 307 | 349 | * |
| 308 | 350 | * @param $question LP_Question |
| 309 | 351 | * @param $new_type |
| 310 | 352 | * |
| 311 | - * @return bool|int|LP_Question | |
| 353 | + * @return false|void | |
| 354 | + * @since 3.0.0 | |
| 355 | + * @version 1.0.1 | |
| 312 | 356 | */ |
| 313 | - public function change_question_type( $question, $new_type ) { | |
| 357 | + public function change_question_type( &$question, $new_type ) { | |
| 314 | 358 | if ( learn_press_get_post_type( $question->get_id() ) != LP_QUESTION_CPT ) { |
| 315 | 359 | return false; |
| 316 | 360 | } |
| 317 | 361 | |
| 318 | 362 | $question_id = $question->get_id(); |
| 319 | - $old_type = $question->get_type(); | |
| 320 | 363 | |
| 321 | - /*if ( $old_type == $new_type ) { | |
| 322 | - return false; | |
| 323 | - }*/ | |
| 364 | + // If not new Question or not change type return | |
| 365 | + $old_type = get_post_meta( $question_id, '_lp_type', true ); | |
| 366 | + if ( ! empty( $old_type ) && $old_type === $new_type ) { | |
| 367 | + return; | |
| 368 | + } | |
| 324 | 369 | |
| 325 | 370 | $answer_options = $question->get_data( 'answer_options' ); |
| 326 | - | |
| 327 | 371 | update_post_meta( $question_id, '_lp_type', $new_type ); |
| 328 | 372 | $question->set_type( $new_type ); |
| 329 | 373 | |
| 330 | 374 | $new_question = LP_Question::get_question( $question_id, array( 'force' => true ) ); |
| @@ -355,12 +399,10 @@ | ||
| 355 | 399 | |
| 356 | 400 | LP_Object_Cache::set( 'answer-options-' . $question_id, $answer_options, 'learn-press/questions' ); |
| 357 | 401 | $new_question->set_data( 'answer_options', $answer_options ); |
| 358 | 402 | |
| 359 | - return $new_question; | |
| 403 | + $question = $new_question; | |
| 360 | 404 | } |
| 361 | - | |
| 362 | - return false; | |
| 363 | 405 | } |
| 364 | 406 | |
| 365 | 407 | /** |
| 366 | 408 | * Update answer title |
| @@ -382,10 +424,10 @@ | ||
| 382 | 424 | 'data' => apply_filters( |
| 383 | 425 | 'learn-press/question/update-answer-data', |
| 384 | 426 | array( |
| 385 | 427 | 'title' => $answer['title'], |
| 386 | - 'value' => isset( $answer['value'] ) ? $answer['value'] : '', | |
| 387 | - 'is_true' => isset( $answer['is_true'] ) ? $answer['is_true'] : '', | |
| 428 | + 'value' => $answer['value'] ?? '', | |
| 429 | + 'is_true' => $answer['is_true'] ?? '', | |
| 388 | 430 | ) |
| 389 | 431 | ), |
| 390 | 432 | 'where' => array( |
| 391 | 433 | 'question_answer_id' => $answer['question_answer_id'], |
| @@ -404,15 +446,15 @@ | ||
| 404 | 446 | // Update for Fill in Blanks. |
| 405 | 447 | if ( ! empty( $answer['blanks'] ) ) { |
| 406 | 448 | $blanks = $answer['blanks']; |
| 407 | 449 | |
| 408 | - if ( is_array( $blanks ) ) { | |
| 450 | + /*if ( is_array( $blanks ) ) { | |
| 409 | 451 | $question = LP_Question::get_question( $question_id ); |
| 410 | 452 | |
| 411 | 453 | foreach ( $blanks as $id => $blank ) { |
| 412 | 454 | $question->_blanks[ $blank['id'] ] = $blank; |
| 413 | 455 | } |
| 414 | - } | |
| 456 | + }*/ | |
| 415 | 457 | |
| 416 | 458 | learn_press_update_question_answer_meta( $answer['question_answer_id'], '_blanks', $blanks ); |
| 417 | 459 | } |
| 418 | 460 | |
| @@ -562,29 +604,23 @@ | ||
| 562 | 604 | $answers = $question->get_data( 'answer_options' ); |
| 563 | 605 | |
| 564 | 606 | global $wpdb; |
| 565 | 607 | |
| 566 | - // delete all answer in question | |
| 567 | - if ( $force ) { | |
| 568 | - $delete = $wpdb->delete( | |
| 569 | - $wpdb->learnpress_question_answers, | |
| 570 | - array( 'question_id' => $question_id ) | |
| 571 | - ); | |
| 608 | + // Delete answer meta | |
| 609 | + $wpdb->delete( | |
| 610 | + $wpdb->learnpress_question_answermeta, | |
| 611 | + array( 'learnpress_question_answer_id' => $answer_id ) | |
| 612 | + ); | |
| 572 | 613 | |
| 573 | - if ( $delete ) { | |
| 574 | - $question->set_data( 'answer_options', '' ); | |
| 575 | - } | |
| 576 | - } else { | |
| 577 | - $delete = $wpdb->delete( | |
| 578 | - $wpdb->learnpress_question_answers, | |
| 579 | - array( 'question_answer_id' => $answer_id ) | |
| 580 | - ); | |
| 581 | - if ( $delete ) { | |
| 582 | - unset( $answers[ $answer_id ] ); | |
| 583 | - $question->set_data( 'answer_options', $answers ); | |
| 614 | + $delete = $wpdb->delete( | |
| 615 | + $wpdb->learnpress_question_answers, | |
| 616 | + array( 'question_answer_id' => $answer_id ) | |
| 617 | + ); | |
| 618 | + if ( $delete ) { | |
| 619 | + unset( $answers[ $answer_id ] ); | |
| 620 | + $question->set_data( 'answer_options', $answers ); | |
| 584 | 621 | |
| 585 | - $this->sort_answers( $question_id, array_keys( $answers ) ); | |
| 586 | - } | |
| 622 | + $this->sort_answers( $question_id, array_keys( $answers ) ); | |
| 587 | 623 | } |
| 588 | 624 | |
| 589 | 625 | return $delete; |
| 590 | 626 | } |
| @@ -917,43 +953,8 @@ | ||
| 917 | 953 | return $answer_options; |
| 918 | 954 | } |
| 919 | 955 | |
| 920 | 956 | /** |
| 921 | - * Load answer options for the question from database. | |
| 922 | - * Load from cache if data is already loaded into cache. | |
| 923 | - * Otherwise, load from database and put to cache. | |
| 924 | - * | |
| 925 | - * @param $question LP_Question | |
| 926 | - */ | |
| 927 | - protected function _load_answer_options( &$question ) { | |
| 928 | - $id = $question->get_id(); | |
| 929 | - $answer_options = LP_Object_Cache::get( 'answer-options-' . $id, 'lp-questions' ); | |
| 930 | - | |
| 931 | - if ( false === $answer_options ) { | |
| 932 | - global $wpdb; | |
| 933 | - $query = $wpdb->prepare( | |
| 934 | - " | |
| 935 | - SELECT * | |
| 936 | - FROM {$wpdb->prefix}learnpress_question_answers | |
| 937 | - WHERE question_id = %d | |
| 938 | - ORDER BY `order` ASC | |
| 939 | - ", | |
| 940 | - $id | |
| 941 | - ); | |
| 942 | - | |
| 943 | - $answer_options = $this->load_answer_options( $question->get_id() ); | |
| 944 | - } | |
| 945 | - $answer_options = apply_filters( 'learn-press/question/load-answer-options', $answer_options, $id ); | |
| 946 | - | |
| 947 | - if ( ! empty( $answer_options['question_answer_id'] ) && $answer_options['question_answer_id'] > 0 ) { | |
| 948 | - $this->_load_answer_option_meta( $answer_options ); | |
| 949 | - } | |
| 950 | - LP_Object_Cache::set( 'answer-options-' . $id, $answer_options, 'lp-questions' ); | |
| 951 | - | |
| 952 | - $question->set_data( 'answer_options', $answer_options ); | |
| 953 | - } | |
| 954 | - | |
| 955 | - /** | |
| 956 | 957 | * Load question answers |
| 957 | 958 | * |
| 958 | 959 | * @updated 3.1.0 |
| 959 | 960 | * |
| @@ -984,64 +985,7 @@ | ||
| 984 | 985 | LP_Object_Cache::set( 'question-' . $question_id, $answer_options, 'question-answers' ); |
| 985 | 986 | } |
| 986 | 987 | |
| 987 | 988 | return $answer_options; |
| 988 | - } | |
| 989 | - | |
| 990 | - /** | |
| 991 | - * Load meta data for answer options. | |
| 992 | - * | |
| 993 | - * @param array $answer_options | |
| 994 | - * | |
| 995 | - * @return mixed; | |
| 996 | - */ | |
| 997 | - protected function _load_answer_option_meta( &$answer_options ) { | |
| 998 | - if ( ! $answer_options ) { | |
| 999 | - return false; | |
| 1000 | - } | |
| 1001 | - | |
| 1002 | - $answer_option_ids = wp_list_pluck( $answer_options, 'question_answer_id' ); | |
| 1003 | - $format = array_fill( 0, sizeof( $answer_option_ids ), '%d' ); | |
| 1004 | - $query = $wpdb->prepare( | |
| 1005 | - " | |
| 1006 | - SELECT * | |
| 1007 | - FROM {$wpdb->prefix}learnpress_question_answermeta | |
| 1008 | - WHERE learnpress_question_answer_id IN(" . join( ', ', $format ) . ') | |
| 1009 | - ', | |
| 1010 | - $answer_option_ids | |
| 1011 | - ); | |
| 1012 | - | |
| 1013 | - $metas = $wpdb->get_results( $query ); | |
| 1014 | - | |
| 1015 | - if ( $metas ) { | |
| 1016 | - foreach ( $metas as $meta ) { | |
| 1017 | - $key = $meta->meta_key; | |
| 1018 | - $option_key = $meta->learnpress_question_answer_id; | |
| 1019 | - if ( ! empty( $answer_options[ $option_key ] ) ) { | |
| 1020 | - if ( $key == 'checked' ) { | |
| 1021 | - $key = 'is_true'; | |
| 1022 | - } | |
| 1023 | - $answer_options[ $option_key ][ $key ] = $meta->meta_value; | |
| 1024 | - } | |
| 1025 | - } | |
| 1026 | - } | |
| 1027 | - | |
| 1028 | - return true; | |
| 1029 | - } | |
| 1030 | - | |
| 1031 | - public function add_meta( &$object, $meta ) { | |
| 1032 | - // TODO: Implement add_meta() method. | |
| 1033 | - } | |
| 1034 | - | |
| 1035 | - public function delete_meta( &$object, $meta ) { | |
| 1036 | - // TODO: Implement delete_meta() method. | |
| 1037 | - } | |
| 1038 | - | |
| 1039 | - public function read_meta( &$object ) { | |
| 1040 | - // TODO: Implement read_meta() method. | |
| 1041 | - } | |
| 1042 | - | |
| 1043 | - public function update_meta( &$object, $meta ) { | |
| 1044 | - // TODO: Implement update_meta() method. | |
| 1045 | 989 | } |
| 1046 | 990 | } |
| 1047 | 991 | } |