map_to_object( $data ); } if ( is_null( $this->meta_data ) ) { $this->meta_data = new stdClass(); } } /** * Map array, object data to QuestionAnswerModel. * Use for data get from database. * * @param array|object|mixed $data * * @return QuestionAnswerModel */ public function map_to_object( $data ): QuestionAnswerModel { foreach ( $data as $key => $value ) { if ( property_exists( $this, $key ) ) { $this->{$key} = $value; } } return $this; } /** * Get question post model. * * @return QuestionPostModel|false */ public function get_question_post_model() { return QuestionPostModel::find( $this->question_id, true ); } /** * Find question answer by question_answer_id. * * @param int $question_answer_id * @param bool $check_cache * * @return QuestionAnswerModel|false * @throws Exception */ public static function find( int $question_answer_id, bool $check_cache = false ) { $model = null; $filter = new QuestionAnswersFilter(); $filter->question_answer_id = $question_answer_id; $key_cache = "questionAnswerModel/find/{$question_answer_id}"; $cache = new LP_Cache(); // Check cache if ( $check_cache ) { $model = $cache->get_cache( $key_cache ); if ( $model instanceof QuestionAnswerModel ) { return $model; } } $db = QuestionAnswersDB::getInstance(); $db->get_query_single_row( $filter ); $query_single_row = $db->get_question_answers( $filter ); $rs = $db->wpdb->get_row( $query_single_row ); if ( $rs instanceof stdClass ) { $model = new static( $rs ); } // Set cache if ( $model instanceof QuestionAnswerModel ) { $cache->set_cache( $key_cache, $model ); } return $model; } /** * Get all meta_data * * @return mixed|null */ public function get_all_metadata() { if ( $this->is_get_all_metadata ) { return $this->meta_data; } $questionPostModel = $this->get_question_post_model(); if ( $questionPostModel && $questionPostModel->get_type() === 'fill_in_blanks' ) { $blanks = learn_press_get_question_answer_meta( $this->question_answer_id, '_blanks' ); $this->meta_data = $blanks; $this->is_get_all_metadata = true; } return $this->meta_data; } /** * Get meta value by key. * * @param string $key * @param mixed $value * * @return void * @since 4.2.9 * @version 1.0.0 */ public function save_meta_value_by_key( string $key, $value ) { if ( ! $this->meta_data instanceof stdClass ) { $this->meta_data = new stdClass(); } $this->meta_data->{$key} = $value; update_metadata( 'learnpress_question_answer', $this->question_answer_id, $key, $value ); } /** * Check capabilities of current user to create question answer. * * @throws Exception */ public function check_capabilities_create() { $user = wp_get_current_user(); if ( ! user_can( $user, 'edit_' . LP_LESSON_CPT, $this->question_id ) ) { throw new Exception( __( 'You do not have permission to create answer.', 'learnpress' ) ); } } /** * Check capabilities of current user to update question answer. * * @throws Exception */ public function check_capabilities_update() { $user = wp_get_current_user(); if ( ! user_can( $user, 'edit_' . LP_LESSON_CPT, $this->question_id ) ) { throw new Exception( __( 'You do not have permission to edit this item.', 'learnpress' ) ); } } /** * Update data to database. * * If question_answer_id is empty, insert new data, else update data. * * @throws Exception * @since 4.2.9 * @version 1.0.0 */ public function save() { $db = QuestionAnswersDB::getInstance(); $data = []; foreach ( get_object_vars( $this ) as $property => $value ) { $data[ $property ] = $value; } $args = [ 'data' => $data, 'filter' => new QuestionAnswersFilter(), 'table_name' => $db->tb_lp_question_answers, ]; // Check if exists course id. if ( empty( $this->question_answer_id ) ) { // Insert data. $this->check_capabilities_create(); $args['key_auto_increment'] = 'question_answer_id'; $this->question_answer_id = $db->insert_data( $args ); } else { // Update data. $this->check_capabilities_update(); $args['where_key'] = 'question_answer_id'; $db->update_data( $args ); } $this->clean_caches(); } /** * @throws Exception * * @since 4.2.9 * @version 1.0.1 */ public function check_valid_before_delete() { $questionPostModel = $this->get_question_post_model(); if ( ! $questionPostModel ) { throw new Exception( __( 'Question not found', 'learnpress' ) ); } $this->check_capabilities_update(); if ( $questionPostModel->get_type() === 'single_choice' || $questionPostModel->get_type() === 'multi_choice' ) { // For single choice and multiple choice, at least two answer is required. $filter = new QuestionAnswersFilter(); $filter->question_id = $this->question_id; $total_rows = 0; $filter->query_count = true; $answers = (int) QuestionAnswersDB::getInstance()->get_question_answers( $filter, $total_rows ); if ( $answers <= 2 ) { throw new Exception( __( 'At least two answer is required.', 'learnpress' ) ); } } } /** * Delete row * * @throws Exception */ public function delete() { $this->check_valid_before_delete(); $db = QuestionAnswersDB::getInstance(); $filter = new QuestionAnswersFilter(); $filter->where[] = $db->wpdb->prepare( 'AND question_answer_id = %d', $this->question_answer_id ); $filter->collection = $db->tb_lp_question_answers; $db->delete_execute( $filter ); // Clear cache $this->clean_caches(); } /** * Clean caches. */ public function clean_caches() { $lpQuizCache = new LP_Cache(); $key_cache = "questionAnswerModel/find/{$this->question_answer_id}"; $lpQuizCache->clear( $key_cache ); } }