diff --git a/php/admin/functions.php b/php/admin/functions.php index 5fbb6da52..1a0f866b2 100644 --- a/php/admin/functions.php +++ b/php/admin/functions.php @@ -540,7 +540,7 @@ function qsm_generate_question_option( $key, $single_option ) { foreach ( $single_option['options'] as $key => $value ) { ?>
@@ -703,7 +703,7 @@ class="qsm-wizard-step-text"> __( 'Select the system for grading the quiz.', 'quiz-master-next' ), ), 'enable_contact_form' => array( - 'option_name' => __( 'Enable Contact Form', 'quiz-master-next' ), + 'option_name' => __( 'Display a contact form before quiz', 'quiz-master-next' ), 'value' => 0, 'type' => 'radio', 'options' => array( @@ -716,7 +716,6 @@ class="qsm-wizard-step-text"> 0, ), ), - 'help' => __( 'Display a contact form before quiz', 'quiz-master-next' ), ), 'timer_limit' => array( 'option_name' => __( 'Time Limit (in Minute)', 'quiz-master-next' ), @@ -1391,8 +1390,8 @@ function qsm_quiz_theme_settings( $type, $label, $name, $value, $default_value, break; case 'dropdown': $param = array( - 'name' => "settings[". $name ."]", - 'value' => $value, + 'name' => "settings[". $name ."]", + 'value' => $value, 'default_value' => $default_value, ); qsm_get_input_label_selected( $param ); @@ -1508,7 +1507,7 @@ function qsm_get_input_label_selected( $param ) { return; } $value = ''; - + if ( ! empty( $param['value'] ) ) { $value = $param['value']; } diff --git a/php/classes/class-qmn-quiz-manager.php b/php/classes/class-qmn-quiz-manager.php index 26e3d29ca..4c6e17e3f 100644 --- a/php/classes/class-qmn-quiz-manager.php +++ b/php/classes/class-qmn-quiz-manager.php @@ -705,7 +705,17 @@ public function load_questions( $quiz_id, $quiz_options, $is_quiz_page, $questio $term_ids = implode( ',', $category_ids ); $question_id = implode( ',', $question_ids ); $term_ids = ( '' !== $quiz_options->randon_category ) ? $quiz_options->randon_category : $term_ids; - $tq_ids = $wpdb->get_results( "SELECT DISTINCT `term_id`, `question_id` FROM `{$wpdb->prefix}mlw_question_terms` WHERE `question_id` IN ({$question_id}) AND `term_id` IN ({$term_ids}) AND `taxonomy`='qsm_category'", ARRAY_A ); + $tq_ids = $wpdb->get_results( + "SELECT DISTINCT `term_id`, `question_id` + FROM `{$wpdb->prefix}mlw_question_terms` + JOIN `{$wpdb->prefix}mlw_questions` ON `{$wpdb->prefix}mlw_question_terms`.`question_id` = `{$wpdb->prefix}mlw_questions`.`question_id` + WHERE `{$wpdb->prefix}mlw_question_terms`.`question_id` IN ($question_id) + AND `{$wpdb->prefix}mlw_question_terms`.`term_id` IN ($term_ids) + AND `{$wpdb->prefix}mlw_question_terms`.`taxonomy` = 'qsm_category' + AND `{$wpdb->prefix}mlw_questions`.`deleted` = 0 + ", + ARRAY_A + ); $random = array(); if ( ! empty( $tq_ids ) ) { $term_data = array(); @@ -748,7 +758,19 @@ public function load_questions( $quiz_id, $quiz_options, $is_quiz_page, $questio if ( 1 == $quiz_options->randomness_order || 2 == $quiz_options->randomness_order ) { $category_order_sql = 'ORDER BY rand()'; } - $tq_ids[] = $wpdb->get_results( "SELECT DISTINCT `question_id` FROM `{$wpdb->prefix}mlw_question_terms` WHERE `quiz_id` = $quiz_id AND `term_id` = $category AND `taxonomy`='qsm_category' AND question_id NOT IN ($exclude_ids) ".esc_sql( $category_order_sql )." LIMIT $limit", ARRAY_A ); + $tq_ids[] = $wpdb->get_results( + "SELECT DISTINCT q.`question_id` + FROM `{$wpdb->prefix}mlw_questions` AS q + JOIN `{$wpdb->prefix}mlw_question_terms` AS qt ON q.`question_id` = qt.`question_id` + WHERE qt.`quiz_id` = $quiz_id + AND qt.`term_id` = $category + AND qt.`taxonomy` = 'qsm_category' + AND qt.`question_id` NOT IN ($exclude_ids) + AND q.`deleted` = 0 + ".esc_sql( $category_order_sql )." + LIMIT $limit", + ARRAY_A + ); } $final_result = array_column(array_merge(...array_map('array_merge', $tq_ids)),'question_id'); if ( 1 == $quiz_options->randomness_order || 2 == $quiz_options->randomness_order ) { diff --git a/php/classes/class-qsm-quiz-api.php b/php/classes/class-qsm-quiz-api.php index 63013af1f..de0c5f873 100644 --- a/php/classes/class-qsm-quiz-api.php +++ b/php/classes/class-qsm-quiz-api.php @@ -11,7 +11,7 @@ * @since 4.0.0 */ class QSMQuizApi { - + public function __construct() { add_action( 'rest_api_init', array( $this, 'register_routes' ) ); add_action( 'wp_ajax_regenerate_api_key', array( $this, 'regenerate_api_key' ) ); @@ -64,8 +64,8 @@ public function register_routes() { } public function regenerate_api_key() { - if ( ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( $_POST['nonce'], 'regenerate_api_key_nonce' ) ) { - wp_send_json_error( 'Invalid nonce.' ); + if ( ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['nonce'] ) ), 'regenerate_api_key_nonce' ) ) { + wp_send_json_error( __('Invalid nonce.', 'quiz-master-next' ) ); } $api_key = bin2hex(random_bytes(16)); $api_key = password_hash($api_key, PASSWORD_BCRYPT); @@ -73,18 +73,18 @@ public function regenerate_api_key() { } public function load_form_field() { - - if ( isset($_POST['qsm_api_form_nonce']) && wp_verify_nonce($_POST['qsm_api_form_nonce'], 'qsm_api_form') && isset($_POST['qsm_api_settings']) ) { - $qsm_api_settings = maybe_serialize($_POST['qsm_api_settings']); + + if ( isset($_POST['qsm_api_form_nonce']) && wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['qsm_api_form_nonce'] ) ), 'qsm_api_form') && isset($_POST['qsm_api_settings']) ) { + $qsm_api_settings = maybe_serialize( qsm_sanitize_rec_array( wp_unslash( $_POST['qsm_api_settings'] ) ) ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized update_option('qsm_quiz_api_settings', $qsm_api_settings); } - + $qsm_api_settings_serialized = get_option('qsm_quiz_api_settings'); if ( $qsm_api_settings_serialized ) { $qsm_api_settings = maybe_unserialize($qsm_api_settings_serialized); } else { - + $default_api_settings = array( 'api_key' => '', 'get_questions' => '', @@ -147,7 +147,7 @@ public function load_form_field() { - get_header('authorization'); $verification = $this->qsm_verify_api_key_settings($api_key_param, 'get_result'); if ( $verification['success'] ) { if ( $request->get_param('result_id') ) { global $wpdb; $results_data = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}mlw_results WHERE result_id = %d", $request->get_param('result_id') ) ); - + if ( $results_data ) { $results_data->quiz_results = maybe_unserialize($results_data->quiz_results); $response = array( @@ -217,34 +217,34 @@ public function qsm_get_quiz_result_info( WP_REST_Request $request ) { $from_date = $request->get_param('from_date'); $order = $request->get_param('order'); $s = $request->get_param('s'); - + $query = "SELECT * FROM {$wpdb->prefix}mlw_results WHERE 1=1"; $limit = empty($limit) ? 10 : $limit; $order = empty($order) ? 'ASC' : $order; - + if ( ! empty($quiz_id) ) { $query .= $wpdb->prepare(" AND quiz_id = %s", $quiz_id); } - + if ( ! empty($s) ) { $rsearch = '%' . esc_sql( $wpdb->esc_like( $s ) ) . '%'; $query .= $wpdb->prepare(" AND (name LIKE %s OR quiz_name LIKE %s OR email LIKE %s)", $rsearch, $rsearch, $rsearch); } - + if ( ! empty($name) ) { $query .= $wpdb->prepare(" AND name = %s", $name); } - + if ( ! empty($email) ) { $query .= $wpdb->prepare(" AND email = %s", $email); } - + if ( ! empty($from_date) ) { $query .= $wpdb->prepare( " AND time_taken_real >= %s", $from_date ); } - + $results = $wpdb->get_results($query .= " ORDER BY result_id {$order} LIMIT {$limit}"); - + if ( $results ) { $data = []; foreach ( $results as $key => $value ) { @@ -262,7 +262,7 @@ public function qsm_get_quiz_result_info( WP_REST_Request $request ) { 'message' => "", ); } - + if ( ! $results ) { if ( ! $request->get_param('result_id') && ! $request->get_param('quizId') && empty($name) && empty($email) && ! $request->get_param('from_date') ) { $response['message'] = __('No quiz results available.found for the specified criteria.', 'quiz-master-next'); @@ -285,7 +285,7 @@ public function qsm_get_quiz_result_info( WP_REST_Request $request ) { } return rest_ensure_response($response); } - + public function qsm_get_quiz_info( WP_REST_Request $request ) { $api_key_param = $request->get_header('authorization'); $verification = $this->qsm_verify_api_key_settings($api_key_param, 'get_quiz'); @@ -365,26 +365,26 @@ public function qsm_get_quiz_info( WP_REST_Request $request ) { public function qsm_convert_to_api_format( $inputObject ) { $apiFormat = []; - + foreach ( $inputObject as $key => $value ) { - if ( $key === 'message_after' || $key === 'user_email_template' || $key === 'quiz_settings' ) { + if ( 'message_after' === $key || 'user_email_template' === $key || 'quiz_settings' === $key ) { $apiFormat[ $key ] = maybe_unserialize($value); - if ( $key === 'quiz_settings' ) { + if ( 'quiz_settings' === $key ) { $apiFormat[ $key ] = $this->qsm_unserialize_to_api_format($apiFormat[ $key ]); } } elseif ( is_array($value) || is_object($value) ) { - $apiFormat[ $key ] = $this->qsm_convert_to_api_format($value); + $apiFormat[ $key ] = $this->qsm_convert_to_api_format($value); } else { $apiFormat[ $key ] = $value; } } - + return $apiFormat; } - + public function qsm_unserialize_to_api_format( $data ) { $result = array(); - + if ( is_serialized($data) ) { return maybe_unserialize($data); } @@ -398,19 +398,19 @@ public function qsm_unserialize_to_api_format( $data ) { } } } - + return $result; } - + public function qsm_unserialize_recursive_loop( $value ) { $unserializedValue = maybe_unserialize($value); - + if ( is_array($unserializedValue) ) { foreach ( $unserializedValue as $innerKey => $innerValue ) { $unserializedValue[ $innerKey ] = $this->qsm_unserialize_recursive_loop($innerValue); } } - + return $unserializedValue; } @@ -441,28 +441,28 @@ public function qsm_get_quiz_questions( WP_REST_Request $request ) { $question_name = $request->get_param('question_name' ); $quiz_id = $request->get_param('quizId' ); $limit = $request->get_param( 'limit' ) ? $request->get_param( 'limit' ) : 10; - + $query = "SELECT * FROM {$wpdb->prefix}mlw_questions WHERE 1=1"; - + if ( ! empty($question_name) ) { $qnsearch = '%' . esc_sql( $wpdb->esc_like( $question_name ) ) . '%'; $query .= $wpdb->prepare(" AND question_name LIKE %s", $qnsearch); } - + if ( ! empty($quiz_id) ) { $query .= $wpdb->prepare( " AND quiz_id=%d", $quiz_id ); } - + $results = $wpdb->get_results($query .= " LIMIT {$limit}"); - + if ( $results ) { - + foreach ( $results as $key => $result ) { $result->answer_array = maybe_unserialize( $result->answer_array ); $result->question_settings = maybe_unserialize( $result->question_settings ); $data[] = $result; } - + $response = array( 'count' => count($data), 'success' => true, @@ -474,7 +474,7 @@ public function qsm_get_quiz_questions( WP_REST_Request $request ) { 'message' => "", ); } - + if ( ! $results ) { if ( ! $request->get_param('quizId') && ! $request->get_param('question_name') ) { $response['message'] = __('No quiz results available.', 'quiz-master-next'); @@ -495,18 +495,18 @@ public function qsm_get_quiz_questions( WP_REST_Request $request ) { } return $response; } - + public function qsm_api_quiz_submit( $request ) { - + $qsm_api_settings_serialized = get_option('qsm_quiz_api_settings'); $api_key = $request->get_header('authorization'); if ( $qsm_api_settings_serialized ) { - $qsm_api_settings = maybe_unserialize($qsm_api_settings_serialized); - + $qsm_api_settings = maybe_unserialize($qsm_api_settings_serialized); + if ( ($api_key && "" != $api_key) && (isset($qsm_api_settings['api_key']) && ("" != $qsm_api_settings['api_key'] && $api_key == $qsm_api_settings['api_key'])) && isset($qsm_api_settings['allow_submit_quiz']) && "1" == $qsm_api_settings['allow_submit_quiz'] ) { - + $quiz_id = ! empty( $_POST['qmn_quiz_id'] ) ? sanitize_text_field( wp_unslash( $_POST['qmn_quiz_id'] ) ) : 0 ; - + global $qmn_allowed_visit, $mlwQuizMasterNext, $wpdb, $qmnQuizManager; $qmn_allowed_visit = true; $qmnQuizManager = new QMNQuizManager(); @@ -521,11 +521,11 @@ public function qsm_api_quiz_submit( $request ) { 'fields' => 'ids', 'numberposts' => 1, )); - + if ( ! empty( $post_ids[0] ) ) { $post_status = get_post_status( $post_ids[0] ); } - + if ( is_null( $options ) || 1 == $options->deleted ) { echo wp_json_encode( array( @@ -550,11 +550,11 @@ public function qsm_api_quiz_submit( $request ) { ); wp_die(); } - + $qsm_option = isset( $options->quiz_settings ) ? maybe_unserialize( $options->quiz_settings ) : array(); $qsm_option = array_map( 'maybe_unserialize', $qsm_option ); $post_status = false; - + if ( 0 != $options->limit_total_entries ) { $mlw_qmn_entries_count = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(quiz_id) FROM {$wpdb->prefix}mlw_results WHERE deleted=0 AND quiz_id=%d", $options->quiz_id ) ); if ( $mlw_qmn_entries_count >= $options->limit_total_entries ) { @@ -606,7 +606,7 @@ public function qsm_api_quiz_submit( $request ) { ), ); } - + return rest_ensure_response($response); } diff --git a/php/classes/class-qsm-results-pages.php b/php/classes/class-qsm-results-pages.php index d426e1b49..52dd11198 100644 --- a/php/classes/class-qsm-results-pages.php +++ b/php/classes/class-qsm-results-pages.php @@ -177,7 +177,6 @@ public static function generate_pages( $response_data ) { // Decodes special characters, runs through our template // variables, and then outputs the text. - //$page = htmlspecialchars_decode( $content, ENT_QUOTES ); $page = wp_kses_post( $content ); //last chance to filter $page