diff --git a/assets/Premium Bundle.png b/assets/Premium Bundle.png deleted file mode 100644 index 7ee627438..000000000 Binary files a/assets/Premium Bundle.png and /dev/null differ diff --git a/assets/Starter Bundle.png b/assets/Starter Bundle.png deleted file mode 100644 index 9e5a54fd6..000000000 Binary files a/assets/Starter Bundle.png and /dev/null differ diff --git a/css/qsm-admin-question.css b/css/qsm-admin-question.css index b5e9e5e09..0e0bfe9ed 100644 --- a/css/qsm-admin-question.css +++ b/css/qsm-admin-question.css @@ -453,11 +453,11 @@ input#image_size-width { .change-answer-editor-label>#change-answer-editor { width: auto; } -a.import-button.button.disable_import { +a.import-button.button.disable_import, a.link-question.button.disable_import { position: relative; z-index: 0; } -a.import-button.button.disable_import::before { +a.import-button.button.disable_import::before, a.link-question.button.disable_import::before { content: ''; background: rgba(255, 255, 255, 0.5); width: 100%; diff --git a/css/qsm-admin.css b/css/qsm-admin.css index 63a049e03..f15f72b61 100644 --- a/css/qsm-admin.css +++ b/css/qsm-admin.css @@ -1378,7 +1378,7 @@ tr .qsm-opt-desc { #quiz_settings_wrapper .qsm-opt-desc { display: none !important; } -.form-table td fieldset label { +.qsm_tab_content .form-table td fieldset label { margin-right: 20px !important; width: 100%; } @@ -1458,6 +1458,8 @@ td.scheduled_time_start { background: #fff; box-sizing: border-box; } + + .qsm-text-main-wrap #postbox-container-1 { position: relative; background: #fff; diff --git a/js/qsm-admin.js b/js/qsm-admin.js index 603dbe52d..277e3378e 100644 --- a/js/qsm-admin.js +++ b/js/qsm-admin.js @@ -2240,10 +2240,14 @@ var import_button; QSMQuestion.addQuestionToPage(model); QSMQuestion.savePages(); - $('.import-button').removeClass('disable_import'); + $('.import-button, .link-question').removeClass('disable_import'); QSMQuestion.countTotal(); - import_button.html('').html(qsm_admin_messages.add_question); - import_button.attr("onclick", "return confirm(" + qsm_admin_messages.confirm_message + "' '" + qsm_admin_messages.import_question_again + ")"); + if(import_button){ + import_button.html(qsm_admin_messages.add_question); + } + if(import_button){ + import_button.attr("onclick", "return confirm('" + qsm_admin_messages.confirm_message + " " + qsm_admin_messages.import_question_again + "');"); + } QSMQuestion.openEditPopup(model.id, $('.question[data-question-id=' + model.id + ']').find('.edit-question-button')); // $('#save-popup-button').trigger('click'); }, @@ -3256,7 +3260,7 @@ var import_button; $(document).on('click', '.qsm-popup-bank .import-button', function (event) { event.preventDefault(); - $(this).text('').text(qsm_admin_messages.adding_question); + $(this).text(qsm_admin_messages.adding_question); import_button = $(this); $('.import-button').addClass('disable_import'); QSMQuestion.addQuestionFromQuestionBank($(this).data('question-id')); @@ -3773,6 +3777,7 @@ var import_button; }) .done(function (results) { if (results.status) { + jQuery(document).trigger('qsm_after_save_results'); QSMAdmin.displayAlert(qsm_admin_messages.results_page_saved, 'success'); } else { QSMAdmin.displayAlert( qsm_admin_messages.results_page_save_error + ' ' + qsm_admin_messages.results_page_saved, 'error'); diff --git a/js/qsm-quiz.js b/js/qsm-quiz.js index af8382bde..bbd87c641 100644 --- a/js/qsm-quiz.js +++ b/js/qsm-quiz.js @@ -132,7 +132,7 @@ var qsmTimerInterval = []; // Calculates starting time. var timerTotal = parseFloat(qmn_quiz_data[quizID].timer_limit) * 60; var timerStarted = localStorage.getItem('mlw_started_quiz' + quizID); - var timerConsumed = parseInt(localStorage.getItem('mlw_time_consumed_quiz' + quizID)); + var timerConsumed = parseInt(localStorage.getItem('mlw_time_consumed_quiz' + quizID)) || 1; var timerRemaning = timerTotal - timerConsumed; if ('yes' == timerStarted && 0 < timerRemaning) { seconds = parseInt(timerRemaning); @@ -162,6 +162,7 @@ var qsmTimerInterval = []; * @param int quizID The ID of the quiz. */ timer: function (quizID) { + jQuery(document).trigger('qmn_timer_consumed_seconds', [quizID, qmn_quiz_data, qsm_timer_consumed_obj]); qmn_quiz_data[quizID].timerRemaning -= 1; qmn_quiz_data[quizID].timerConsumed += 1; if (0 > qmn_quiz_data[quizID].timerRemaning) { @@ -177,7 +178,7 @@ var qsmTimerInterval = []; } } var display = QSM.secondsToTimer(secondsRemaining); - if(qsm_timer_consumed_obj.qmn_count_upward_status == true){ + if(qsm_timer_consumed_obj.qmn_count_upward_status){ display = QSM.secondsToTimer(secondsConsumed); } var systemTime = new Date().getTime() / 1000; @@ -361,7 +362,7 @@ var qsmTimerInterval = []; // Calculates starting time. let timerStarted = localStorage.getItem('mlw_started_quiz' + quizID); - let timerConsumed = parseInt(localStorage.getItem('mlw_time_consumed_quiz' + quizID)); + let timerConsumed = parseInt(localStorage.getItem('mlw_time_consumed_quiz' + quizID)) || 1; let seconds = parseFloat(qmn_quiz_data[quizID].timer_limit) * 60; let timerRemaning = seconds - timerConsumed; if ('yes' == timerStarted && 0 < timerRemaning) { diff --git a/mlw_quizmaster2.php b/mlw_quizmaster2.php index b65eb8b09..ce63fc21e 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.1.3 + * Version: 9.2.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.1.3'; + public $version = '9.2.0'; /** * QSM Alert Manager Object @@ -345,6 +345,7 @@ private function load_dependencies() { * @return void */ private function add_hooks() { + add_action( 'admin_menu', array( $this, 'qsm_add_user_capabilities' ) ); 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' ) ); @@ -524,10 +525,8 @@ public function qsm_admin_scripts_style( $hook ) { 'results_page_saved' => __('Results pages were saved!', 'quiz-master-next'), 'results_page_save_error' => __('There was an error when saving the results pages.', 'quiz-master-next'), 'all_categories' => __('All Categories', 'quiz-master-next'), - 'add_question' => __('Add Question', 'quiz-master-next'), 'question_created' => __('Question created!', 'quiz-master-next'), 'new_question' => __('Your new question!', 'quiz-master-next'), - 'adding_question' => __('Adding question...', 'quiz-master-next'), 'creating_question' => __('Creating question...', 'quiz-master-next'), 'duplicating_question' => __('Duplicating question...', 'quiz-master-next'), 'saving_question' => __('Saving question...', 'quiz-master-next'), @@ -652,6 +651,26 @@ public function register_quiz_post_types() { 'rewrite' => array( 'slug' => $cpt_slug ), 'has_archive' => $has_archive, 'supports' => array( 'title', 'author', 'comments', 'thumbnail' ), + 'capability_type' => array( 'qsm_quiz', 'qsm_quizzes' ), + 'map_meta_cap' => true, + ); + $quiz_args['capabilities'] = array( + 'edit_post' => 'edit_qsm_quiz', + 'edit_post' => 'duplicate_qsm_quiz', + 'read_post' => 'read_qsm_quiz', + 'delete_post' => 'delete_qsm_quiz', + 'edit_posts' => 'edit_qsm_quizzes', + 'edit_others_posts' => 'edit_others_qsm_quizzes', + 'publish_posts' => 'publish_qsm_quizzes', + 'read_private_posts' => 'read_private_qsm_quizzes', + 'delete_posts' => 'delete_qsm_quizzes', + 'delete_private_posts' => 'delete_private_qsm_quizzes', + 'delete_published_posts' => 'delete_published_qsm_quizzes', + 'delete_others_posts' => 'delete_others_qsm_quizzes', + 'edit_private_posts' => 'edit_private_qsm_quizzes', + 'edit_published_posts' => 'edit_published_qsm_quizzes', + 'create_posts' => 'create_qsm_quizzes', + 'moderate_comments' => 'view_qsm_quiz_result', ); // Registers post type. @@ -682,10 +701,88 @@ public function register_quiz_post_types() { 'show_in_rest' => true, 'show_tagcloud' => false, 'rewrite' => false, + 'capabilities' => array( + 'manage_terms' => 'manage_qsm_quiz_categories', + 'edit_terms' => 'edit_qsm_quiz_categories', + 'delete_terms' => 'delete_qsm_quiz_categories', + 'assign_terms' => 'assign_qsm_quiz_categories', + ), ); register_taxonomy( 'qsm_category', array( 'qsm-taxonomy' ), $taxonomy_args ); } + public function qsm_add_user_capabilities() { + $administrator_capabilities = array( + 'duplicate_qsm_quiz', + 'delete_qsm_quiz', + 'edit_others_qsm_quizzes', + 'publish_qsm_quizzes', + 'read_private_qsm_quizzes', + 'delete_qsm_quizzes', + 'delete_private_qsm_quizzes', + 'delete_published_qsm_quizzes', + 'delete_others_qsm_quizzes', + 'edit_private_qsm_quizzes', + 'edit_published_qsm_quizzes', + 'manage_qsm_quiz_categories', + 'manage_qsm_quiz_answer_label', + 'view_qsm_quiz_result', + 'edit_qsm_quiz_categories', + 'assign_qsm_quiz_categories', + 'delete_qsm_quiz_categories', + ); + $editor_capabilities = array( + 'publish_qsm_quizzes', + 'edit_published_qsm_quizzes', + 'edit_others_qsm_quizzes', + 'delete_published_qsm_quizzes', + 'delete_qsm_quiz', + 'delete_qsm_quizzes', + 'manage_qsm_quiz_categories', + 'manage_qsm_quiz_answer_label', + 'view_qsm_quiz_result', + 'edit_qsm_quiz_categories', + 'assign_qsm_quiz_categories', + ); + $author_capabilities = array( + 'edit_published_qsm_quizzes', + 'publish_qsm_quizzes', + ); + $contributor_capabilities = array( + 'read_qsm_quiz', + 'edit_qsm_quiz', + 'edit_qsm_quizzes', + 'create_qsm_quizzes', + ); + + $user = wp_get_current_user(); + $roles = (array) $user->roles; + $rolename = $roles[0]; + + $role = get_role( $rolename ); + + // Remove all capabilities first. + foreach ( $administrator_capabilities as $cap ) { + if ( $role->has_cap( $cap ) ) { + $role->remove_cap( $cap ); + } + } + + // Dynamically determine the capabilities to add based on the current user role. + $capabilities_to_add = isset(${$rolename . '_capabilities'}) ? ${$rolename . '_capabilities'} : array(); + $capabilities_to_add = apply_filters( + 'qsm_default_user_capabilities', + isset(${$rolename . '_capabilities'}) ? array_unique( array_merge( $capabilities_to_add, $contributor_capabilities ) ) : [], + $user + ); + + if ( isset( $capabilities_to_add ) ) { + foreach ( $capabilities_to_add as $cap ) { + $role->add_cap( $cap ); + } + } + } + public function parent_file( $file_name ) { global $menu, $submenu, $parent_file, $submenu_file; if ( 'edit-tags.php?taxonomy=qsm_category' === $submenu_file ) { @@ -729,44 +826,45 @@ public function setup_admin_menu() { $enabled = get_option( 'qsm_multiple_category_enabled' ); $menu_position = self::get_free_menu_position(26.1, 0.3); $settings = (array) get_option( 'qmn-settings' ); - if ( ! class_exists('QSM_Ultimate') ) { - $user = wp_get_current_user(); - if ( in_array( 'subscriber', (array) $user->roles, true ) ) { - $role_capabilities = get_role( 'subscriber' ); - $role_capabilities->remove_cap('edit_posts'); - $role_capabilities->remove_cap('moderate_comments'); - } - } - else { - apply_filters('qsm_user_role_menu_for_subcriber',true); - } - $qsm_dashboard_page = add_menu_page( 'Quiz And Survey Master', __( 'QSM', 'quiz-master-next' ), 'edit_posts', 'qsm_dashboard', 'qsm_generate_dashboard_page', 'dashicons-feedback', $menu_position ); - add_submenu_page( 'qsm_dashboard', __( 'Dashboard', 'quiz-master-next' ), __( 'Dashboard', 'quiz-master-next' ), 'edit_posts', 'qsm_dashboard', 'qsm_generate_dashboard_page', 0 ); + + apply_filters('qsm_user_role_menu_for_subscriber', true); + + $capabilities = array( + 'delete_published_qsm_quizzes', + 'create_qsm_quizzes', + 'delete_others_qsm_quizzes', + 'manage_qsm_quiz_categories', + 'manage_qsm_quiz_answer_label', + 'view_qsm_quiz_result', + ); + + add_menu_page( 'Quiz And Survey Master', __( 'QSM', 'quiz-master-next' ), $capabilities[1], 'qsm_dashboard', 'qsm_generate_dashboard_page', 'dashicons-feedback', $menu_position ); + add_submenu_page( 'qsm_dashboard', __( 'Dashboard', 'quiz-master-next' ), __( 'Dashboard', 'quiz-master-next' ), $capabilities[2], 'qsm_dashboard', 'qsm_generate_dashboard_page', 0 ); if ( $enabled && 'cancelled' !== $enabled ) { - $qsm_taxonomy_menu_hook = add_submenu_page( 'qsm_dashboard', __( 'Question Categories', 'quiz-master-next' ), __( 'Question Categories', 'quiz-master-next' ), 'edit_posts', 'edit-tags.php?taxonomy=qsm_category' ); + add_submenu_page( 'qsm_dashboard', __( 'Question Categories', 'quiz-master-next' ), __( 'Question Categories', 'quiz-master-next' ), $capabilities[3], 'edit-tags.php?taxonomy=qsm_category' ); } if ( ! class_exists( 'QSM_Advanced_Assessment' ) ) { - add_submenu_page( 'qsm_dashboard', __( 'Answer Labels', 'quiz-master-next' ), __( 'Answer Labels', 'quiz-master-next' ), 'manage_options', 'qsm-answer-label', 'qsm_advanced_assessment_quiz_page_content', 3 ); + add_submenu_page( 'qsm_dashboard', __( 'Answer Labels', 'quiz-master-next' ), __( 'Answer Labels', 'quiz-master-next' ), $capabilities[4], 'qsm-answer-label', 'qsm_advanced_assessment_quiz_page_content', 3 ); } - add_submenu_page( 'options.php', __( 'Settings', 'quiz-master-next' ), __( 'Settings', 'quiz-master-next' ), 'edit_posts', 'mlw_quiz_options', 'qsm_generate_quiz_options' ); - add_submenu_page( 'qsm_dashboard', __( 'Results', 'quiz-master-next' ), __( 'Results', 'quiz-master-next' ), 'moderate_comments', 'mlw_quiz_results', 'qsm_generate_admin_results_page' ); + add_submenu_page( 'options.php', __( 'Settings', 'quiz-master-next' ), __( 'Settings', 'quiz-master-next' ), $capabilities[1], 'mlw_quiz_options', 'qsm_generate_quiz_options' ); + add_submenu_page( 'qsm_dashboard', __( 'Results', 'quiz-master-next' ), __( 'Results', 'quiz-master-next' ), $capabilities[5], 'mlw_quiz_results', 'qsm_generate_admin_results_page' ); // Failed Submission. if ( ! empty( $settings['enable_qsm_log'] ) && $settings['enable_qsm_log'] ) { - add_submenu_page( 'qsm_dashboard', __( 'Failed Submission', 'quiz-master-next' ), __( 'Failed Submission', 'quiz-master-next' ), 'moderate_comments', 'qsm-quiz-failed-submission', array( $this, 'admin_failed_submission_page' ) ); + add_submenu_page( 'qsm_dashboard', __( 'Failed Submission', 'quiz-master-next' ), __( 'Failed Submission', 'quiz-master-next' ), $capabilities[2], 'qsm-quiz-failed-submission', array( $this, 'admin_failed_submission_page' ) ); } // Failed DB Query if ( ! empty( $settings['enable_qsm_log'] ) && $settings['enable_qsm_log'] && $this->get_failed_alter_table_queries() ) { - add_submenu_page( 'qsm_dashboard', __( 'Failed DB Queries', 'quiz-master-next' ), __( 'Failed Database Queries', 'quiz-master-next' ), 'moderate_comments', 'qsm-database-failed-queries', array( $this, 'qsm_database_failed_queries' ) ); + add_submenu_page( 'qsm_dashboard', __( 'Failed DB Queries', 'quiz-master-next' ), __( 'Failed Database Queries', 'quiz-master-next' ), $capabilities[2], 'qsm-database-failed-queries', array( $this, 'qsm_database_failed_queries' ) ); } - add_submenu_page( 'options.php', __( 'Result Details', 'quiz-master-next' ), __( 'Result Details', 'quiz-master-next' ), 'moderate_comments', 'qsm_quiz_result_details', 'qsm_generate_result_details' ); - add_submenu_page( 'qsm_dashboard', __( 'Settings', 'quiz-master-next' ), __( 'Settings', 'quiz-master-next' ), 'manage_options', 'qmn_global_settings', array( 'QMNGlobalSettingsPage', 'display_page' ) ); - add_submenu_page( 'qsm_dashboard', __( 'Tools', 'quiz-master-next' ), __( 'Tools', 'quiz-master-next' ), 'manage_options', 'qsm_quiz_tools', 'qsm_generate_quiz_tools' ); - add_submenu_page( 'qsm_dashboard', __( 'Stats', 'quiz-master-next' ), __( 'Stats', 'quiz-master-next' ), 'moderate_comments', 'qmn_stats', 'qmn_generate_stats_page' ); - add_submenu_page( 'qsm_dashboard', __( 'About', 'quiz-master-next' ), __( 'About', 'quiz-master-next' ), 'moderate_comments', 'qsm_quiz_about', 'qsm_generate_about_page' ); - - add_submenu_page( 'qsm_dashboard', __( 'Extensions Settings', 'quiz-master-next' ), '' . __( 'Extensions', 'quiz-master-next' ) . '', 'moderate_comments', 'qmn_addons', 'qmn_addons_page', 34 ); - add_submenu_page( 'qsm_dashboard', __( 'Free Add-ons', 'quiz-master-next' ), '' . esc_html__( 'Free Add-ons', 'quiz-master-next' ) . '', 'moderate_comments', 'qsm-free-addon', 'qsm_display_optin_page', 90 ); + add_submenu_page( 'options.php', __( 'Result Details', 'quiz-master-next' ), __( 'Result Details', 'quiz-master-next' ), $capabilities[5], 'qsm_quiz_result_details', 'qsm_generate_result_details' ); + add_submenu_page( 'qsm_dashboard', __( 'Settings', 'quiz-master-next' ), __( 'Settings', 'quiz-master-next' ), $capabilities[2], 'qmn_global_settings', array( 'QMNGlobalSettingsPage', 'display_page' ) ); + add_submenu_page( 'qsm_dashboard', __( 'Tools', 'quiz-master-next' ), __( 'Tools', 'quiz-master-next' ), $capabilities[2], 'qsm_quiz_tools', 'qsm_generate_quiz_tools' ); + add_submenu_page( 'qsm_dashboard', __( 'Stats', 'quiz-master-next' ), __( 'Stats', 'quiz-master-next' ), $capabilities[2], 'qmn_stats', 'qmn_generate_stats_page' ); + add_submenu_page( 'qsm_dashboard', __( 'About', 'quiz-master-next' ), __( 'About', 'quiz-master-next' ), $capabilities[2], 'qsm_quiz_about', 'qsm_generate_about_page' ); + + add_submenu_page( 'qsm_dashboard', __( 'Extensions Settings', 'quiz-master-next' ), '' . __( 'Extensions', 'quiz-master-next' ) . '', $capabilities[2], 'qmn_addons', 'qmn_addons_page', 34 ); + add_submenu_page( 'qsm_dashboard', __( 'Free Add-ons', 'quiz-master-next' ), '' . esc_html__( 'Free Add-ons', 'quiz-master-next' ) . '', $capabilities[2], 'qsm-free-addon', 'qsm_display_optin_page', 90 ); // Register screen option for dashboard page add_action( 'screen_settings', 'qsm_dashboard_screen_options', 10, 2 ); } diff --git a/php/admin/admin-results-details-page.php b/php/admin/admin-results-details-page.php index 7bbe45feb..59825ee2b 100644 --- a/php/admin/admin-results-details-page.php +++ b/php/admin/admin-results-details-page.php @@ -8,7 +8,7 @@ * @since 4.4.0 */ function qsm_generate_result_details() { - if ( ! current_user_can( 'moderate_comments' ) ) { + if ( ! current_user_can( 'view_qsm_quiz_result' ) ) { return; } global $mlwQuizMasterNext; @@ -69,6 +69,12 @@ function qsm_generate_results_details_tab() { $quiz_id = intval( $results_data->quiz_id ); $mlwQuizMasterNext->pluginHelper->prepare_quiz( $quiz_id ); + $quiz_post_id = $wpdb->get_var( $wpdb->prepare( "SELECT post_id FROM $wpdb->postmeta WHERE meta_key = 'quiz_id' AND meta_value = %d", $quiz_id ) ); + $post_author = get_post_field( 'post_author', $quiz_post_id, true ); + if ( ( ! current_user_can( 'view_qsm_quiz_result' ) || intval($post_author) != get_current_user_id()) && ! current_user_can( 'delete_others_qsm_quizzes' ) ) { + return; + } + //Get the data for comments $quiz_options = $mlwQuizMasterNext->quiz_settings->get_setting( 'quiz_options'); $comments_enabled = $quiz_options['comment_section']; diff --git a/php/admin/admin-results-page.php b/php/admin/admin-results-page.php index 3653acd1a..7647e67d3 100644 --- a/php/admin/admin-results-page.php +++ b/php/admin/admin-results-page.php @@ -12,7 +12,7 @@ function qsm_generate_admin_results_page() { // Makes sure user has the right privledges. - if ( ! current_user_can( 'moderate_comments' ) ) { + if ( ! current_user_can( 'view_qsm_quiz_result' ) ) { return; } @@ -524,7 +524,20 @@ function qsm_results_overview_tab_content() { ?> - quiz_name ); ?>
| |
+ + quiz_name ); ?> +
+ + user ) || current_user_can( 'delete_others_qsm_quizzes' ) ) { + ?> + | + + | + + +
+ $v ) { if ( isset( $v['content'][ $x ] ) ) { diff --git a/php/admin/options-page-contact-tab.php b/php/admin/options-page-contact-tab.php index d111a98f1..e5138fa8d 100644 --- a/php/admin/options-page-contact-tab.php +++ b/php/admin/options-page-contact-tab.php @@ -88,7 +88,7 @@ function qsm_options_contact_tab_content() { - + @@ -96,11 +96,11 @@ function qsm_options_contact_tab_content() {
@@ -182,9 +182,6 @@ function qsm_contact_form_admin_ajax() { foreach ( $settings as $key => $val ) { $quiz_options[ $key ] = $val; } - if ( isset($settings['loggedin_user_contact']) ) { - $quiz_options['loggedin_user_contact'] = (1 == $settings['loggedin_user_contact']) ? 0 : 1; - } $mlwQuizMasterNext->pluginHelper->update_quiz_setting( 'quiz_options', $quiz_options ); } diff --git a/php/admin/options-page-style-tab.php b/php/admin/options-page-style-tab.php index 9eb3cee99..bdbff7d42 100644 --- a/php/admin/options-page-style-tab.php +++ b/php/admin/options-page-style-tab.php @@ -71,6 +71,7 @@ function qsm_options_styling_tab_content() {
  • +
    diff --git a/php/admin/options-page-text-tab.php b/php/admin/options-page-text-tab.php index 19cb1131e..ad85cf3ce 100644 --- a/php/admin/options-page-text-tab.php +++ b/php/admin/options-page-text-tab.php @@ -40,6 +40,7 @@ function mlw_options_text_tab_content() {
  • +
    diff --git a/php/admin/quiz-options-page.php b/php/admin/quiz-options-page.php index 615b9a455..8f81d03d8 100644 --- a/php/admin/quiz-options-page.php +++ b/php/admin/quiz-options-page.php @@ -16,26 +16,18 @@ * @since 4.4.0 */ function qsm_generate_quiz_options() { - - // Checks if current user can. - if ( ! current_user_can( 'edit_posts' ) ) { - return; - } global $wpdb; global $mlwQuizMasterNext; + $quiz_id = isset( $_GET['quiz_id'] ) ? intval( $_GET['quiz_id'] ) : 0; + $quiz_post_id = $wpdb->get_var( $wpdb->prepare( "SELECT post_id FROM $wpdb->postmeta WHERE meta_key = 'quiz_id' AND meta_value = %d", $quiz_id ) ); + $post_author = get_post_field( 'post_author', $quiz_post_id, true ); //user role addon is active - apply_filters('qsm_user_role_permission_page',true); - // Check user capability - if ( ! class_exists('QSM_Ultimate') ) { - $user = wp_get_current_user(); - if ( in_array( 'author', (array) $user->roles, true ) ) { - $user_id = sanitize_text_field( $user->ID ); - $quiz_id = isset( $_GET['quiz_id'] ) ? intval( $_GET['quiz_id'] ) : 0; - $quiz_author_id = $wpdb->get_var( $wpdb->prepare( "SELECT quiz_author_id FROM {$wpdb->prefix}mlw_quizzes WHERE quiz_id=%d AND quiz_author_id=%d LIMIT 1", $quiz_id, $user_id ) ); - if ( ! $quiz_author_id ) { - wp_die( 'You are not allow to edit this quiz, You need higher permission!' ); - } - } + apply_filters( 'qsm_user_role_permission_page', true ); + + // Check if the current user has the capability to edit the quiz. + if ( ( ! current_user_can( 'edit_qsm_quiz', $quiz_post_id ) || intval($post_author) != get_current_user_id()) && ! current_user_can( 'edit_others_qsm_quizzes' ) ) { + wp_die( 'You are not allowed to edit this quiz, You need higher permission!' ); + return; } $quiz_name = ''; @@ -112,7 +104,7 @@ function qsm_generate_quiz_options() { - +
    diff --git a/php/admin/quizzes-page.php b/php/admin/quizzes-page.php index 11a4f218f..4ca12112a 100644 --- a/php/admin/quizzes-page.php +++ b/php/admin/quizzes-page.php @@ -179,18 +179,25 @@ public function qsm_post_row_actions( $actions, $post ) { $settings = (array) get_option( 'qmn-settings' ); $quiz_id = get_post_meta( $post->ID, 'quiz_id', true ); if ( ! empty( $quiz_id ) ) { - $actions = array( - 'edit' => '' . esc_html__( 'Edit', 'quiz-master-next' ) . '', - 'duplicate' => '' . esc_html__( 'Duplicate', 'quiz-master-next' ) . '', - 'delete' => '' . esc_html__( 'Delete', 'quiz-master-next' ) . '', - 'view_results' => '' . esc_html__( 'View Results', 'quiz-master-next' ) . '', - ); + $actions = array(); + if ( ( current_user_can( 'edit_qsm_quiz', $post->ID ) && get_current_user_id() == $post->post_author ) || current_user_can( 'edit_others_qsm_quizzes' ) ) { + $actions['edit'] = '' . esc_html__( 'Edit', 'quiz-master-next' ) . ''; + } + if ( ( current_user_can( 'duplicate_qsm_quiz', $post->ID ) && get_current_user_id() == $post->post_author ) || current_user_can( 'edit_others_qsm_quizzes' ) ) { + $actions['duplicate'] = '' . esc_html__( 'Duplicate', 'quiz-master-next' ) . ''; + } + if ( ( current_user_can( 'delete_qsm_quiz', $post->ID ) && get_current_user_id() == $post->post_author ) || current_user_can( 'delete_others_qsm_quizzes' ) ) { + $actions['delete'] = '' . esc_html__( 'Delete', 'quiz-master-next' ) . ''; + } + if ( ( current_user_can( 'view_qsm_quiz_result' ) && get_current_user_id() == $post->post_author ) || current_user_can( 'edit_others_qsm_quizzes' ) ) { + $actions['view_result'] = '' . esc_html__( 'View Results', 'quiz-master-next' ) . ''; + } if ( empty( $settings['disable_quiz_public_link'] ) ) { $actions['view'] = '' . esc_html__( 'Preview', 'quiz-master-next' ) . ''; } $actions = apply_filters( 'qsm_quiz_actions_after', $actions, $post ); - } - } + } + } return $actions; } @@ -319,8 +326,10 @@ public function qsm_quiz_list_header() {

    '.esc_html__( 'Add New', 'quiz-master-next' ).''; - echo apply_filters( 'qsm_add_quiz_after', $add_button ); ?> + if ( current_user_can( 'create_qsm_quizzes' ) ) { + $add_button = '' . esc_html__( 'Add New', 'quiz-master-next' ) . ''; + } + echo apply_filters( 'qsm_add_quiz_after', ! empty( $add_button ) ? $add_button : '' ); ?>

    + - + diff --git a/php/classes/class-qmn-log-manager.php b/php/classes/class-qmn-log-manager.php index 35749acf2..e8454a481 100644 --- a/php/classes/class-qmn-log-manager.php +++ b/php/classes/class-qmn-log-manager.php @@ -44,7 +44,7 @@ public function register_post_type() { $settings = (array) get_option( 'qmn-settings' ); $log_args = array( 'labels' => array( 'name' => 'QSM Logs' ), - 'public' => ! empty( $settings['enable_qsm_log'] ) && $settings['enable_qsm_log'], + 'public' => ! empty( $settings['enable_qsm_log'] ) && $settings['enable_qsm_log'] && current_user_can( 'switch_themes' ), 'query_var' => false, 'publicly_queryable' => false, 'rewrite' => false, diff --git a/php/classes/class-qmn-quiz-creator.php b/php/classes/class-qmn-quiz-creator.php index c0c1b63a3..39a29da31 100644 --- a/php/classes/class-qmn-quiz-creator.php +++ b/php/classes/class-qmn-quiz-creator.php @@ -274,7 +274,7 @@ public function delete_quiz( $quiz_id, $quiz_name ) { $quizzes_table = $wpdb->prefix . 'mlw_quizzes'; $quiz_post_id = $wpdb->get_var( "SELECT post_id FROM $wpdb->postmeta WHERE meta_key = 'quiz_id' AND meta_value = '$quiz_id'" ); - if ( empty( $quiz_post_id ) || ! current_user_can( 'delete_post', $quiz_post_id ) ) { + if ( ( empty( $quiz_post_id ) || ! current_user_can( 'delete_qsm_quiz', $quiz_post_id ) ) && ! current_user_can( 'administrator' ) ) { $mlwQuizMasterNext->alertManager->newAlert( __( 'Sorry, you are not allowed to delete this quiz.', 'quiz-master-next' ), 'error' ); return; } @@ -397,7 +397,7 @@ public function duplicate_quiz( $quiz_id, $quiz_name, $is_duplicating_questions global $wpdb; $quiz_post_id = $wpdb->get_var( "SELECT post_id FROM $wpdb->postmeta WHERE meta_key = 'quiz_id' AND meta_value = '$quiz_id'" ); - if ( empty( $quiz_post_id ) || ! current_user_can( 'edit_post', $quiz_post_id ) ) { + if ( empty( $quiz_post_id ) || ! current_user_can( 'edit_qsm_quiz', $quiz_post_id ) ) { $mlwQuizMasterNext->alertManager->newAlert( __( 'Sorry, you are not allowed to duplicate this quiz.', 'quiz-master-next' ), 'error' ); return; } diff --git a/php/classes/class-qmn-quiz-manager.php b/php/classes/class-qmn-quiz-manager.php index 6dfecc3b4..756641c27 100644 --- a/php/classes/class-qmn-quiz-manager.php +++ b/php/classes/class-qmn-quiz-manager.php @@ -597,7 +597,7 @@ public function display_shortcode( $atts ) { $correct_answer_text = $mlwQuizMasterNext->pluginHelper->qsm_language_support( $correct_answer_text, "quiz_quick_result_correct_answer_text-{$qmn_array_for_variables['quiz_id']}" ); $wrong_answer_text = sanitize_text_field( $qmn_quiz_options->quick_result_wrong_answer_text ); $wrong_answer_text = $mlwQuizMasterNext->pluginHelper->qsm_language_support( $wrong_answer_text, "quiz_quick_result_wrong_answer_text-{$qmn_array_for_variables['quiz_id']}" ); - $quiz_processing_message = $mlwQuizMasterNext->pluginHelper->qsm_language_support( $qmn_quiz_options->quiz_processing_message, "quiz_quiz_processing_message-{$qmn_array_for_variables['quiz_id']}" ); + $quiz_processing_message = isset( $qmn_quiz_options->quiz_processing_message ) ? $mlwQuizMasterNext->pluginHelper->qsm_language_support( $qmn_quiz_options->quiz_processing_message, "quiz_quiz_processing_message-{$qmn_array_for_variables['quiz_id']}" ) : ''; $quiz_limit_choice = $mlwQuizMasterNext->pluginHelper->qsm_language_support( $qmn_quiz_options->quiz_limit_choice, "quiz_quiz_limit_choice-{$qmn_array_for_variables['quiz_id']}" ); $qmn_json_data = array( 'quiz_id' => $qmn_array_for_variables['quiz_id'], @@ -929,14 +929,6 @@ public function load_questions( $quiz_id, $quiz_options, $is_quiz_page, $questio $question_ids = apply_filters( 'qsm_load_questions_ids', $question_ids, $quiz_id, $quiz_options ); $question_ids = QMNPluginHelper::qsm_shuffle_assoc( $question_ids ); $question_sql = implode( ',', $question_ids ); - ?> - - get_results( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}mlw_questions WHERE quiz_id=%d AND deleted=0 %1s %2s %3s", $quiz_id, $question_sql, $order_by_sql, $limit_sql ) ); } + if ( + in_array( intval( $quiz_options->randomness_order ), [ 1, 2 ], true) && + ! empty($questions) && + is_array($questions) && + ! isset($_COOKIE[ 'question_ids_' . $quiz_id ]) + ) { + $question_ids = array(); + foreach ( $questions as $question ) { + $question_ids[] = $question->question_id; + } + + $question_sql = implode(',', array_unique($question_ids)); // Prevent duplicates + ?> + + 0, 'min_point' => 0, @@ -2614,7 +2627,7 @@ public static function qsm_max_min_points_conditions( $max_value_array, $min_val $max_min_result['max_point'] = max( $max_value_array ); $max_min_result['min_point'] = min( $min_value_array ); } - return $max_min_result; + return apply_filters( 'qsm_max_min_points_conditions_result', $max_min_result, $question_required, $question ); } /** diff --git a/php/classes/class-qsm-install.php b/php/classes/class-qsm-install.php index 2e9918b53..134d91bc3 100644 --- a/php/classes/class-qsm-install.php +++ b/php/classes/class-qsm-install.php @@ -729,16 +729,16 @@ public function register_default_settings() { // Registers loggedin_user_contact setting $field_array = array( 'id' => 'loggedin_user_contact', - 'label' => __( 'Show contact form to logged in users', 'quiz-master-next' ), + 'label' => __( 'Hide contact form to logged in users', 'quiz-master-next' ), 'type' => 'radio', 'options' => array( array( 'label' => __( 'Yes', 'quiz-master-next' ), - 'value' => 0, + 'value' => 1, ), array( 'label' => __( 'No', 'quiz-master-next' ), - 'value' => 1, + 'value' => 0, ), ), 'default' => 0, diff --git a/php/classes/class-qsm-settings.php b/php/classes/class-qsm-settings.php index 863894099..5046ca6e8 100644 --- a/php/classes/class-qsm-settings.php +++ b/php/classes/class-qsm-settings.php @@ -470,9 +470,13 @@ public function get_quiz_options() { $quiz_options = array_merge( $quiz_options, $options ); } - $text = $this->get_setting( 'quiz_text' ); - if ( is_array( $text ) ) { - $quiz_options = array_merge( $quiz_options, $text ); + $text = $this->get_setting('quiz_text'); + if ( is_array($text) ) { + foreach ( $text as $key => $value ) { + if ( ! empty($value) ) { + $quiz_options[ $key ] = $value; + } + } } // Return as old object model diff --git a/php/rest-api.php b/php/rest-api.php index 0c924004e..bbb612a19 100644 --- a/php/rest-api.php +++ b/php/rest-api.php @@ -543,7 +543,6 @@ function qsm_rest_get_questions( WP_REST_Request $request ) { $quiz_name = $wpdb->get_row( $wpdb->prepare( "SELECT quiz_name FROM {$wpdb->prefix}mlw_quizzes WHERE quiz_id = %d", $question['quiz_id'] ), ARRAY_A ); $question['page'] = isset( $question['page'] ) ? $question['page'] : 0; $categorysArray = QSM_Questions::get_question_categories( $question['question_id'] ); - $question_data = array( 'id' => $question['question_id'], 'quizID' => $question['quiz_id'], diff --git a/php/template-variables.php b/php/template-variables.php index 114b4c9a2..564fe870e 100644 --- a/php/template-variables.php +++ b/php/template-variables.php @@ -637,7 +637,7 @@ function mlw_qmn_variable_date( $content, $results ) { * @return string Returns the contents for the results page */ function mlw_qmn_variable_finished_time( $content, $mlw_quiz_array ) { - $date = date_i18n( get_option( 'time_format' ), $mlw_quiz_array['time_taken'] ); + $date = isset( $mlw_quiz_array['time_taken'] ) ? date_i18n( get_option( 'time_format' ), $mlw_quiz_array['time_taken'] ) : ''; $content = str_replace( '%TIME_FINISHED%', $date, $content ); return $content; } @@ -1111,7 +1111,7 @@ function qsm_questions_answers_shortcode_to_text( $mlw_quiz_array, $qmn_question if ( isset( $answer['question_type'] ) && in_array( intval( $answer['question_type'] ), $question_with_text_input, true ) ) { $do_show_wrong = true; $user_given_answer = '' === $answer[1] ? $quiz_options->no_answer_text : htmlentities( $answer[1] ); - $user_given_answer = str_replace( "\n" , "
    ", $user_given_answer ); + $user_given_answer = str_replace( "\n" , "
    ", $user_given_answer ); if ( 12 == $answer['question_type'] && ! empty( $answer[1] ) && strtotime( $user_given_answer ) ) { $preferred_date_format = isset($quiz_options->preferred_date_format) ? $quiz_options->preferred_date_format : get_option('date_format'); $user_given_answer = date_i18n($preferred_date_format, strtotime($user_given_answer)); @@ -1348,7 +1348,7 @@ function qsm_questions_answers_shortcode_to_text( $mlw_quiz_array, $qmn_question $caption = ""; if ( ! empty($single_answer[3]) ) { $caption_name = array_search($image_url, $image_list, true); - $caption = ''.$caption_name.''; + $caption = '' . esc_html( $caption_name ) . ''; } if ( 4 == $answer['question_type'] || 10 == $answer['question_type'] ) { $close_span_without_br = ''; @@ -1365,13 +1365,13 @@ function qsm_questions_answers_shortcode_to_text( $mlw_quiz_array, $qmn_question foreach ( $image_list as $key => $value ) { if ( in_array( $value , $user_text_array_multiple_response, true ) ) { if ( is_numeric( $key ) ) { $key = ""; } - $caption_name = ''.$key.''; - $images_answer .= "$open_span_tag'".esc_html( $caption_name.$close_span_without_br ); + $caption_name = '' . esc_html( $key ) . ''; + $images_answer .= $open_span_tag . '' . $caption_name . $close_span_without_br; } } - $mlw_question_answer_display = str_replace( '%USER_ANSWER%', "$images_answer", $mlw_question_answer_display ); + $mlw_question_answer_display = str_replace( '%USER_ANSWER%', $images_answer, $mlw_question_answer_display ); } else { - $mlw_question_answer_display = str_replace( '%USER_ANSWER%', "$open_span_tag'". esc_html($close_span_with_br.$caption ), $mlw_question_answer_display ); + $mlw_question_answer_display = str_replace( '%USER_ANSWER%', $open_span_tag . '' . $close_span_with_br . $caption, $mlw_question_answer_display ); } } elseif ( 5 == $answer['question_type'] || 3 == $answer['question_type'] ) { $mlw_question_answer_display = str_replace( '%USER_ANSWER%', "$open_span_tag" . nl2br( htmlspecialchars_decode( $user_answer_new, ENT_QUOTES ) ) . $close_span_with_br, $mlw_question_answer_display ); diff --git a/readme.txt b/readme.txt index 71ca822ac..93fc2ba80 100644 --- a/readme.txt +++ b/readme.txt @@ -4,23 +4,34 @@ Tags: quiz, survey, test, exam, online assessment Requires at least: 4.9 Tested up to: 6.6 Requires PHP: 5.4 -Stable tag: 9.1.3 +Stable tag: 9.2.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. Customize personalized results, emails, and create a leaderboard to enhance user engagement +Create engaging quizzes, surveys, tests, & more, with the versatile quiz maker and survey plugin for WordPress. Perfect for gathering insights from any audience. == Description == -https://youtu.be/DyiCCNnDpHk?si=7nda3koRTGw7BW_J - -**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. +**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 quiz maker 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 WordPress plugin to increase user engagement, gather valuable data, and build a stronger connection with your audience. **Try Demo ➡️ [Get a personal sandbox demo with QSM](https://instawp.io/plugins/quiz-master-next?utm_source=wp.org&utm_medium=wp_org_description&utm_campaign=wp_org_to_qsm)** +https://youtu.be/DyiCCNnDpHk?si=7nda3koRTGw7BW_J + ### CREATE UNLIMITED QUIZZES AND QUESTIONS -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. +Create without limits with our online quiz maker— QSM—to craft 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. + +This WordPress quiz maker allows you to create from lead generation quizzes, and customer satisfaction surveys, to assessments, personality tests, fun trivia quizzes, and more. + +### QUIZ DEMOS + +- [Personality Quiz](https://demo.quizandsurveymaster.com/personality-quiz/) +- [Flashcard Demo](https://demo.quizandsurveymaster.com/flash-card-demo/) +- [Quiz with Navigation](https://demo.quizandsurveymaster.com/quiz-with-navigation/) +- [Science Quiz](https://demo.quizandsurveymaster.com/science-quiz/) +- [Quiz with Leaderboard](https://demo.quizandsurveymaster.com/advanced-leaderboard-demo/) +- [Mathematics Quiz](https://demo.quizandsurveymaster.com/interactive-maths-quiz/) ### DIVERSE RANGE OF QUESTIONS @@ -39,11 +50,28 @@ Create quizzes, forms, or surveys with a variety of question types tailored to y - **Polar**: Answer by choosing a spot on the slider scale. - **Opt-in**: Use the checkbox selection to give permission/agree to a text. -**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. +Engage your audience effortlessly with our interactive quiz builder! Easily create tailored quizzes, forms, or surveys using diverse question types that align with your goals and make interaction fun. + +- **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. + +ADVANCED QUESTION TYPES +QSM comes with some advanced question types in their 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. ### CREATE QUIZ WITH BLOCK EDITOR @@ -55,7 +83,7 @@ With the QSM plugin, effortlessly create detailed market research surveys and sh ### FULLY CUSTOMIZABLE -Customize every aspect of your quizzes and surveys: +Create custom quiz and survey forms by customizing every aspect of your quizzes and surveys that users interact with, using our WordPress quiz builder’s flexible features; **Custom Style CSS**: Personalize the look and feel of your quizzes and surveys to match your brand and style perfectly. @@ -65,6 +93,10 @@ Customize every aspect of your quizzes and surveys: **Template Variables**: Use variables to generate custom messages for users and humanize their quiz experience. +### RESPONSIVE DESIGN + +Quiz and Survey Master ensures that your WordPress forms, quizzes, and surveys look and perform flawlessly on any device and browser, thanks to its responsive quiz design. This WordPress quiz maker offers smooth performance, even when using its various themes. You can also create unlimited questions without lag and easily share your quizzes with an audience. + ### DISPLAY SCORE-BASED CUSTOM RESULTS With the QSM plugin, you can create customized results based on quiz scores. Tailor multiple result pages to different score ranges, offering a unique and engaging experience for each participant. @@ -154,6 +186,24 @@ This section describes how to install the plugin and get it working. == Frequently Asked Questions == += How do I get started with QSM - A free quiz maker in WordPress? = + +The quickest way to build a quiz is using the QSM - Block Editor in WordPress. Simply navigate to a New Page or Post, select the QSM Block, and add a new quiz. Enter the quiz's name, set advanced options if required, and click Create Quiz. From there, start adding questions and options, choosing question types from the right-side panel, and Save your draft. Once ready, click Publish to post the quiz on the WordPress website. + +Alternatively, you can create a quiz or survey using the default method, which offers more features and settings. If you have started a quiz in the block editor, simply save the draft and go to QSM > Quizzes/Surveys to edit your existing quiz or add a new one to continue building it with full customization options. + += Can this plugin be translated? = + +Yes, it’s completely possible! With integration to the WPML plugin, this online quiz tool enables you to translate your quizzes and surveys into multiple languages. For more information, refer to the documentation on translating the QSM WordPress plugin. + += How can I get access to all advanced features? = + +To access advanced features, integrations, and themes, you can upgrade to the QSM All Access plan. The pro license gives you access to our 40 add-ons such as advanced assessment, flashcards, email integrations, advanced analytics, and 8 premium themes + += Can I create paid quizzes and surveys? = + +Yes, this is achievable by our Payment Integration add-on. Using PayPal and Stripe, you can easily add payments to your online quizzes and surveys, allowing you to monetize your content easily. + = Can I display different content based on user responses? = 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. @@ -164,8 +214,7 @@ Yes, QSM allows you to collect and analyze user data from your quizzes and surve = Is QSM compatible with other plugins and themes? = -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. - +As a WordPress quiz maker, QSM is designed to be compatible with most other 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. == Screenshots == @@ -189,11 +238,17 @@ QSM is designed to be compatible with most WordPress plugins and themes. However 18. Database == Changelog == += 9.2.0 ( October 07, 2024 ) = +* Bug: Resolved HTML tag issue with the %USER_ANSWER% variable +* Bug: Fixed the issue with contact form position settings +* Bug: Resolved warning issue in the %TIME_FINISHED% variable +* Enhancement: Optimized performance for random question logic +* Enhancement: Improved user permissions and added additional security checks + = 9.1.3 ( September 12, 2024 ) = * Feature: Added placeholder customization for short answer and paragraph questions * Bug: Resolved vulnerability issue with question settings * Bug: Fixed issue with undefined page redirection -* Bug: Enter key issue resolved in paragraph question type = 9.1.2 ( August 22, 2024 ) = * Bug: Resolved issue preventing global settings from being saved