From af6429b9ce427a9ba50694dbce4a853d94babdb2 Mon Sep 17 00:00:00 2001 From: Mohammad Zubair Ali Date: Thu, 20 Jun 2024 12:52:28 +0530 Subject: [PATCH 01/12] fixed http_referer issue --- php/classes/class-qmn-quiz-manager.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/classes/class-qmn-quiz-manager.php b/php/classes/class-qmn-quiz-manager.php index 4b3303164..97817780d 100644 --- a/php/classes/class-qmn-quiz-manager.php +++ b/php/classes/class-qmn-quiz-manager.php @@ -1872,7 +1872,7 @@ public function qsm_get_quiz_to_reload() { */ private function add_quiz_results( $data ) { global $wpdb; - if ( empty( $wpdb ) || empty( $data['qmn_array_for_variables'] ) || empty( $data['results_array'] ) || empty( $data['unique_id'] ) || empty( $data['http_referer'] ) || ! isset( $data['form_type'] ) ) { + if ( empty( $wpdb ) || empty( $data['qmn_array_for_variables'] ) || empty( $data['results_array'] ) || empty( $data['unique_id'] ) || ! isset( $data['http_referer'] ) || ! isset( $data['form_type'] ) ) { return false; } From 66829408d46eac712d003676e1765bdd4d78d28d Mon Sep 17 00:00:00 2001 From: PranavAwasthi Date: Wed, 26 Jun 2024 15:42:26 +0530 Subject: [PATCH 02/12] Fixed category's parent issue --- php/classes/class-qsm-questions.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php/classes/class-qsm-questions.php b/php/classes/class-qsm-questions.php index cd7d7888c..8d54db908 100644 --- a/php/classes/class-qsm-questions.php +++ b/php/classes/class-qsm-questions.php @@ -487,7 +487,7 @@ public static function get_question_categories_from_term_ids( $term_ids ) { $categories_names[ $tax->term_id ] = $tax->name; $taxs[ $tax->parent ][] = $tax; } - $categories_tree = self::create_terms_tree( $taxs, $taxs[0] ); + $categories_tree = self::create_terms_tree( $taxs, isset( $taxs[0] ) ? $taxs[0] : reset( $taxs ) ); } $categories = array( 'list' => $categories_names, @@ -527,7 +527,7 @@ public static function get_question_categories( $question_id = 0 ) { $categories_names[ $tax->term_id ] = $tax->name; $taxs[ $tax->parent ][] = $tax; } - $categories_tree = self::create_terms_tree( $taxs, $taxs[0] ); + $categories_tree = self::create_terms_tree( $taxs, isset( $taxs[0] ) ? $taxs[0] : reset( $taxs ) ); } } From 40d357957f1923e380168fa8daface54a5a5c96b Mon Sep 17 00:00:00 2001 From: PranavAwasthi Date: Thu, 27 Jun 2024 12:28:18 +0530 Subject: [PATCH 03/12] added case sensitive option to text question types --- php/admin/options-page-questions-tab.php | 2 +- php/classes/question-types/class-question-review-text.php | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/php/admin/options-page-questions-tab.php b/php/admin/options-page-questions-tab.php index 9d318afb3..ff2789454 100644 --- a/php/admin/options-page-questions-tab.php +++ b/php/admin/options-page-questions-tab.php @@ -433,7 +433,7 @@ class="save-page-button button button-primary"> __( 'Yes', 'quiz-master-next' ), ), 'default' => '0', - 'show' => '14' . $show_case_sensitive, + 'show' => '3, 5, 14' . $show_case_sensitive, ), 'limit_text' => array( 'heading' => __( 'Limit Text', 'quiz-master-next' ), diff --git a/php/classes/question-types/class-question-review-text.php b/php/classes/question-types/class-question-review-text.php index 79e02cf0a..18a2c9380 100644 --- a/php/classes/question-types/class-question-review-text.php +++ b/php/classes/question-types/class-question-review-text.php @@ -18,8 +18,14 @@ public function set_user_answer() { } public function set_answer_status() { + global $mlwQuizMasterNext; + $case_sensitive = $mlwQuizMasterNext->pluginHelper->get_question_setting( $this->question_id, 'case_sensitive' ); $user_answer_value = $this->user_answer['input']; - $answer_key = array_search( $this->prepare_for_string_matching( $user_answer_value ), array_map( array( $this, 'prepare_for_string_matching' ), $this->correct_answer ), true ); + if ( 1 === intval($case_sensitive ) ) { + $answer_key = array_search( $user_answer_value, $this->correct_answer, true ); + }else { + $answer_key = array_search( $this->prepare_for_string_matching( $user_answer_value ), array_map( array( $this, 'prepare_for_string_matching' ), $this->correct_answer ), true ); + } if ( false !== $answer_key ) { $this->answer_status = 'correct'; $this->points += $this->answer_array[ $answer_key ][1]; From 54e06fd703e5f31d12f52db754d4cca371268152 Mon Sep 17 00:00:00 2001 From: Mohammad Zubair Ali Date: Thu, 27 Jun 2024 16:04:41 +0530 Subject: [PATCH 04/12] added function to check table structure --- mlw_quizmaster2.php | 103 +++++++++++++++++++++++++++++++++++++ php/template-variables.php | 4 +- 2 files changed, 105 insertions(+), 2 deletions(-) diff --git a/mlw_quizmaster2.php b/mlw_quizmaster2.php index 2b6a65ad5..616d2c4c6 100644 --- a/mlw_quizmaster2.php +++ b/mlw_quizmaster2.php @@ -784,6 +784,109 @@ public function admin_failed_submission_page() { $QmnFailedSubmissions->render_list_table(); } } + /** + * Check database structure + * + * @since 9.0.6 + * @return void + */ + public function qsm_check_database_structure() { + global $wpdb; + + // Define the table names + $quiz_table_name = $wpdb->prefix . 'mlw_quizzes'; + $question_table_name = $wpdb->prefix . 'mlw_questions'; + $results_table_name = $wpdb->prefix . 'mlw_results'; + $audit_table_name = $wpdb->prefix . 'mlw_qm_audit_trail'; + $themes_table_name = $wpdb->prefix . 'mlw_themes'; + $quiz_themes_settings_table_name = $wpdb->prefix . 'mlw_quiz_theme_settings'; + $question_terms_table_name = $wpdb->prefix . 'mlw_question_terms'; + + // List of tables and their columns + $tables = [ + $quiz_table_name => [ + 'quiz_id', 'quiz_name', 'message_before', 'message_after', 'message_comment', 'message_end_template', + 'user_email_template', 'admin_email_template', 'submit_button_text', 'name_field_text', 'business_field_text', + 'email_field_text', 'phone_field_text', 'comment_field_text', 'email_from_text', 'question_answer_template', + 'leaderboard_template', 'quiz_system', 'randomness_order', 'loggedin_user_contact', 'show_score', 'send_user_email', + 'send_admin_email', 'contact_info_location', 'user_name', 'user_comp', 'user_email', 'user_phone', 'admin_email', + 'comment_section', 'question_from_total', 'total_user_tries', 'total_user_tries_text', 'certificate_template', + 'social_media', 'social_media_text', 'pagination', 'pagination_text', 'timer_limit', 'quiz_stye', 'question_numbering', + 'quiz_settings', 'theme_selected', 'last_activity', 'require_log_in', 'require_log_in_text', 'limit_total_entries', + 'limit_total_entries_text', 'scheduled_timeframe', 'scheduled_timeframe_text', 'disable_answer_onselect', 'ajax_show_correct', + 'quiz_views', 'quiz_taken', 'deleted', 'quiz_author_id' + ], + $question_table_name => [ + 'question_id', 'quiz_id', 'question_name', 'answer_array', 'answer_one', 'answer_one_points', 'answer_two', + 'answer_two_points', 'answer_three', 'answer_three_points', 'answer_four', 'answer_four_points', 'answer_five', + 'answer_five_points', 'answer_six', 'answer_six_points', 'correct_answer', 'question_answer_info', 'comments', + 'hints', 'question_order', 'question_type', 'question_type_new', 'question_settings', 'category', 'deleted', + 'deleted_question_bank' + ], + $results_table_name => [ + 'result_id', 'quiz_id', 'quiz_name', 'quiz_system', 'point_score', 'correct_score', 'correct', 'total', 'name', + 'business', 'email', 'phone', 'user', 'user_ip', 'time_taken', 'time_taken_real', 'quiz_results', 'deleted', + 'unique_id', 'form_type', 'page_name', 'page_url' + ], + $audit_table_name => [ + 'trail_id', 'action_user', 'action', 'quiz_id', 'quiz_name', 'form_data', 'time' + ], + $themes_table_name => [ + 'id', 'theme', 'theme_name', 'default_settings', 'theme_active' + ], + $quiz_themes_settings_table_name => [ + 'id', 'theme_id', 'quiz_id', 'quiz_theme_settings', 'active_theme' + ], + $question_terms_table_name => [ + 'id', 'question_id', 'quiz_id', 'term_id', 'taxonomy' + ] + ]; + + // Check all tables + $errors = []; + foreach ($tables as $table_name => $columns) { + $error = $this->qsm_check_table_structure($table_name, $columns); + if ($error) { + $errors[] = $error; + } + } + + if (!empty($errors)) { + foreach ($errors as $error) { + echo esc_html($error) . "
"; + } + } else { + esc_html_e("All tables have the correct structure.", "quiz-master-next"); + update_option('qsm_check_database_structure', 1); + } + } + + /** + * Check if table and columns exist + * + * @since 9.0.6 + * @param string $table_name + * @param array $expected_columns + * @return string|null + */ + public function qsm_check_table_structure($table_name, $expected_columns) { + global $wpdb; + $columns = $wpdb->get_results("SHOW COLUMNS FROM $table_name"); + if (!$columns) { + return esc_html__("Table ", "quiz-master-next") . $table_name . esc_html__(" does not exist.", "quiz-master-next"); + } + $existing_columns = array_column($columns, 'Field'); + $missing_columns = []; + foreach ($expected_columns as $column) { + if (!in_array($column, $existing_columns)) { + $missing_columns[] = $column; + } + } + if (!empty($missing_columns)) { + return esc_html__("Table ", "quiz-master-next") . $table_name . esc_html__(" is missing columns: ", "quiz-master-next") . implode(', ', $missing_columns); + } + return null; + } /** * Failed Database queries diff --git a/php/template-variables.php b/php/template-variables.php index b1c22ce30..a4dc68f27 100644 --- a/php/template-variables.php +++ b/php/template-variables.php @@ -134,7 +134,7 @@ function qsm_variable_single_answer( $content, $mlw_quiz_array ) { $ser_answer = $wpdb->get_row( $wpdb->prepare( "SELECT question_settings FROM {$wpdb->prefix}mlw_questions WHERE question_id = %d", $question_id ), ARRAY_A ); $question_settings = qmn_sanitize_input_data( $ser_answer['question_settings'] ); $answerstr = ""; - if ( isset($answers['user_answer']) ) { + if ( isset($answers['user_answer']) && is_array($answers['user_answer']) ) { if ( 13 === intval( $answers['question_type'] ) ) { $answerstr .= $answers['points']; }elseif ( 12 === intval( $answers['question_type'] ) ) { @@ -510,7 +510,7 @@ function qsm_contact_field_variable( $content, $results_array ) { function qsm_all_contact_fields_variable( $content, $results ) { global $mlwQuizMasterNext; $contact_form = $mlwQuizMasterNext->pluginHelper->get_quiz_setting( 'contact_form' ); - + $return = ''; if ( isset( $results['contact'] ) && ( is_array( $results['contact'] ) || is_object( $results['contact'] ) ) ) { foreach ( $results['contact'] as $results_contact ) { From 48397644bc55929ed333d2831fc05a950ec674ef Mon Sep 17 00:00:00 2001 From: Mohammad Zubair Ali Date: Thu, 27 Jun 2024 16:13:32 +0530 Subject: [PATCH 05/12] fixed phpcs --- mlw_quizmaster2.php | 181 +++++++++++++++++++++++++++++-------- php/template-variables.php | 14 +-- 2 files changed, 150 insertions(+), 45 deletions(-) diff --git a/mlw_quizmaster2.php b/mlw_quizmaster2.php index 616d2c4c6..5108403eb 100644 --- a/mlw_quizmaster2.php +++ b/mlw_quizmaster2.php @@ -804,55 +804,160 @@ public function qsm_check_database_structure() { // List of tables and their columns $tables = [ - $quiz_table_name => [ - 'quiz_id', 'quiz_name', 'message_before', 'message_after', 'message_comment', 'message_end_template', - 'user_email_template', 'admin_email_template', 'submit_button_text', 'name_field_text', 'business_field_text', - 'email_field_text', 'phone_field_text', 'comment_field_text', 'email_from_text', 'question_answer_template', - 'leaderboard_template', 'quiz_system', 'randomness_order', 'loggedin_user_contact', 'show_score', 'send_user_email', - 'send_admin_email', 'contact_info_location', 'user_name', 'user_comp', 'user_email', 'user_phone', 'admin_email', - 'comment_section', 'question_from_total', 'total_user_tries', 'total_user_tries_text', 'certificate_template', - 'social_media', 'social_media_text', 'pagination', 'pagination_text', 'timer_limit', 'quiz_stye', 'question_numbering', - 'quiz_settings', 'theme_selected', 'last_activity', 'require_log_in', 'require_log_in_text', 'limit_total_entries', - 'limit_total_entries_text', 'scheduled_timeframe', 'scheduled_timeframe_text', 'disable_answer_onselect', 'ajax_show_correct', - 'quiz_views', 'quiz_taken', 'deleted', 'quiz_author_id' + $quiz_table_name => [ + 'quiz_id', + 'quiz_name', + 'message_before', + 'message_after', + 'message_comment', + 'message_end_template', + 'user_email_template', + 'admin_email_template', + 'submit_button_text', + 'name_field_text', + 'business_field_text', + 'email_field_text', + 'phone_field_text', + 'comment_field_text', + 'email_from_text', + 'question_answer_template', + 'leaderboard_template', + 'quiz_system', + 'randomness_order', + 'loggedin_user_contact', + 'show_score', + 'send_user_email', + 'send_admin_email', + 'contact_info_location', + 'user_name', + 'user_comp', + 'user_email', + 'user_phone', + 'admin_email', + 'comment_section', + 'question_from_total', + 'total_user_tries', + 'total_user_tries_text', + 'certificate_template', + 'social_media', + 'social_media_text', + 'pagination', + 'pagination_text', + 'timer_limit', + 'quiz_stye', + 'question_numbering', + 'quiz_settings', + 'theme_selected', + 'last_activity', + 'require_log_in', + 'require_log_in_text', + 'limit_total_entries', + 'limit_total_entries_text', + 'scheduled_timeframe', + 'scheduled_timeframe_text', + 'disable_answer_onselect', + 'ajax_show_correct', + 'quiz_views', + 'quiz_taken', + 'deleted', + 'quiz_author_id', ], - $question_table_name => [ - 'question_id', 'quiz_id', 'question_name', 'answer_array', 'answer_one', 'answer_one_points', 'answer_two', - 'answer_two_points', 'answer_three', 'answer_three_points', 'answer_four', 'answer_four_points', 'answer_five', - 'answer_five_points', 'answer_six', 'answer_six_points', 'correct_answer', 'question_answer_info', 'comments', - 'hints', 'question_order', 'question_type', 'question_type_new', 'question_settings', 'category', 'deleted', - 'deleted_question_bank' + $question_table_name => [ + 'question_id', + 'quiz_id', + 'question_name', + 'answer_array', + 'answer_one', + 'answer_one_points', + 'answer_two', + 'answer_two_points', + 'answer_three', + 'answer_three_points', + 'answer_four', + 'answer_four_points', + 'answer_five', + 'answer_five_points', + 'answer_six', + 'answer_six_points', + 'correct_answer', + 'question_answer_info', + 'comments', + 'hints', + 'question_order', + 'question_type', + 'question_type_new', + 'question_settings', + 'category', + 'deleted', + 'deleted_question_bank', ], - $results_table_name => [ - 'result_id', 'quiz_id', 'quiz_name', 'quiz_system', 'point_score', 'correct_score', 'correct', 'total', 'name', - 'business', 'email', 'phone', 'user', 'user_ip', 'time_taken', 'time_taken_real', 'quiz_results', 'deleted', - 'unique_id', 'form_type', 'page_name', 'page_url' + $results_table_name => [ + 'result_id', + 'quiz_id', + 'quiz_name', + 'quiz_system', + 'point_score', + 'correct_score', + 'correct', + 'total', + 'name', + 'business', + 'email', + 'phone', + 'user', + 'user_ip', + 'time_taken', + 'time_taken_real', + 'quiz_results', + 'deleted', + 'unique_id', + 'form_type', + 'page_name', + 'page_url', ], - $audit_table_name => [ - 'trail_id', 'action_user', 'action', 'quiz_id', 'quiz_name', 'form_data', 'time' + $audit_table_name => [ + 'trail_id', + 'action_user', + 'action', + 'quiz_id', + 'quiz_name', + 'form_data', + 'time', ], - $themes_table_name => [ - 'id', 'theme', 'theme_name', 'default_settings', 'theme_active' + $themes_table_name => [ + 'id', + 'theme', + 'theme_name', + 'default_settings', + 'theme_active', ], $quiz_themes_settings_table_name => [ - 'id', 'theme_id', 'quiz_id', 'quiz_theme_settings', 'active_theme' + 'id', + 'theme_id', + 'quiz_id', + 'quiz_theme_settings', + 'active_theme', + ], + $question_terms_table_name => [ + 'id', + 'question_id', + 'quiz_id', + 'term_id', + 'taxonomy', ], - $question_terms_table_name => [ - 'id', 'question_id', 'quiz_id', 'term_id', 'taxonomy' - ] ]; // Check all tables $errors = []; - foreach ($tables as $table_name => $columns) { + foreach ( $tables as $table_name => $columns ) { $error = $this->qsm_check_table_structure($table_name, $columns); - if ($error) { + if ( $error ) { $errors[] = $error; } } - if (!empty($errors)) { - foreach ($errors as $error) { + if ( ! empty($errors) ) { + foreach ( $errors as $error ) { echo esc_html($error) . "
"; } } else { @@ -869,20 +974,20 @@ public function qsm_check_database_structure() { * @param array $expected_columns * @return string|null */ - public function qsm_check_table_structure($table_name, $expected_columns) { + public function qsm_check_table_structure( $table_name, $expected_columns ) { global $wpdb; $columns = $wpdb->get_results("SHOW COLUMNS FROM $table_name"); - if (!$columns) { + if ( ! $columns ) { return esc_html__("Table ", "quiz-master-next") . $table_name . esc_html__(" does not exist.", "quiz-master-next"); } $existing_columns = array_column($columns, 'Field'); $missing_columns = []; - foreach ($expected_columns as $column) { - if (!in_array($column, $existing_columns)) { + foreach ( $expected_columns as $column ) { + if ( ! in_array($column, $existing_columns, true) ) { $missing_columns[] = $column; } } - if (!empty($missing_columns)) { + if ( ! empty($missing_columns) ) { return esc_html__("Table ", "quiz-master-next") . $table_name . esc_html__(" is missing columns: ", "quiz-master-next") . implode(', ', $missing_columns); } return null; diff --git a/php/template-variables.php b/php/template-variables.php index a4dc68f27..ae207d466 100644 --- a/php/template-variables.php +++ b/php/template-variables.php @@ -134,7 +134,7 @@ function qsm_variable_single_answer( $content, $mlw_quiz_array ) { $ser_answer = $wpdb->get_row( $wpdb->prepare( "SELECT question_settings FROM {$wpdb->prefix}mlw_questions WHERE question_id = %d", $question_id ), ARRAY_A ); $question_settings = qmn_sanitize_input_data( $ser_answer['question_settings'] ); $answerstr = ""; - if ( isset($answers['user_answer']) && is_array($answers['user_answer']) ) { + if ( isset( $answers['user_answer'] ) && is_array( $answers['user_answer'] ) ) { if ( 13 === intval( $answers['question_type'] ) ) { $answerstr .= $answers['points']; }elseif ( 12 === intval( $answers['question_type'] ) ) { @@ -515,10 +515,10 @@ function qsm_all_contact_fields_variable( $content, $results ) { if ( isset( $results['contact'] ) && ( is_array( $results['contact'] ) || is_object( $results['contact'] ) ) ) { foreach ( $results['contact'] as $results_contact ) { $options = qsm_get_options_of_contact_fields($contact_form, $results_contact['label'], $results_contact['type'] ); - $isRadioOrSelect = in_array($results_contact['type'], ['radio', 'select']); - $hasOptions = !empty(trim($options)); + $isRadioOrSelect = in_array($results_contact['type'], [ 'radio', 'select' ]); + $hasOptions = ! empty(trim($options)); - if (($isRadioOrSelect && $hasOptions) || !$isRadioOrSelect) { + if ( ($isRadioOrSelect && $hasOptions) || ! $isRadioOrSelect ) { $return .= $results_contact['label'] . ': ' . $results_contact['value'] . '
'; } } @@ -526,9 +526,9 @@ function qsm_all_contact_fields_variable( $content, $results ) { $content = str_replace( '%CONTACT_ALL%', $return, $content ); return $content; } -function qsm_get_options_of_contact_fields($data, $label, $type) { - foreach ($data as $item) { - if ($item['label'] === $label && $item['type'] === $type) { +function qsm_get_options_of_contact_fields( $data, $label, $type ) { + foreach ( $data as $item ) { + if ( $item['label'] === $label && $item['type'] === $type ) { return $item['options']; } } From 1a36589065ed99bfd7a10b80ebce5f99394da963 Mon Sep 17 00:00:00 2001 From: Mohammad Zubair Ali Date: Fri, 28 Jun 2024 14:25:02 +0530 Subject: [PATCH 06/12] show database table structure message --- mlw_quizmaster2.php | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/mlw_quizmaster2.php b/mlw_quizmaster2.php index 5108403eb..e05014e5a 100644 --- a/mlw_quizmaster2.php +++ b/mlw_quizmaster2.php @@ -348,6 +348,9 @@ private function add_hooks() { add_action( 'admin_menu', array( $this, 'setup_admin_menu' ) ); add_action( 'admin_head', array( $this, 'admin_head' ), 900 ); add_action( 'init', array( $this, 'register_quiz_post_types' ) ); + if ( empty( get_option('qsm_check_database_structure') ) || ! empty($_GET['qsm_check_database_structure']) ) { + add_action( 'admin_init', array( $this, 'qsm_check_database_structure' ) ); + } add_filter( 'parent_file', array( &$this, 'parent_file' ), 9999, 1 ); add_action( 'plugins_loaded', array( &$this, 'qsm_load_textdomain' ) ); add_action( 'admin_enqueue_scripts', array( $this, 'qsm_admin_scripts_style' ), 10 ); @@ -946,7 +949,7 @@ public function qsm_check_database_structure() { 'taxonomy', ], ]; - + $response['message'] = ""; // Check all tables $errors = []; foreach ( $tables as $table_name => $columns ) { @@ -955,15 +958,23 @@ public function qsm_check_database_structure() { $errors[] = $error; } } - if ( ! empty($errors) ) { + $response['message'] .= esc_html__("Incorrect database structure!", "quiz-master-next") . "
"; foreach ( $errors as $error ) { - echo esc_html($error) . "
"; + $response['status'] = "error"; + $response['message'] .= esc_html($error) . "
"; } + update_option('qsm_check_database_structure', "error"); } else { - esc_html_e("All tables have the correct structure.", "quiz-master-next"); - update_option('qsm_check_database_structure', 1); + update_option('qsm_check_database_structure', "success"); + $response['status'] = "success"; + $response['message'] = esc_html__("All tables have the correct structure.", "quiz-master-next"); } + if ( ! empty( $_GET['qsm_check_database_structure'] ) ) { + $this->alertManager->newAlert( $response['message'], $response['status'] ); + }else { + return $response; + } } /** From e5a1b043785a199feaf53910188f83a60423b19a Mon Sep 17 00:00:00 2001 From: randhirexpresstech Date: Mon, 1 Jul 2024 09:54:09 +0530 Subject: [PATCH 07/12] adjust add result function for import feature --- php/classes/class-qmn-quiz-manager.php | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/php/classes/class-qmn-quiz-manager.php b/php/classes/class-qmn-quiz-manager.php index 97817780d..25f4c85bc 100644 --- a/php/classes/class-qmn-quiz-manager.php +++ b/php/classes/class-qmn-quiz-manager.php @@ -1870,7 +1870,7 @@ public function qsm_get_quiz_to_reload() { * * @return boolean results added or not */ - private function add_quiz_results( $data ) { + public function add_quiz_results( $data ) { global $wpdb; if ( empty( $wpdb ) || empty( $data['qmn_array_for_variables'] ) || empty( $data['results_array'] ) || empty( $data['unique_id'] ) || ! isset( $data['http_referer'] ) || ! isset( $data['form_type'] ) ) { return false; @@ -1883,6 +1883,9 @@ private function add_quiz_results( $data ) { $wpdb->suppress_errors(); try { + if ( empty( $data['page_name'] ) ) { + $data['page_name'] = url_to_postid( $data['http_referer'] ) ? get_the_title( url_to_postid( $data['http_referer'] ) ) : ''; + } $res = $wpdb->insert( $table_name, array( @@ -1902,11 +1905,11 @@ private function add_quiz_results( $data ) { 'time_taken' => $data['qmn_array_for_variables']['time_taken'], 'time_taken_real' => gmdate( 'Y-m-d H:i:s', strtotime( $data['qmn_array_for_variables']['time_taken'] ) ), 'quiz_results' => maybe_serialize( $data['results_array'] ), - 'deleted' => 0, + 'deleted' => ( isset( $data['deleted'] ) && 1 === intval( $data['deleted'] ) ) ? 1 : 0, 'unique_id' => $data['unique_id'], 'form_type' => $data['form_type'], 'page_url' => $data['http_referer'], - 'page_name' => url_to_postid( $data['http_referer'] ) ? get_the_title( url_to_postid( $data['http_referer'] ) ) : '', + 'page_name' => sanitize_text_field( $data['page_name'] ), ), array( '%d', From 32fe308bdb92b6a860d3bf173d2b7b307bf92e54 Mon Sep 17 00:00:00 2001 From: PranavAwasthi Date: Thu, 27 Jun 2024 12:28:18 +0530 Subject: [PATCH 08/12] added case sensitive option to text question types --- php/admin/options-page-questions-tab.php | 2 +- php/classes/question-types/class-question-review-text.php | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/php/admin/options-page-questions-tab.php b/php/admin/options-page-questions-tab.php index 9d318afb3..ff2789454 100644 --- a/php/admin/options-page-questions-tab.php +++ b/php/admin/options-page-questions-tab.php @@ -433,7 +433,7 @@ class="save-page-button button button-primary"> __( 'Yes', 'quiz-master-next' ), ), 'default' => '0', - 'show' => '14' . $show_case_sensitive, + 'show' => '3, 5, 14' . $show_case_sensitive, ), 'limit_text' => array( 'heading' => __( 'Limit Text', 'quiz-master-next' ), diff --git a/php/classes/question-types/class-question-review-text.php b/php/classes/question-types/class-question-review-text.php index 79e02cf0a..18a2c9380 100644 --- a/php/classes/question-types/class-question-review-text.php +++ b/php/classes/question-types/class-question-review-text.php @@ -18,8 +18,14 @@ public function set_user_answer() { } public function set_answer_status() { + global $mlwQuizMasterNext; + $case_sensitive = $mlwQuizMasterNext->pluginHelper->get_question_setting( $this->question_id, 'case_sensitive' ); $user_answer_value = $this->user_answer['input']; - $answer_key = array_search( $this->prepare_for_string_matching( $user_answer_value ), array_map( array( $this, 'prepare_for_string_matching' ), $this->correct_answer ), true ); + if ( 1 === intval($case_sensitive ) ) { + $answer_key = array_search( $user_answer_value, $this->correct_answer, true ); + }else { + $answer_key = array_search( $this->prepare_for_string_matching( $user_answer_value ), array_map( array( $this, 'prepare_for_string_matching' ), $this->correct_answer ), true ); + } if ( false !== $answer_key ) { $this->answer_status = 'correct'; $this->points += $this->answer_array[ $answer_key ][1]; From 1c0d1801259fd96e614228fd4fc2e263cb7ae36d Mon Sep 17 00:00:00 2001 From: PranavAwasthi Date: Wed, 26 Jun 2024 15:42:26 +0530 Subject: [PATCH 09/12] Fixed category's parent issue --- php/classes/class-qsm-questions.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php/classes/class-qsm-questions.php b/php/classes/class-qsm-questions.php index cd7d7888c..8d54db908 100644 --- a/php/classes/class-qsm-questions.php +++ b/php/classes/class-qsm-questions.php @@ -487,7 +487,7 @@ public static function get_question_categories_from_term_ids( $term_ids ) { $categories_names[ $tax->term_id ] = $tax->name; $taxs[ $tax->parent ][] = $tax; } - $categories_tree = self::create_terms_tree( $taxs, $taxs[0] ); + $categories_tree = self::create_terms_tree( $taxs, isset( $taxs[0] ) ? $taxs[0] : reset( $taxs ) ); } $categories = array( 'list' => $categories_names, @@ -527,7 +527,7 @@ public static function get_question_categories( $question_id = 0 ) { $categories_names[ $tax->term_id ] = $tax->name; $taxs[ $tax->parent ][] = $tax; } - $categories_tree = self::create_terms_tree( $taxs, $taxs[0] ); + $categories_tree = self::create_terms_tree( $taxs, isset( $taxs[0] ) ? $taxs[0] : reset( $taxs ) ); } } From 95f69e1b00e8c497fc07a66af9262c35cacc6359 Mon Sep 17 00:00:00 2001 From: randhirexpresstech Date: Mon, 1 Jul 2024 09:54:09 +0530 Subject: [PATCH 10/12] adjust add result function for import feature --- php/classes/class-qmn-quiz-manager.php | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/php/classes/class-qmn-quiz-manager.php b/php/classes/class-qmn-quiz-manager.php index 97817780d..25f4c85bc 100644 --- a/php/classes/class-qmn-quiz-manager.php +++ b/php/classes/class-qmn-quiz-manager.php @@ -1870,7 +1870,7 @@ public function qsm_get_quiz_to_reload() { * * @return boolean results added or not */ - private function add_quiz_results( $data ) { + public function add_quiz_results( $data ) { global $wpdb; if ( empty( $wpdb ) || empty( $data['qmn_array_for_variables'] ) || empty( $data['results_array'] ) || empty( $data['unique_id'] ) || ! isset( $data['http_referer'] ) || ! isset( $data['form_type'] ) ) { return false; @@ -1883,6 +1883,9 @@ private function add_quiz_results( $data ) { $wpdb->suppress_errors(); try { + if ( empty( $data['page_name'] ) ) { + $data['page_name'] = url_to_postid( $data['http_referer'] ) ? get_the_title( url_to_postid( $data['http_referer'] ) ) : ''; + } $res = $wpdb->insert( $table_name, array( @@ -1902,11 +1905,11 @@ private function add_quiz_results( $data ) { 'time_taken' => $data['qmn_array_for_variables']['time_taken'], 'time_taken_real' => gmdate( 'Y-m-d H:i:s', strtotime( $data['qmn_array_for_variables']['time_taken'] ) ), 'quiz_results' => maybe_serialize( $data['results_array'] ), - 'deleted' => 0, + 'deleted' => ( isset( $data['deleted'] ) && 1 === intval( $data['deleted'] ) ) ? 1 : 0, 'unique_id' => $data['unique_id'], 'form_type' => $data['form_type'], 'page_url' => $data['http_referer'], - 'page_name' => url_to_postid( $data['http_referer'] ) ? get_the_title( url_to_postid( $data['http_referer'] ) ) : '', + 'page_name' => sanitize_text_field( $data['page_name'] ), ), array( '%d', From d66fd5383611be666c455437a37bb0398d16bf4a Mon Sep 17 00:00:00 2001 From: PranavAwasthi Date: Wed, 10 Jul 2024 12:20:26 +0530 Subject: [PATCH 11/12] Fixed vulnerability in text tab --- php/classes/class-qsm-fields.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/classes/class-qsm-fields.php b/php/classes/class-qsm-fields.php index e8f4c6061..f085aad69 100644 --- a/php/classes/class-qsm-fields.php +++ b/php/classes/class-qsm-fields.php @@ -31,7 +31,7 @@ public static function generate_section( $fields, $section ) { if ( ( isset( $_POST[ $field["id"] ] ) && 'multiple_fields' !== $field["type"] ) || 'selectinput' == $field["type"] ) { switch ( $field["type"] ) { case 'text': - $sanitized_value = sanitize_text_field( wp_unslash( $_POST[ $field["id"] ] ) ); + $sanitized_value = esc_html( sanitize_text_field( wp_unslash( $_POST[ $field["id"] ] ) ) ); break; case 'url': From ae65951890e045cec952e8797f16df229ce5bca3 Mon Sep 17 00:00:00 2001 From: Mohammad Zubair Ali Date: Thu, 11 Jul 2024 10:55:10 +0530 Subject: [PATCH 12/12] Update changelog 9.1.0 --- mlw_quizmaster2.php | 8 +- php/template-variables.php | 8 +- readme.txt | 202 ++++++++++++++++++++----------------- 3 files changed, 120 insertions(+), 98 deletions(-) diff --git a/mlw_quizmaster2.php b/mlw_quizmaster2.php index e05014e5a..48525e282 100644 --- a/mlw_quizmaster2.php +++ b/mlw_quizmaster2.php @@ -2,7 +2,7 @@ /** * Plugin Name: Quiz And Survey Master * Description: Easily and quickly add quizzes and surveys to your website. - * Version: 9.0.5 + * Version: 9.1.0 * Author: ExpressTech * Author URI: https://quizandsurveymaster.com/ * Plugin URI: https://expresstech.io/ @@ -43,7 +43,7 @@ class MLWQuizMasterNext { * @var string * @since 4.0.0 */ - public $version = '9.0.5'; + public $version = '9.1.0'; /** * QSM Alert Manager Object @@ -790,7 +790,7 @@ public function admin_failed_submission_page() { /** * Check database structure * - * @since 9.0.6 + * @since 9.1.0 * @return void */ public function qsm_check_database_structure() { @@ -980,7 +980,7 @@ public function qsm_check_database_structure() { /** * Check if table and columns exist * - * @since 9.0.6 + * @since 9.1.0 * @param string $table_name * @param array $expected_columns * @return string|null diff --git a/php/template-variables.php b/php/template-variables.php index ae207d466..5116b077d 100644 --- a/php/template-variables.php +++ b/php/template-variables.php @@ -515,7 +515,7 @@ function qsm_all_contact_fields_variable( $content, $results ) { if ( isset( $results['contact'] ) && ( is_array( $results['contact'] ) || is_object( $results['contact'] ) ) ) { foreach ( $results['contact'] as $results_contact ) { $options = qsm_get_options_of_contact_fields($contact_form, $results_contact['label'], $results_contact['type'] ); - $isRadioOrSelect = in_array($results_contact['type'], [ 'radio', 'select' ]); + $isRadioOrSelect = in_array($results_contact['type'], [ 'radio', 'select' ], true); $hasOptions = ! empty(trim($options)); if ( ($isRadioOrSelect && $hasOptions) || ! $isRadioOrSelect ) { @@ -528,9 +528,9 @@ function qsm_all_contact_fields_variable( $content, $results ) { } function qsm_get_options_of_contact_fields( $data, $label, $type ) { foreach ( $data as $item ) { - if ( $item['label'] === $label && $item['type'] === $type ) { - return $item['options']; - } + if ( $item['label'] === $label && $item['type'] === $type ) { + return $item['options']; + } } return null; // Option not found } diff --git a/readme.txt b/readme.txt index e8aaf4971..2c18d338a 100644 --- a/readme.txt +++ b/readme.txt @@ -4,142 +4,158 @@ Tags: quiz, survey, test, exam, online assessment Requires at least: 4.9 Tested up to: 6.5 Requires PHP: 5.4 -Stable tag: 9.0.5 +Stable tag: 9.1.0 License: GPLv2 License URI: http://www.gnu.org/licenses/gpl-2.0.html -Easily create exams, generate leads, surveys and any type of quiz with our popular WordPress Quiz Plugin. Custom flows, emails and create leaderboard +Easily create exams, generate leads, surveys and any type of quiz with our popular WordPress Quiz Plugin. Customize personalized results, emails, and create a leaderboard to enhance user engagement == Description == -Try Demo ➡️ [Get a personal sandbox demo with QSM](https://instawp.io/plugins/quiz-master-next) +**Quiz and Survey Master** is the easiest quiz and survey maker plugin for creating quizzes, surveys, and forms on your WordPress website. Create everything from fun trivia quizzes to in-depth customer satisfaction assessments, using a user-friendly drag-and-drop interface. Go beyond basic questions with multimedia support for richer content, analyze results to gain valuable insights, and even integrate with email marketing services to capture leads. Quiz & Survey Master is a powerful tool to increase user engagement, gather valuable data, and build a stronger connection with your audience. -= Demoes! = -* [Sample Quiz](https://quizandsurveymaster.com/quiz/sample-quiz/?utm_source=readme&utm_medium=plugin&utm_content=sample-quiz&utm_campaign=qsm_plugin) -* [Sample Survey](https://quizandsurveymaster.com/quiz/sample-survey/?utm_source=readme&utm_medium=plugin&utm_content=sample-survey&utm_campaign=qsm_plugin) -* [Personality Quiz](https://quizandsurveymaster.com/quiz/personality-quiz/?utm_source=readme&utm_medium=plugin&utm_campaign=qsm_plugin) -* [Quiz with Leaderboard](https://demo.quizandsurveymaster.com/advanced-leaderboard-demo/?utm_source=readme&utm_medium=plugin&utm_campaign=qsm_plugin) -* [Popup Quiz](https://quizandsurveymaster.com/simple-popup-demo/?utm_source=readme&utm_medium=plugin&utm_campaign=qsm_plugin) -* [Flashcards](https://demo.quizandsurveymaster.com/flash-card-demo/?utm_source=readme&utm_medium=plugin&utm_campaign=qsm_plugin) -* [Paid Quiz](https://demo.quizandsurveymaster.com/payment-integration-demo/?utm_source=readme&utm_medium=plugin&utm_campaign=qsm_plugin) +**Try Demo ➡️ [Get a personal sandbox demo with QSM](https://instawp.io/plugins/quiz-master-next)** -= Themes = -* [Theme Breeze](https://themes.quizandsurveymaster.com/breeze-qsm-theme-demo/?utm_source=readme&utm_medium=plugin&utm_campaign=qsm_plugin) -* [Theme Fragrance](https://themes.quizandsurveymaster.com/fragrance-qsm-theme-demo/?utm_source=readme&utm_medium=plugin&utm_campaign=qsm_plugin) -* [Theme Ivory](https://themes.quizandsurveymaster.com/ivory-qsm-theme-demo/?utm_source=readme&utm_medium=plugin&utm_campaign=qsm_plugin) -* [Theme Pool](https://themes.quizandsurveymaster.com/pool-qsm-theme-demo/?utm_source=readme&utm_medium=plugin&utm_campaign=qsm_plugin) +### CREATE UNLIMITED QUIZZES AND QUESTIONS -= Easily Create Quiz or Surveys For Your Users = -Quiz and Survey Master is the easiest [WordPress Quiz Plugin](https://quizandsurveymaster.com/) which can be used to create engaging content to drive traffic and increase user engagement. Everything from viral quiz, trivia quiz, customer satisfaction surveys to employee surveys. This plugin is the ultimate marketing tool for your website. +Create without limits with QSM by crafting unlimited quizzes with endless questions in diverse formats. Utilize the built-in text editor to format text and incorporate images, audio, and video. Build forms, quizzes, and surveys that resonate with your audience, creating a fulfilling learning and engagement experience. -[youtube https://www.youtube.com/watch?v=DyiCCNnDpHk] +### DIVERSE RANGE OF QUESTIONS -= Customize Text = -You can customize anything your users will see and engage with. Everything from the text blocks throughout the quiz or survey to the submit button. You can even use "template variables" to generate personalized text for your users. +Create quizzes, forms, or surveys with a variety of question types tailored to your specific goals: +- **Multiple Choice**: Choose one correct answer option. +- **Multiple Response**: Select multiple correct answer options. +- **Dropdown**: Pick one correct answer from the dropdown menu options. +- **Short Answer**: Provide concise written responses. +- **Paragraph**: Write longer, detailed answers. +- **Fill in the Blank**: Complete sentences with the correct missing words. +- **Date**: Select a specific calendar date. +- **File Upload**: Attach images, PDFs, and documents. +- **Number**: Enter answers in numerical format. +- **Captcha**: Verify identity with anti-bot check. +- **Polar**: Answer by choosing a spot on the slider scale. +- **Opt-in**: Use the checkbox selection to give permission/agree to a text. -= Question Types = -You can have **multiple choice** (radio buttons), **true and false**, **open answer** question, **drop down**, **multiple response** (checkboxes), **fill in the blank**, **number**, **captcha**, **polar** (slider) and **accept**. We release more questions types with every major release. +**Advanced Question Types** available in the pro plan: +- **Matching Pairs**: Drag and drop answers vertically to match with the correct option. +- **Radio Grid**: Choose one answer per row from a grid of options. +- **Checkbox Grid**: Select multiple answers per row from a grid of options. -= Customize Results Based on Score = -Using our quiz builder plugin, you can customize the results page based on the user's score. +### CREATE QUIZ WITH BLOCK EDITOR -= Emails After Quiz = -After the user takes a quiz or survey, you can have the plugin email you and the user with results. This too can be customized with your own text. +Block Editors in WordPress simplify content creation and customization through intuitive drag-and-drop functionality. QSM incorporates its own block editor, making it the easiest and most convenient way to create quizzes in WordPress, enhancing user experience and workflow efficiency. -= Flexibility = -Your quiz or survey can be graded with an incorrect/correct system or a points-based system. Or not at all. You ask for contact information at the beginning or the end and you decide which contact fields are required. You can decide to use all the questions or only a select few chosen at random. You can also set the number of questions per page or have all the questions on one page. +### GAIN BUSINESS INSIGHTS WITH SURVEYS -= Categories = -You can assign categories to your questions using our quiz maker plugin. You can then show the user their score in a **particular** category or an average score of the categories. +With the QSM plugin, effortlessly create detailed market research surveys and share them on social platforms to gather valuable consumer information. Store the data in a database or export it for analysis using QSM's advanced features like the export add-on and reporting and analysis add-on. Gain valuable insights from efficient data collection and analysis, enabling you to make informed business decisions and share the findings with your audience. -= Countdown Timer = -Add countdown timer to your quizzes and effectively create skills assessment or online exams on your website. +### FULLY CUSTOMIZABLE -= Lead Generation = -You can integrate Mailchimp, Activecampaign, Zapier, Campaign Monitor, Get Response to your quiz or surveys in order to create drip email campaigns and reachout to your audience. Checkout our [integrations](https://quizandsurveymaster.com/downloads/category/integrations/). +Customize every aspect of your quizzes and surveys: +- **Custom Style CSS**: Personalize the look and feel of your quizzes and surveys to match your brand and style perfectly. +- **Custom text blocks**: Add custom text to various parts of quizzes and surveys for better communication and engagement. +- **Button Labels**: Tailor button labels such as start, submit, or retake quiz to improve user experience and align with your quiz’s goal. +- **Template Variables**: Use variables to generate custom messages for users and humanize their quiz experience. -= Other Useful Features = +### DISPLAY SCORE-BASED CUSTOM RESULTS -* Allow the user to share the results on *social networks* -* Show all questions on one page or have only a set number of questions per page -* Require user to be logged in -* Schedule when the quiz or survey should be active -* **Require** certain or all questions to be answered -* Limit amount of total entries to quiz or survey -* Can set amount of tries a user has to take the quiz or survey -* Can enable **comment boxes** for each question and/or comment section at the end of the quiz or survey -* Can enable **hints** for questions -* Can show user why the answer is the correct answer -* Questions can be in predetermined order or random -* Keep track how long a user takes on the quiz or survey -* Able to set up time limits on the quiz or survey -* Create and display math formulas -* Compatible with [WPML](https://wpml.org/) and its extensions -* And **Much** More... +Create customized results based on quiz scores. Tailor multiple result pages to different score ranges, offering a unique and engaging experience for each participant. -= QSM Addons = -Quiz And Survey Master is fully functional and is packed with tons of features that will meet the needs of most, we do offer various extra features including: +### CUSTOM EMAIL TEMPLATES -**Free Add-ons** +Keep your users in the loop with personalized emails about their progress and results. Customize messages for both users and admins with tailored email templates based on quiz outcomes. Build user loyalty with consistent communication and timely notifications. -* [Certificates](https://quizandsurveymaster.com/downloads/certificate/?utm_source=readme&utm_medium=plugin&utm_campaign=qsm_plugin&utm_content=certificate) -* [Leaderboards](https://quizandsurveymaster.com/downloads/leaderboards/?utm_source=readme&utm_medium=plugin&utm_campaign=qsm_plugin&utm_content=leaderboads) +### FLEXIBLE GRADING SYSTEMS -**Premium Add-ons** +Customize how quizzes and assessments are graded with options for correct/incorrect or points-based systems, or use both. Create a competitive atmosphere for participants, motivating them to excel and engage actively in quizzes and exams. -* [Reporting & Analysis](https://quizandsurveymaster.com/downloads/results-analysis/?utm_source=readme&utm_medium=plugin&utm_content=reporting-analysis&utm_campaign=qsm_plugin) -* [Export Results](https://quizandsurveymaster.com/downloads/export-results/?utm_source=readme&utm_medium=plugin&utm_content=export-results&utm_campaign=qsm_plugin) -* [Logic](https://quizandsurveymaster.com/downloads/logic/?utm_source=readme&utm_medium=plugin&utm_content=logic&utm_campaign=qsm_plugin) -* [User Dashboard](https://quizandsurveymaster.com/downloads/user-dashboard/?utm_source=readme&utm_medium=plugin&utm_content=user-dashboard&utm_campaign=qsm_plugin) -* [URL Parameters](https://quizandsurveymaster.com/downloads/url-parameters/?utm_campaign=qsm_plugin&utm_medium=plugin&utm_source=readme&utm_content=url-parameters) -* [Google Analytics Tracking](https://quizandsurveymaster.com/downloads/google-analytics-tracking/?utm_campaign=qsm_plugin&utm_medium=plugin&utm_source=readme) -* [Landing Page](https://quizandsurveymaster.com/downloads/landing-page/?utm_source=readme&utm_medium=plugin&utm_content=landing-page&utm_campaign=qsm_plugin) -* [MailChimp Integration](https://quizandsurveymaster.com/downloads/mailchimp-integration/?utm_source=readme&utm_medium=plugin&utm_content=mailchimp-integration&utm_campaign=qsm_plugin) -* And **many** more available in our [Quiz And Survey Master Addon Store](https://quizandsurveymaster.com/addons/?utm_source=readme&utm_medium=plugin&utm_content=all-addons&utm_campaign=qsm_plugin) +### ASSIGN CATEGORIES TO QUESTIONS -= Reachout to us = +Organize your questions by assigning parent and sub-categories. Create category-specific results for participants based on scores they achieved within each category or average scores of the categories. -* You can contact our pro support via our [Contact Form](https://quizandsurveymaster.com/contact-support/) or use the WordPress form for free plugin support. We are equally active on both places. -* Join our [official FB group](https://www.facebook.com/groups/516958552587745). -* Quiz And Survey Master on [GitHub](https://github.com/QuizandSurveyMaster/quiz_master_next/)! +### GENERATE LEADS WITH BUILT-IN CONTACT FORM -🌐Our themes and plugins +Expand your customer base and nurture leads effectively with QSM’s in-built contact forms. Easily collect emails and smoothly integrate with top marketing tools like Mailchimp, ActiveCampaign, Zapier, Campaign Monitor, and GetResponse to drive targeted marketing campaigns. -If you like this plugin, consider exploring our other themes and plugins: +### OTHER USEFUL FEATURES +- Set countdown timer +- Schedule active date and timeframe for quizzes/surveys +- Set Multi-Page surveys and quizzes with a limited number of questions per page +- Enable social sharing of quiz/survey results +- Require user login for privacy and access restrictions +- Personalized quiz experience with randomized questions, answers, or both +- Import questions from the Question Bank across quizzes and surveys. +- Set a limit for incorrect answers that automatically ends the quiz. +- Limit the number of total entries to quiz or survey +- Set the number of user attempts to complete the form +- Display the welcome quiz page with animation +- Enable comment boxes for each question +- Enable hints for questions to assist participants. +- Create math formulas in questions, using TeX and LaTeX notation. +- Compatible with [WPML](https://wpml.org/) and its extensions +- And Much More… -🧱 [Gutena](https://wordpress.org/themes/gutena/) - Block Based Theme for WordPress includes over 50 free block patterns with new patterns added every week. +### ELEVATE YOUR QUIZZES AND SURVEYS WITH QSM PRO -☰ [Responsive Menu](https://wordpress.org/plugins/responsive-menu/) - Best WordPress Menu Builder Plugin to create awesome and interactive mobile & desktop menus for WordPress websites. +Advance your quiz and survey experiences with QSM Pro’s comprehensive toolkit. Access a wide range of professional addons, themes, and integration with tools to maximize user engagement. -📙 [Projectopia](https://wordpress.org/plugins/projectopia-core/) - Project Management & Invoicing plugin for WordPress. Generate invoices, send quotes, generate leads, manage clients, provide support - all inside your WordPress website. +**QSM Pro’s features include:** -📅 [Booking Ultra](https://wordpress.org/plugins/booking-ultra-pro/) - Appointment Booking plugin for WordPress - Show a quick form to accept bookings for your services with pre-set booking slots. Ideal for salons, medical professionals, lawyers, consultants, etc. +**QSM Premium Addons** +- [Export and Import](https://quizandsurveymaster.com/downloads/export-import/) +- [Reporting and Analysis](https://quizandsurveymaster.com/downloads/results-analysis/) +- [Advanced Assessment](https://quizandsurveymaster.com/downloads/advanced-assessment/) +- [Quiz Navigator](https://quizandsurveymaster.com/downloads/quiz-navigator/) +- [Quiz Proctor](https://quizandsurveymaster.com/downloads/quiz-proctor/) +- [Advanced Question Types](https://quizandsurveymaster.com/downloads/advanced-question-types/) +- [Google Sheet Connector](https://quizandsurveymaster.com/downloads/sync-with-google-sheets/) +- [Logic](https://quizandsurveymaster.com/downloads/logic/) +- [User Dashboard](https://quizandsurveymaster.com/downloads/user-dashboard/) +- [MailChimp Integration](https://quizandsurveymaster.com/downloads/mailchimp-integration/) +- [Zapier Integration](https://quizandsurveymaster.com/downloads/zapier-integration/) -⚡ [InstaWP](https://instawp.com/) - Launch a quick WordPress site with this sandbox service. Create New WordPress instance within a second. +**QSM Themes** +- [Fortune theme](https://themes.quizandsurveymaster.com/fortune/) +- [Breeze theme](https://themes.quizandsurveymaster.com/breeze-qsm-theme-demo/) +- [Pool theme](https://themes.quizandsurveymaster.com/pool-qsm-theme-demo/) +- [Sapience theme](https://themes.quizandsurveymaster.com/sapience/) +- [Sigma theme](https://themes.quizandsurveymaster.com/sigma/) +- [Ivory theme](https://themes.quizandsurveymaster.com/ivory-qsm-theme-demo/) + +### SUPPORT + +For clarity on QSM core and features, check [QSM Documentation](https://quizandsurveymaster.com/docs/). You can reach for support through our [Contact Form](https://quizandsurveymaster.com/contact-support/) or use the WordPress form for free plugin support. We're equally responsive on both platforms. + +### REACH OUT TO US +- Join our official [FB group](https://www.facebook.com/groups/516958552587745). +- Learn more from our tutorials on [Youtube Channel](https://www.youtube.com/@QuizAndSurveyMaster). +- Get further insights on QSM and WordPress from our [Blogs](https://quizandsurveymaster.com/blog/). == Installation == -* Navigate to Add New Plugin page within your WordPress -* Search for Quiz And Survey Master -* Click Install Now link on the plugin and follow the prompts -* Activate the plugin through the 'Plugins' menu in WordPress +This section describes how to install the plugin and get it working. + +e.g. + +1. Upload the plugin files to the `/wp-content/plugins/plugin-name` directory, or install the plugin through the WordPress plugins screen directly. +1. Activate the plugin through the 'Plugins' screen in WordPress +1. Use the Settings->Plugin Name screen to configure the plugin +1. (Make your instructions match the desired user flow for activating and installing your plugin. Include any steps that might be needed for explanatory purposes) == Frequently Asked Questions == -= How do you use that feature? = -We have extensive documentation and videos for the plugin. You can view the documentation here: [Documentation](https://quizandsurveymaster.com/docs). If you still need assistance, feel free to reach out to us! += Can I display different content based on user responses? = -= I want to edit the output for %QUESTIONS_ANSWERS%. Can I do that? = +Absolutely! With QSM, you can create conditional logic-based quizzes and surveys, where specific questions or content are displayed based on the user's previous responses. This feature is particularly useful for creating personalized experiences, such as personality quizzes or branching surveys. -Yes, it is possible to edit the output of the variable %QUESTIONS_ANSWERS%. When editing your quiz, go to the “Text” tab. Once on the “Text” tab scroll almost all the way down the page and you will see a text area that allows you to edit the contents of %QUESTIONS_ANSWERS%. += Can I collect and analyze user data from my quizzes and surveys? = -= I want to remove the "Correct Answer" part of my results page, or I want to display the "Correct Answer Info" part on my results page. How can I do that? = +Yes, QSM allows you to collect and analyze user data from your quizzes and surveys. You can view detailed reports and results in the admin area, including user responses, scores, and completion rates. Additionally, you can integrate with popular email marketing platforms like Mailchimp and ActiveCampaign for lead generation and follow-up campaigns. -To make these changes, you will edit the %QUESTIONS_ANSWERS% variable. To do that, simply look at the answer to the previous question. += Is QSM compatible with other plugins and themes? = -= My preview looks different than my quiz. What can I do? = +QSM is designed to be compatible with most WordPress plugins and themes. However, in case of any conflicts or issues, our team provides comprehensive documentation, including common conflict solutions and guidelines for theme compatibility. -This is usually a theme conflict. You can [checkout out our common conflict solutions](https://quizandsurveymaster.com/docs/advanced-topics/common-theme-conflict-fixes/) or feel free to contact us. == Screenshots == @@ -163,6 +179,12 @@ This is usually a theme conflict. You can [checkout out our common conflict solu 18. Database == Changelog == += 9.1.0 ( July 11, 2024 ) = +* Feature: Added case-sensitive option to paragraph and short answers question types +* Bug: Fixed vulnerability with quiz settings +* Bug: Fixed php error with quiz categories +* Enhancement: Added option to check database structure + = 9.0.5 ( June 19, 2024 ) = * Bug: Resolved a security vulnerability * Bug: Fixed the wpApiSettings JavaScript error