From 504249c97e17444a736ba1fd5b4ac5df680c8951 Mon Sep 17 00:00:00 2001 From: Mohammad Zubair Ali Date: Wed, 11 Sep 2024 16:13:59 +0530 Subject: [PATCH 01/49] fixed false result redirect page issue --- php/admin/options-page-questions-tab.php | 4 ++-- php/admin/options-page-results-page-tab.php | 2 +- php/shortcodes.php | 10 +++++----- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/php/admin/options-page-questions-tab.php b/php/admin/options-page-questions-tab.php index b9fe3e7e8..bc8458a2e 100644 --- a/php/admin/options-page-questions-tab.php +++ b/php/admin/options-page-questions-tab.php @@ -347,7 +347,7 @@ class="save-page-button button button-primary"> 'text', 'default' => '', 'priority' => '1', - 'show' => '3, 5, 7' , + 'show' => '3, 5, 7', ), ); $advanced_question_option = apply_filters( 'qsm_question_advanced_option', $advanced_question_option ); diff --git a/php/admin/options-page-results-page-tab.php b/php/admin/options-page-results-page-tab.php index 69407843f..f02344749 100644 --- a/php/admin/options-page-results-page-tab.php +++ b/php/admin/options-page-results-page-tab.php @@ -290,7 +290,7 @@ function qsm_options_results_tab_template(){

/

- + diff --git a/php/shortcodes.php b/php/shortcodes.php index 26acbf518..4df224894 100644 --- a/php/shortcodes.php +++ b/php/shortcodes.php @@ -203,11 +203,11 @@ function qsm_generate_fb_header_metadata() { quizCreator->get_id(); - $featured_image = get_option("quiz_featured_image_$quiz_id"); - ?> - - quizCreator->get_id(); + $featured_image = get_option("quiz_featured_image_$quiz_id"); + ?> + + Date: Thu, 12 Sep 2024 13:57:08 +0530 Subject: [PATCH 02/49] fixed paragraph question BR issue --- php/template-variables.php | 1 + 1 file changed, 1 insertion(+) diff --git a/php/template-variables.php b/php/template-variables.php index 3ed2233c6..c7b804c7d 100644 --- a/php/template-variables.php +++ b/php/template-variables.php @@ -1111,6 +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 ); 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)); From 17fdecf53669ebdb6b5f5e6dccf7f665ca9c43f3 Mon Sep 17 00:00:00 2001 From: PranavAwasthi Date: Mon, 16 Sep 2024 11:36:57 +0530 Subject: [PATCH 03/49] Fixed NaN timer issue --- js/qsm-quiz.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/js/qsm-quiz.js b/js/qsm-quiz.js index 89c3611eb..7bc31c3af 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); @@ -357,7 +357,7 @@ var qsmTimerInterval = []; // Calculates starting time. let timerStarted = localStorage.getItem('mlw_started_quiz' + quizID); - let timerConsumed = parseInt(localStorage.getItem('mlw_time_consumed_quiz' + quizID)); + var 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) { From bff2996ad4642199b26afdd5ab82b7914016df06 Mon Sep 17 00:00:00 2001 From: PranavAwasthi Date: Mon, 16 Sep 2024 11:43:03 +0530 Subject: [PATCH 04/49] Fixed sonar issue --- js/qsm-quiz.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/qsm-quiz.js b/js/qsm-quiz.js index 7bc31c3af..7ec401320 100644 --- a/js/qsm-quiz.js +++ b/js/qsm-quiz.js @@ -357,7 +357,7 @@ var qsmTimerInterval = []; // Calculates starting time. let timerStarted = localStorage.getItem('mlw_started_quiz' + quizID); - var timerConsumed = parseInt(localStorage.getItem('mlw_time_consumed_quiz' + quizID)) || 1; + 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) { From 97e55cebeba83a51afad79be97a4116cfe742e1d Mon Sep 17 00:00:00 2001 From: Mohammad Zubair Ali Date: Mon, 23 Sep 2024 13:45:15 +0530 Subject: [PATCH 05/49] update set cookie logic --- php/classes/class-qmn-quiz-manager.php | 30 +++++++++++++++++++------- php/template-variables.php | 2 +- 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/php/classes/class-qmn-quiz-manager.php b/php/classes/class-qmn-quiz-manager.php index 0bfc86ef6..1b84e7f71 100644 --- a/php/classes/class-qmn-quiz-manager.php +++ b/php/classes/class-qmn-quiz-manager.php @@ -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 ]) && + ! empty( $quiz_options->question_from_total ) + ) { + $question_ids = array(); + foreach ( $questions as $question ) { + $question_ids[] = $question->question_id; + } + + $question_sql = implode(',', array_unique($question_ids)); // Prevent duplicates + ?> + + 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)); From 4922f865f64a583d6b7d551f5e4d15ca3809947c Mon Sep 17 00:00:00 2001 From: Mohammad Zubair Ali Date: Mon, 23 Sep 2024 15:36:53 +0530 Subject: [PATCH 06/49] fixed issue with random order --- php/classes/class-qmn-quiz-manager.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/php/classes/class-qmn-quiz-manager.php b/php/classes/class-qmn-quiz-manager.php index 1b84e7f71..7ffcadd29 100644 --- a/php/classes/class-qmn-quiz-manager.php +++ b/php/classes/class-qmn-quiz-manager.php @@ -976,8 +976,7 @@ public function load_questions( $quiz_id, $quiz_options, $is_quiz_page, $questio in_array( intval( $quiz_options->randomness_order ), [ 1, 2 ], true) && ! empty($questions) && is_array($questions) && - ! isset($_COOKIE[ 'question_ids_' . $quiz_id ]) && - ! empty( $quiz_options->question_from_total ) + ! isset($_COOKIE[ 'question_ids_' . $quiz_id ]) ) { $question_ids = array(); foreach ( $questions as $question ) { From be628fa7f433667f893c89dab27b31d1a8fcd270 Mon Sep 17 00:00:00 2001 From: etchirag Date: Tue, 24 Sep 2024 16:06:03 +0530 Subject: [PATCH 07/49] Respove the other files code --- js/qsm-quiz.js | 4 ++-- php/classes/class-qmn-quiz-manager.php | 29 +++++++++++++++++++------- readme.txt | 1 - 3 files changed, 23 insertions(+), 11 deletions(-) diff --git a/js/qsm-quiz.js b/js/qsm-quiz.js index 89c3611eb..7ec401320 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); @@ -357,7 +357,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/php/classes/class-qmn-quiz-manager.php b/php/classes/class-qmn-quiz-manager.php index 6dfecc3b4..8d93dff8a 100644 --- a/php/classes/class-qmn-quiz-manager.php +++ b/php/classes/class-qmn-quiz-manager.php @@ -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 + ?> + + Date: Tue, 24 Sep 2024 16:07:33 +0530 Subject: [PATCH 08/49] Minor changes to resolve other file change --- php/classes/class-qmn-quiz-manager.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php/classes/class-qmn-quiz-manager.php b/php/classes/class-qmn-quiz-manager.php index 8d93dff8a..7ffcadd29 100644 --- a/php/classes/class-qmn-quiz-manager.php +++ b/php/classes/class-qmn-quiz-manager.php @@ -2417,8 +2417,8 @@ public static function check_answers( $options, $quiz_data ) { $results_array = apply_filters( 'qmn_results_array', $results_array, $question ); // If question was graded correctly. if ( ! isset( $results_array['null_review'] ) ) { - $points_earned += isset($results_array['points']) ? (float)$results_array['points'] : 0; - $answer_points += isset($results_array['points']) ? (float)$results_array['points'] : 0; + $points_earned += (float)$results_array['points']; + $answer_points += (float)$results_array['points']; // If the user's answer was correct. if ( isset( $results_array['correct'] ) && ( 'correct' == $results_array['correct'] ) ) { $total_correct += 1; From 9a4ab5df58cd860c68e67106a2d7f00eeecf9de6 Mon Sep 17 00:00:00 2001 From: PranavAwasthi Date: Wed, 25 Sep 2024 10:09:09 +0530 Subject: [PATCH 09/49] User permissions related code changes --- mlw_quizmaster2.php | 145 ++++++++++++++++++----- php/admin/admin-results-details-page.php | 11 +- php/admin/admin-results-page.php | 2 +- php/admin/quiz-options-page.php | 28 ++--- php/admin/quizzes-page.php | 29 +++-- php/admin/settings-page.php | 3 +- php/classes/class-qmn-log-manager.php | 2 +- php/classes/class-qmn-quiz-creator.php | 4 +- 8 files changed, 163 insertions(+), 61 deletions(-) diff --git a/mlw_quizmaster2.php b/mlw_quizmaster2.php index 691737e9c..a58d29905 100644 --- a/mlw_quizmaster2.php +++ b/mlw_quizmaster2.php @@ -346,6 +346,7 @@ private function load_dependencies() { */ private function add_hooks() { add_action( 'admin_menu', array( $this, 'setup_admin_menu' ) ); + add_action( 'admin_init', array( $this, 'qsm_add_user_capabilities' ) ); 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']) ) { @@ -652,6 +653,28 @@ 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', + 'manage_categories' => 'manage_qsm_quiz_categories', + 'manage_categories' => 'manage_qsm_quiz_answer_label', + 'moderate_comments' => 'view_qsm_quiz_result', ); // Registers post type. @@ -686,6 +709,73 @@ public function register_quiz_post_types() { register_taxonomy( 'qsm_category', array( 'qsm-taxonomy' ), $taxonomy_args ); } + public function qsm_add_user_capabilities() { + $default_capabilities = array( + 'administrator' => array( + 'edit_qsm_quiz', + 'duplicate_qsm_quiz', + 'read_qsm_quiz', + 'delete_qsm_quiz', + 'edit_qsm_quizzes', + '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', + 'create_qsm_quizzes', + 'manage_qsm_quiz_categories', + 'manage_qsm_quiz_answer_label', + 'view_qsm_quiz_result' + ), + 'editor' => array( + 'edit_qsm_quiz', + 'read_qsm_quiz', + 'edit_qsm_quizzes', + 'publish_qsm_quizzes', + 'edit_published_qsm_quizzes', + 'delete_published_qsm_quizzes', + 'delete_qsm_quiz', + 'delete_qsm_quizzes', + 'create_qsm_quizzes' + ), + 'author' => array( + 'read_qsm_quiz', + 'edit_qsm_quiz', + 'edit_qsm_quizzes', + 'create_qsm_quizzes', + 'edit_published_qsm_quizzes', + 'publish_qsm_quizzes' + ), + 'contributor' => array( + 'read_qsm_quiz', + 'edit_qsm_quiz', + 'edit_qsm_quizzes', + 'read_private_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 ($default_capabilities['administrator'] as $cap) { + $role->remove_cap($cap); + } + // Then add capabilities based on the current user role + if (isset($default_capabilities[$rolename])) { + foreach ($default_capabilities[$rolename] as $cap) { + $role->add_cap($cap); + } + } + do_action('qsm_add_user_capabilities_after'); + } + public function parent_file( $file_name ) { global $menu, $submenu, $parent_file, $submenu_file; if ( 'edit-tags.php?taxonomy=qsm_category' === $submenu_file ) { @@ -729,44 +819,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' + ); + + $qsm_dashboard_page = 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' ); + $qsm_taxonomy_menu_hook = 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..9601c17d9 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,11 @@ 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( "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_qsm_quiz', $quiz_post_id ) ) { + return; + } + //Get the data for comments $quiz_options = $mlwQuizMasterNext->quiz_settings->get_setting( 'quiz_options'); $comments_enabled = $quiz_options['comment_section']; @@ -138,6 +143,10 @@ function qsm_generate_results_details_tab() { 'result_id' => $result_id, 'results' => $results, ) ); + echo '
';
+    print_r($results_array);
+    echo '
'; + die; //convert to preferred date format $results_array = $mlwQuizMasterNext->pluginHelper->convert_to_preferred_date_format($results_array); diff --git a/php/admin/admin-results-page.php b/php/admin/admin-results-page.php index 3653acd1a..e9f7aa877 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; } diff --git a/php/admin/quiz-options-page.php b/php/admin/quiz-options-page.php index df060040b..db7eecc19 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 ) ); + //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 ) ) { + 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..db611d560 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 ) ) { + $actions['edit'] = '' . esc_html__( 'Edit', 'quiz-master-next' ) . ''; + } + if ( current_user_can( 'duplicate_qsm_quiz', $post->ID ) ) { + $actions['duplicate'] = '' . esc_html__( 'Duplicate', 'quiz-master-next' ) . ''; + } + if ( current_user_can( 'delete_published_qsm_quizzes' ) ) { + $actions['delete'] = '' . esc_html__( 'Delete', 'quiz-master-next' ) . ''; + } + if ( current_user_can( 'view_qsm_quiz_result' ) ) { + $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..2a17e95dd 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 ) ) { $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; } From 346a6b6c95e02d49cb4f38df9a820eab53c9e99b Mon Sep 17 00:00:00 2001 From: PranavAwasthi Date: Wed, 25 Sep 2024 10:15:52 +0530 Subject: [PATCH 10/49] removed print_r --- php/admin/admin-results-details-page.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/php/admin/admin-results-details-page.php b/php/admin/admin-results-details-page.php index 9601c17d9..25e11a90f 100644 --- a/php/admin/admin-results-details-page.php +++ b/php/admin/admin-results-details-page.php @@ -143,10 +143,6 @@ function qsm_generate_results_details_tab() { 'result_id' => $result_id, 'results' => $results, ) ); - echo '
';
-    print_r($results_array);
-    echo '
'; - die; //convert to preferred date format $results_array = $mlwQuizMasterNext->pluginHelper->convert_to_preferred_date_format($results_array); From 160cd355a483a2567cfac1dcf83dbb5422a6f1e0 Mon Sep 17 00:00:00 2001 From: PranavAwasthi Date: Wed, 25 Sep 2024 10:21:37 +0530 Subject: [PATCH 11/49] removed not needed default capability --- mlw_quizmaster2.php | 1 - 1 file changed, 1 deletion(-) diff --git a/mlw_quizmaster2.php b/mlw_quizmaster2.php index a3adaa1a8..41788bfc0 100644 --- a/mlw_quizmaster2.php +++ b/mlw_quizmaster2.php @@ -754,7 +754,6 @@ public function qsm_add_user_capabilities() { 'read_qsm_quiz', 'edit_qsm_quiz', 'edit_qsm_quizzes', - 'read_private_qsm_quizzes', 'create_qsm_quizzes' ) ); From 34dda275d11c5d46557c7a3bac5f3afe66195466 Mon Sep 17 00:00:00 2001 From: PranavAwasthi Date: Wed, 25 Sep 2024 11:22:47 +0530 Subject: [PATCH 12/49] split default capability along filter --- mlw_quizmaster2.php | 89 +++++++++++++++++++-------------------------- 1 file changed, 37 insertions(+), 52 deletions(-) diff --git a/mlw_quizmaster2.php b/mlw_quizmaster2.php index 41788bfc0..3deeb987c 100644 --- a/mlw_quizmaster2.php +++ b/mlw_quizmaster2.php @@ -710,69 +710,54 @@ public function register_quiz_post_types() { } public function qsm_add_user_capabilities() { - $default_capabilities = array( - 'administrator' => array( - 'edit_qsm_quiz', - 'duplicate_qsm_quiz', - 'read_qsm_quiz', - 'delete_qsm_quiz', - 'edit_qsm_quizzes', - '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', - 'create_qsm_quizzes', - 'manage_qsm_quiz_categories', - 'manage_qsm_quiz_answer_label', - 'view_qsm_quiz_result' - ), - 'editor' => array( - 'edit_qsm_quiz', - 'read_qsm_quiz', - 'edit_qsm_quizzes', - 'publish_qsm_quizzes', - 'edit_published_qsm_quizzes', - 'delete_published_qsm_quizzes', - 'delete_qsm_quiz', - 'delete_qsm_quizzes', - 'create_qsm_quizzes' - ), - 'author' => array( - 'read_qsm_quiz', - 'edit_qsm_quiz', - 'edit_qsm_quizzes', - 'create_qsm_quizzes', - 'edit_published_qsm_quizzes', - 'publish_qsm_quizzes' - ), - 'contributor' => array( - 'read_qsm_quiz', - 'edit_qsm_quiz', - 'edit_qsm_quizzes', - 'create_qsm_quizzes' - ) - ); + $qsm_common_capabilities = ['read_qsm_quiz', 'edit_qsm_quiz', 'edit_qsm_quizzes', 'create_qsm_quizzes']; + $administrator_capabilities = apply_filters( 'qsm_default_user_capabilities', array_merge($qsm_common_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' + )) ); + $editor_capabilities = apply_filters( 'qsm_default_user_capabilities', array_merge($qsm_common_capabilities, array( + 'publish_qsm_quizzes', + 'edit_published_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' + )) ); + $author_capabilities = apply_filters( 'qsm_default_user_capabilities', array_merge($qsm_common_capabilities, array( + 'edit_published_qsm_quizzes', + 'publish_qsm_quizzes' + )) ); + $contributor_capabilities = apply_filters( 'qsm_default_user_capabilities', $qsm_common_capabilities ); $user = wp_get_current_user(); $roles = (array) $user->roles; $rolename = $roles[0]; $role = get_role($rolename); // Remove all capabilities first - foreach ($default_capabilities['administrator'] as $cap) { + foreach ($administrator_capabilities as $cap) { $role->remove_cap($cap); } - // Then add capabilities based on the current user role - if (isset($default_capabilities[$rolename])) { - foreach ($default_capabilities[$rolename] as $cap) { + // Dynamically determine the capabilities to add based on the current user role + $capabilities_to_add = ${$rolename . '_capabilities'}; + if (isset($capabilities_to_add)) { + foreach ($capabilities_to_add as $cap) { $role->add_cap($cap); } } - do_action('qsm_add_user_capabilities_after'); } public function parent_file( $file_name ) { From 0df89249ab2e76a070003698d9e9b24561b177b4 Mon Sep 17 00:00:00 2001 From: PranavAwasthi Date: Wed, 25 Sep 2024 11:37:21 +0530 Subject: [PATCH 13/49] added filter for default capabilities --- mlw_quizmaster2.php | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/mlw_quizmaster2.php b/mlw_quizmaster2.php index 3deeb987c..80b1ad45d 100644 --- a/mlw_quizmaster2.php +++ b/mlw_quizmaster2.php @@ -710,8 +710,7 @@ public function register_quiz_post_types() { } public function qsm_add_user_capabilities() { - $qsm_common_capabilities = ['read_qsm_quiz', 'edit_qsm_quiz', 'edit_qsm_quizzes', 'create_qsm_quizzes']; - $administrator_capabilities = apply_filters( 'qsm_default_user_capabilities', array_merge($qsm_common_capabilities, array( + $administrator_capabilities = array( 'duplicate_qsm_quiz', 'delete_qsm_quiz', 'edit_others_qsm_quizzes', @@ -726,8 +725,8 @@ public function qsm_add_user_capabilities() { 'manage_qsm_quiz_categories', 'manage_qsm_quiz_answer_label', 'view_qsm_quiz_result' - )) ); - $editor_capabilities = apply_filters( 'qsm_default_user_capabilities', array_merge($qsm_common_capabilities, array( + ); + $editor_capabilities = array( 'publish_qsm_quizzes', 'edit_published_qsm_quizzes', 'delete_published_qsm_quizzes', @@ -736,16 +735,21 @@ public function qsm_add_user_capabilities() { 'manage_qsm_quiz_categories', 'manage_qsm_quiz_answer_label', 'view_qsm_quiz_result' - )) ); - $author_capabilities = apply_filters( 'qsm_default_user_capabilities', array_merge($qsm_common_capabilities, array( + ); + $author_capabilities = [ 'edit_published_qsm_quizzes', 'publish_qsm_quizzes' - )) ); - $contributor_capabilities = apply_filters( 'qsm_default_user_capabilities', $qsm_common_capabilities ); + ]; + $contributor_capabilities = [ + '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) { @@ -753,6 +757,7 @@ public function qsm_add_user_capabilities() { } // Dynamically determine the capabilities to add based on the current user role $capabilities_to_add = ${$rolename . '_capabilities'}; + $capabilities_to_add = apply_filters('qsm_default_user_capabilities', array_unique(array_merge($capabilities_to_add, $contributor_capabilities))); if (isset($capabilities_to_add)) { foreach ($capabilities_to_add as $cap) { $role->add_cap($cap); From a45f1e3a902e3c23c4b85e1f2187fba7e5920d5b Mon Sep 17 00:00:00 2001 From: PranavAwasthi Date: Wed, 25 Sep 2024 11:57:52 +0530 Subject: [PATCH 14/49] added a variable to filter --- mlw_quizmaster2.php | 48 ++++++++++++++++++++++++++------------------- 1 file changed, 28 insertions(+), 20 deletions(-) diff --git a/mlw_quizmaster2.php b/mlw_quizmaster2.php index 80b1ad45d..94536767c 100644 --- a/mlw_quizmaster2.php +++ b/mlw_quizmaster2.php @@ -724,7 +724,7 @@ public function qsm_add_user_capabilities() { 'edit_published_qsm_quizzes', 'manage_qsm_quiz_categories', 'manage_qsm_quiz_answer_label', - 'view_qsm_quiz_result' + 'view_qsm_quiz_result', ); $editor_capabilities = array( 'publish_qsm_quizzes', @@ -734,33 +734,41 @@ public function qsm_add_user_capabilities() { 'delete_qsm_quizzes', 'manage_qsm_quiz_categories', 'manage_qsm_quiz_answer_label', - 'view_qsm_quiz_result' + 'view_qsm_quiz_result', ); - $author_capabilities = [ + $author_capabilities = array( 'edit_published_qsm_quizzes', - 'publish_qsm_quizzes' - ]; - $contributor_capabilities = [ + '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; + '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) { - $role->remove_cap($cap); + + $role = get_role( $rolename ); + + // Remove all capabilities first. + foreach ( $administrator_capabilities as $cap ) { + $role->remove_cap( $cap ); } - // Dynamically determine the capabilities to add based on the current user role + + // Dynamically determine the capabilities to add based on the current user role. $capabilities_to_add = ${$rolename . '_capabilities'}; - $capabilities_to_add = apply_filters('qsm_default_user_capabilities', array_unique(array_merge($capabilities_to_add, $contributor_capabilities))); - if (isset($capabilities_to_add)) { - foreach ($capabilities_to_add as $cap) { - $role->add_cap($cap); + $capabilities_to_add = apply_filters( + 'qsm_default_user_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 ); } } } From e11036a09318b73e739a2bd365b65da1a62d18d0 Mon Sep 17 00:00:00 2001 From: PranavAwasthi Date: Wed, 25 Sep 2024 12:14:26 +0530 Subject: [PATCH 15/49] fix subscriber role --- mlw_quizmaster2.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/mlw_quizmaster2.php b/mlw_quizmaster2.php index 94536767c..687da91ed 100644 --- a/mlw_quizmaster2.php +++ b/mlw_quizmaster2.php @@ -759,10 +759,10 @@ public function qsm_add_user_capabilities() { } // Dynamically determine the capabilities to add based on the current user role. - $capabilities_to_add = ${$rolename . '_capabilities'}; + $capabilities_to_add = 'subscriber' !== $rolename ? ${$rolename . '_capabilities'} : []; $capabilities_to_add = apply_filters( 'qsm_default_user_capabilities', - array_unique( array_merge( $capabilities_to_add, $contributor_capabilities ) ), + 'subscriber' !== $rolename ? array_unique( array_merge( $capabilities_to_add, $contributor_capabilities ) ) : [], $user ); @@ -828,10 +828,10 @@ public function setup_admin_menu() { 'view_qsm_quiz_result' ); - $qsm_dashboard_page = add_menu_page( 'Quiz And Survey Master', __( 'QSM', 'quiz-master-next' ), $capabilities[1], 'qsm_dashboard', 'qsm_generate_dashboard_page', 'dashicons-feedback', $menu_position ); + 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' ), $capabilities[3], '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' ), $capabilities[4], 'qsm-answer-label', 'qsm_advanced_assessment_quiz_page_content', 3 ); From 60b3e81b485d10e93ee1e067cb568bc9f1d6ac6c Mon Sep 17 00:00:00 2001 From: PranavAwasthi Date: Wed, 25 Sep 2024 12:34:35 +0530 Subject: [PATCH 16/49] fixed some conditions --- mlw_quizmaster2.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mlw_quizmaster2.php b/mlw_quizmaster2.php index 687da91ed..572f2a1f6 100644 --- a/mlw_quizmaster2.php +++ b/mlw_quizmaster2.php @@ -759,10 +759,10 @@ public function qsm_add_user_capabilities() { } // Dynamically determine the capabilities to add based on the current user role. - $capabilities_to_add = 'subscriber' !== $rolename ? ${$rolename . '_capabilities'} : []; + $capabilities_to_add = isset(${$rolename . '_capabilities'}) ? ${$rolename . '_capabilities'} : array(); $capabilities_to_add = apply_filters( 'qsm_default_user_capabilities', - 'subscriber' !== $rolename ? array_unique( array_merge( $capabilities_to_add, $contributor_capabilities ) ) : [], + isset(${$rolename . '_capabilities'}) ? array_unique( array_merge( $capabilities_to_add, $contributor_capabilities ) ) : [], $user ); From 968cf0aea3f46a74277d3ce909bbc6e540085e19 Mon Sep 17 00:00:00 2001 From: PranavAwasthi Date: Wed, 25 Sep 2024 16:27:38 +0530 Subject: [PATCH 17/49] Fixed quiz links --- php/admin/admin-results-details-page.php | 5 +++-- php/admin/quizzes-page.php | 8 ++++---- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/php/admin/admin-results-details-page.php b/php/admin/admin-results-details-page.php index 25e11a90f..f4ff9b53b 100644 --- a/php/admin/admin-results-details-page.php +++ b/php/admin/admin-results-details-page.php @@ -69,8 +69,9 @@ 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( "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_qsm_quiz', $quiz_post_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 ); + if ( ( current_user_can( 'view_qsm_quiz_result' ) && $post_author == get_current_user_id() ) || ! current_user_can( 'edit_others_qsm_quizzes' ) ) { return; } diff --git a/php/admin/quizzes-page.php b/php/admin/quizzes-page.php index db611d560..f587b69ae 100644 --- a/php/admin/quizzes-page.php +++ b/php/admin/quizzes-page.php @@ -180,16 +180,16 @@ public function qsm_post_row_actions( $actions, $post ) { $quiz_id = get_post_meta( $post->ID, 'quiz_id', true ); if ( ! empty( $quiz_id ) ) { $actions = array(); - if ( current_user_can( 'edit_qsm_quiz', $post->ID ) ) { + if ( ( current_user_can( 'edit_qsm_quiz', $post->ID ) && $post->post_author == get_current_user_id() ) || current_user_can( 'edit_others_qsm_quizzes' ) ) { $actions['edit'] = '' . esc_html__( 'Edit', 'quiz-master-next' ) . ''; } - if ( current_user_can( 'duplicate_qsm_quiz', $post->ID ) ) { + if ( ( current_user_can( 'duplicate_qsm_quiz', $post->ID ) && $post->post_author == get_current_user_id() ) || current_user_can( 'edit_others_qsm_quizzes' ) ) { $actions['duplicate'] = '' . esc_html__( 'Duplicate', 'quiz-master-next' ) . ''; } - if ( current_user_can( 'delete_published_qsm_quizzes' ) ) { + if ( ( current_user_can( 'delete_qsm_quiz', $post->ID ) && $post->post_author == get_current_user_id() ) || current_user_can( 'delete_others_qsm_quizzes' ) ) { $actions['delete'] = '' . esc_html__( 'Delete', 'quiz-master-next' ) . ''; } - if ( current_user_can( 'view_qsm_quiz_result' ) ) { + if ( ( current_user_can( 'view_qsm_quiz_result' ) && $post->post_author == get_current_user_id() ) || current_user_can( 'edit_others_qsm_quizzes' ) ) { $actions['view_result'] = '' . esc_html__( 'View Results', 'quiz-master-next' ) . ''; } if ( empty( $settings['disable_quiz_public_link'] ) ) { From cc43606a959f70a2a86d7050e4872da24ab8740f Mon Sep 17 00:00:00 2001 From: PranavAwasthi Date: Wed, 25 Sep 2024 19:26:04 +0530 Subject: [PATCH 18/49] fixed result page view permissions --- php/admin/admin-results-details-page.php | 4 ++-- php/admin/admin-results-page.php | 15 ++++++++++++++- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/php/admin/admin-results-details-page.php b/php/admin/admin-results-details-page.php index f4ff9b53b..3cf53169f 100644 --- a/php/admin/admin-results-details-page.php +++ b/php/admin/admin-results-details-page.php @@ -70,8 +70,8 @@ function qsm_generate_results_details_tab() { $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 ); - if ( ( current_user_can( 'view_qsm_quiz_result' ) && $post_author == get_current_user_id() ) || ! current_user_can( 'edit_others_qsm_quizzes' ) ) { + $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( 'edit_others_qsm_quizzes' ) ) { return; } diff --git a/php/admin/admin-results-page.php b/php/admin/admin-results-page.php index e9f7aa877..d0afd9db9 100644 --- a/php/admin/admin-results-page.php +++ b/php/admin/admin-results-page.php @@ -524,7 +524,20 @@ function qsm_results_overview_tab_content() { ?> - quiz_name ); ?>
| |
+ + quiz_name ); ?> +
+ + user == get_current_user_id() ) || current_user_can( 'edit_others_qsm_quizzes' ) ) { + ?> + | + + | + + +
+ $v ) { if ( isset( $v['content'][ $x ] ) ) { From 6c2bf39f6705cbc4566753a8a0c7a150df5b823c Mon Sep 17 00:00:00 2001 From: Mohammad Zubair Ali Date: Thu, 26 Sep 2024 18:54:21 +0530 Subject: [PATCH 19/49] added filter hook to update max and min points --- mlw_quizmaster2.php | 38 +++++++++++++------------- php/classes/class-qmn-quiz-manager.php | 6 ++-- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/mlw_quizmaster2.php b/mlw_quizmaster2.php index 572f2a1f6..d94271979 100644 --- a/mlw_quizmaster2.php +++ b/mlw_quizmaster2.php @@ -657,24 +657,24 @@ public function register_quiz_post_types() { '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', - 'manage_categories' => 'manage_qsm_quiz_categories', - 'manage_categories' => 'manage_qsm_quiz_answer_label', - 'moderate_comments' => 'view_qsm_quiz_result', + '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', + 'manage_categories' => 'manage_qsm_quiz_categories', + 'manage_categories' => 'manage_qsm_quiz_answer_label', + 'moderate_comments' => 'view_qsm_quiz_result', ); // Registers post type. @@ -825,7 +825,7 @@ public function setup_admin_menu() { 'delete_others_qsm_quizzes', 'manage_qsm_quiz_categories', 'manage_qsm_quiz_answer_label', - 'view_qsm_quiz_result' + '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 ); diff --git a/php/classes/class-qmn-quiz-manager.php b/php/classes/class-qmn-quiz-manager.php index 7ffcadd29..8432fd699 100644 --- a/php/classes/class-qmn-quiz-manager.php +++ b/php/classes/class-qmn-quiz-manager.php @@ -2566,7 +2566,7 @@ public static function qsm_max_min_points( $options, $question ) { $question_required = ( 0 === maybe_unserialize( $question['question_settings'] )['required'] ); $multi_response = ( '4' === $question_type || '10' === $question_type || '14' === $question_type ); - return self::qsm_max_min_points_conditions( $max_value_array, $min_value_array, $question_required, $multi_response ); + return self::qsm_max_min_points_conditions( $max_value_array, $min_value_array, $question_required, $multi_response, $question ); } /** @@ -2579,7 +2579,7 @@ public static function qsm_max_min_points( $options, $question ) { * @param array $multi_response * @return string $max_min_result */ - public static function qsm_max_min_points_conditions( $max_value_array, $min_value_array, $question_required, $multi_response ) { + public static function qsm_max_min_points_conditions( $max_value_array, $min_value_array, $question_required, $multi_response, $question ) { $max_min_result = array( 'max_point' => 0, 'min_point' => 0, @@ -2627,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 ); } /** From 9b0e9d663559e76a56e5f8ae357682d21ee62e8b Mon Sep 17 00:00:00 2001 From: manandeep singh Date: Fri, 27 Sep 2024 17:21:39 +0530 Subject: [PATCH 20/49] Resolve warning issue in %TIME_FINISHED% variable --- php/template-variables.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/template-variables.php b/php/template-variables.php index 114b4c9a2..8a5cfece4 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; } From e8901de361ba34959256ad64a0691b7ad1ce970f Mon Sep 17 00:00:00 2001 From: PranavAwasthi Date: Fri, 27 Sep 2024 18:59:52 +0530 Subject: [PATCH 21/49] Fixed page access from url parameter changing --- php/admin/quiz-options-page.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php/admin/quiz-options-page.php b/php/admin/quiz-options-page.php index db7eecc19..8f81d03d8 100644 --- a/php/admin/quiz-options-page.php +++ b/php/admin/quiz-options-page.php @@ -20,12 +20,12 @@ function qsm_generate_quiz_options() { 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 if the current user has the capability to edit the quiz. - if ( ! current_user_can( 'edit_qsm_quiz', $quiz_post_id ) ) { + 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; } From bb99a5bb4a9cf533aab29a4f0cb42f3dcde6d5b9 Mon Sep 17 00:00:00 2001 From: etchirag Date: Mon, 30 Sep 2024 09:53:45 +0530 Subject: [PATCH 22/49] Added support for linking the questions --- css/qsm-admin-question.css | 4 +- css/qsm-admin.css | 86 +++++++++++++ js/qsm-admin.js | 89 ++++++++++++-- mlw_quizmaster2.php | 7 +- php/admin/options-page-questions-tab.php | 149 ++++++++++++++++++++++- php/classes/class-qsm-install.php | 11 +- php/classes/class-qsm-questions.php | 111 ++++++++++++----- php/rest-api.php | 44 ++++++- php/template-variables.php | 2 +- 9 files changed, 448 insertions(+), 55 deletions(-) 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..27b9e338b 100644 --- a/css/qsm-admin.css +++ b/css/qsm-admin.css @@ -1458,6 +1458,92 @@ td.scheduled_time_start { background: #fff; box-sizing: border-box; } + +#post-body-content .qsm-popup-upgrade-warning img { + width: auto; + height: 15px; + margin-right: 8px; +} + +.qsm-linked-list-div-block { + padding: 4px; + margin: 5px 0; + margin-top: -20px; + width: max-content; + background-color: #ffe684; + border-radius: 2px; +} + +span.qsm-linked-list-view-button { + cursor: pointer; + color: #135e96; + text-decoration: underline; + font-weight: 500; +} + +span.qsm-linked-list-item { + margin: 0 0 5px 0; + padding: 5px; + background: #f0f0f1; +} + +div.qsm-linked-list-inside a.qsm-unlink-the-question { + color: #DC3232; + font-weight: 500; + max-width: 60px; +} + +.qsm-linked-list-div-block p { + margin: 0; + font-size: 13px; + color: #856404; +} + +.qsm-linked-list-container { + position: absolute; +} + +.qsm-linked-list-div-block .qsm-linked-list-inside { + position: relative; + right: -155px; + top: 20px; + z-index: 999; + width: 350px; + padding: 10px; + box-sizing: border-box; + border-radius: 4px; + background: #ffffff; + border: 1px solid #dfd4d4; + box-shadow: 0 0 6px 2px #ddd; + display: grid; + grid-template-columns: 1fr; +} + +.qsm-linked-list-div-block .qsm-linked-list-inside:before { + content: " "; + position: absolute; + top: -24px; + left: 28%; + margin-left: -12px; + border-width: 12px; + border-style: solid; + border-color: transparent transparent #ffffff transparent; + z-index: 1; +} + +.qsm-linked-list-div-block .qsm-linked-list-inside:after { + content: " "; + position: absolute; + top: -26px; + left: 28%; + margin-left: -12px; + border-width: 12px; + border-style: solid; + border-color: transparent transparent #dfd4d4 transparent; + z-index: 0; +} + + .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..9c75581da 100644 --- a/js/qsm-admin.js +++ b/js/qsm-admin.js @@ -1899,6 +1899,7 @@ var QSMContact; */ var QSMQuestion; var import_button; +var qsm_link_button; (function ($) { if (jQuery('body').hasClass('admin_page_mlw_quiz_options')) { if (window.location.href.indexOf('&tab') == -1 || window.location.href.indexOf('tab=questions') > 0) { @@ -2041,13 +2042,15 @@ var import_button; type: question.type, question: questionText, category: question.category, - quiz_name: question.quiz_name + quiz_name: question.quiz_name, + linked_question: question.linked_question.join(',') })); }, - addQuestionFromQuestionBank: function (questionID) { + addQuestionFromQuestionBank: function (questionID, is_linking = 0) { QSMAdmin.displayAlert(qsm_admin_messages.adding_question, 'info'); var model = new QSMQuestion.question({ - id: questionID + id: questionID, + is_linking: is_linking == 1 ? questionID : 0, }); model.fetch({ headers: { @@ -2240,11 +2243,22 @@ 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 + ")"); + import_button ? import_button.html('').html(qsm_admin_messages.add_question) : ""; + if(qsm_link_button) { + qsm_link_button.html('').html(qsm_admin_messages.link_question); + } + // qsm_link_button ? qsm_link_button.html('').html(qsm_admin_messages.link_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')); + console.log(qsm_link_button); + if(qsm_link_button == ''){ + $(document).find('.qsm-linked-list-inside').hide().empty(); + $(document).find('.qsm-linked-list-div-block').hide(); + } // $('#save-popup-button').trigger('click'); }, addNewQuestion: function (model) { @@ -2780,6 +2794,33 @@ var import_button; $('#image_size_area').show(); } + let link_quizzes_array = question.get('link_quizzes'); + + $('.qsm-linked-list-inside').hide().empty(); + $('.qsm-linked-list-div-block').hide(); + if (typeof link_quizzes_array == 'object' && link_quizzes_array != null && Object.keys(link_quizzes_array).length > 0) { + Object.values(link_quizzes_array).forEach(function(quizName) { + // Ensure each quizName is a valid non-empty string + if (quizName && typeof quizName == 'string' && quizName.trim().length > 0) { + let link = $('') + .attr('href', 'javascript:void(0)') + .attr('class', 'qsm-linked-list-item') + .attr('title', quizName) + .text(quizName.length > 25 ? quizName.substring(0, 25) + '...' : quizName); + + $('.qsm-linked-list-div-block').show(); + $('.qsm-linked-list-inside').append(link); + } + }); + + // Add an "Unlink" link at the end + let unlink = $('') + .attr('href', 'javascript:void(0)') + .attr('class', 'qsm-unlink-the-question button button-danger') + .attr('data-question-id', questionID) + .text(qsm_admin_messages.unlink_question); + $('.qsm-linked-list-inside').append(unlink); + } jQuery(document).trigger('qsm_open_edit_popup', [questionID, CurrentElement]); }, openEditPagePopup: function (pageID) { @@ -3256,16 +3297,50 @@ var import_button; $(document).on('click', '.qsm-popup-bank .import-button', function (event) { event.preventDefault(); + qsm_link_button = ''; $(this).text('').text(qsm_admin_messages.adding_question); import_button = $(this); $('.import-button').addClass('disable_import'); QSMQuestion.addQuestionFromQuestionBank($(this).data('question-id')); - MicroModal.close('modal-2'); + // MicroModal.close('modal-2'); + }); + + + $(document).on('click', '.qsm-popup-bank .link-question', function (event) { + event.preventDefault(); + $(this).text('').text(qsm_admin_messages.linking_question); + qsm_link_button = $(this); + $('.link-question').addClass('disable_import'); + // 1 for the linking the questions default is 0 + QSMQuestion.addQuestionFromQuestionBank($(this).data('question-id'), 1); }); + jQuery(document).on('click', '.qsm-linked-list-div-block .qsm-linked-list-view-button', function () { + let $this = jQuery(this); + let $inside = $this.parents('.qsm-linked-list-div-block').find('.qsm-linked-list-inside'); + $inside.toggle(); + $inside.is(':visible') ? $this.text(qsmQuestionSettings.linked_close) : $this.text(qsmQuestionSettings.linked_view); + }); + + jQuery(document).on('click', '.qsm-linked-list-div-block .qsm-unlink-the-question', function () { + $.ajax({ + url: ajaxurl, + method: 'POST', + data: { + action: 'qsm_unlink_question_from_list', + question_id: jQuery(this).data('question-id'), + nonce: qsmQuestionSettings.unlinkNonce + }, + success: function (response) { + console.log(response); + $(document).find('.qsm-linked-list-div-block').remove(); + } + }); + }); //Click on selected question button. $('.qsm-popup-bank').on('click', '#qsm-import-selected-question', function (event) { var $total_selction = $('#question-bank').find('[name="qsm-question-checkbox[]"]:checked').length; + qsm_link_button = ''; if ($total_selction === 0) { alert(qsm_admin_messages.no_question_selected); } else { diff --git a/mlw_quizmaster2.php b/mlw_quizmaster2.php index b65eb8b09..c09ef50cd 100644 --- a/mlw_quizmaster2.php +++ b/mlw_quizmaster2.php @@ -524,10 +524,13 @@ 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'), + 'add_question' => __('Add', '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'), + 'unlink_question' => __('Unlink', 'quiz-master-next'), + 'adding_question' => __('Adding...', 'quiz-master-next'), + 'linking_question' => __('Linking...', 'quiz-master-next'), + 'link_question' => __('Link', 'quiz-master-next'), 'creating_question' => __('Creating question...', 'quiz-master-next'), 'duplicating_question' => __('Duplicating question...', 'quiz-master-next'), 'saving_question' => __('Saving question...', 'quiz-master-next'), diff --git a/php/admin/options-page-questions-tab.php b/php/admin/options-page-questions-tab.php index 33ceaa4fd..471ff67d2 100644 --- a/php/admin/options-page-questions-tab.php +++ b/php/admin/options-page-questions-tab.php @@ -88,11 +88,14 @@ function qsm_options_questions_tab_content() { $json_data = array( 'quizID' => $quiz_id, 'answerText' => __( 'Answer', 'quiz-master-next' ), + 'linked_view' => __( 'View', 'quiz-master-next' ), + 'linked_close' => __( 'Close', 'quiz-master-next' ), 'nonce' => wp_create_nonce( 'wp_rest' ), 'pages' => $pages, 'qpages' => $qpages, 'qsm_user_ve' => get_user_meta( $user_id, 'rich_editing', true ), 'saveNonce' => wp_create_nonce( 'ajax-nonce-sandy-page' ), + 'unlinkNonce' => wp_create_nonce( 'ajax-nonce-unlink-question' ), 'categories' => $question_categories, 'form_type' => $form_type, 'quiz_system' => $quiz_system, @@ -280,6 +283,12 @@ class="save-page-button button button-primary">
+
+

+
+
+
+
@@ -875,6 +884,80 @@ class="save-page-button button button-primary"> __( + 'Nonce verification failed.', + 'quiz-master-next' + ), + )); + } + $question_id = isset( $_POST['question_id'] ) ? intval( $_POST['question_id'] ) : 0; + if ( $question_id > 0 ) { + qsm_process_unlink_question_from_list_by_question_id($question_id); + wp_send_json_success( array( + 'message' => __( + 'Question is unlinked from all quizzes.', + 'quiz-master-next' + ), + )); + } else { + wp_send_json_error( array( + 'message' => __( + 'Invalid question ID.', + 'quiz-master-next' + ), + )); + } +} +add_action( 'wp_ajax_qsm_unlink_question_from_list', 'qsm_ajax_unlink_question_from_list' ); + +/** + * Unlinks a question from all quizzes it is associated with. + * @since 9.1.3 + * @param int $question_id The ID of the question to unlink. + * @return void + */ +function qsm_process_unlink_question_from_list_by_question_id( $question_id ) { + global $wpdb; + $current_linked_questions = $wpdb->get_var( $wpdb->prepare( + "SELECT linked_question FROM {$wpdb->prefix}mlw_questions WHERE question_id = %d", + $question_id + ) ); + + if ( $current_linked_questions ) { + $current_links = explode(',', $current_linked_questions); + $current_links = array_map('trim', $current_links); + $current_links = array_diff($current_links, [ $question_id ]); + $updated_linked_list = implode(',', array_filter($current_links)); + $linked_ids = explode(',', $updated_linked_list); + foreach ( $linked_ids as $linked_id ) { + $result = $wpdb->update( + $wpdb->prefix . 'mlw_questions', + array( 'linked_question' => $updated_linked_list ), + array( 'question_id' => intval($linked_id) ), + array( '%s' ), + array( '%d' ) + ); + } + $wpdb->update( + $wpdb->prefix . 'mlw_questions', + array( 'linked_question' => '' ), + array( 'question_id' => intval($question_id) ), + array( '%s' ), + array( '%d' ) + ); + } +} + /** * Saves the pages and order from the Questions tab * @@ -1093,7 +1176,21 @@ function qsm_delete_question_from_database() { $question_id = isset( $_POST['question_id'] ) ? intval( $_POST['question_id'] ) : 0; if ( $question_id ) { global $wpdb, $mlwQuizMasterNext; - $results = $wpdb->delete( $wpdb->prefix . 'mlw_questions', array( 'question_id' => $question_id ) ); + $dependent_question_ids = qsm_get_unique_linked_question_ids_to_remove(array( $question_id ) ); + $question_id = array_merge($dependent_question_ids, array( $question_id ) ); + $question_id = array_unique($question_id); + $question_id = array_filter($question_id); + $placeholders = array_fill( 0, count( $question_id ), '%d' ); + + // Construct the query with placeholders + $query = sprintf( + "DELETE FROM {$wpdb->prefix}mlw_questions WHERE question_id IN (%s)", + implode( ', ', $placeholders ) + ); + + // Prepare the query + $query = $wpdb->prepare( $query, $question_id ); + $results = $wpdb->query( $query ); if ( $results ) { wp_send_json_success( __( 'Question removed Successfully.', 'quiz-master-next' ) ); }else { @@ -1134,11 +1231,18 @@ function qsm_bulk_delete_question_from_database() { // Sanitize and validate the IDs $question_id = array_map( 'intval', $question_id ); - + if ( ! empty( $question_id ) ) { - // Generate placeholders for each ID - $placeholders = array_fill( 0, count( $question_id ), '%d' ); + global $wpdb; + + $dependent_question_ids = qsm_get_unique_linked_question_ids_to_remove($question_id); + + $question_id = array_merge($dependent_question_ids, $question_id); + $question_id = array_unique($question_id); // Ensure all IDs are unique + $question_id = array_filter($question_id); // Remove empty values + $placeholders = array_fill( 0, count( $question_id ), '%d' ); + // Construct the query with placeholders $query = sprintf( "DELETE FROM {$wpdb->prefix}mlw_questions WHERE question_id IN (%s)", @@ -1147,7 +1251,7 @@ function qsm_bulk_delete_question_from_database() { // Prepare the query $query = $wpdb->prepare( $query, $question_id ); - + $results = $wpdb->query( $query ); if ( $results ) { wp_send_json_success( __( 'Questions removed Successfully.', 'quiz-master-next' ) ); @@ -1161,6 +1265,36 @@ function qsm_bulk_delete_question_from_database() { } add_action( 'wp_ajax_qsm_bulk_delete_question_from_database', 'qsm_bulk_delete_question_from_database' ); + +/** + * Get Unique Linked Question IDs + * + * @param array $question_ids An array of question IDs to query for linked questions. + * @return array $unique_ids An array of unique question IDs extracted from the linked questions. + * @since 9.1.3 + */ +function qsm_get_unique_linked_question_ids_to_remove( $question_ids ) { + global $wpdb; + $current_linked_questions = array(); + foreach ( $question_ids as $id ) { + $sql = $wpdb->prepare( + "SELECT linked_question FROM {$wpdb->prefix}mlw_questions WHERE question_id = %d", + $id + ); + $linked_question = $wpdb->get_var($sql); + if ( ! empty($linked_question) ) { + $current_linked_questions[] = $linked_question; + } + } + $all_ids = array(); + foreach ( $current_linked_questions as $linked_questions ) { + if ( ! empty($linked_questions) ) { + $all_ids = array_merge($all_ids, explode(',', $linked_questions)); + } + } + return $all_ids; +} + add_action( 'wp_ajax_save_new_category', 'qsm_save_new_category' ); function qsm_save_new_category() { $category = isset( $_POST['name'] ) ? sanitize_text_field( wp_unslash( $_POST['name'] ) ) : ''; @@ -1240,7 +1374,10 @@ function qsm_options_questions_tab_template() {

{{{data.question}}}

Quiz Name: {{data.quiz_name}} <# if ( data.category != '' ) { #> Category: {{data.category}} <# } #>

-
+
+ + +
diff --git a/php/classes/class-qsm-install.php b/php/classes/class-qsm-install.php index 2e9918b53..5e13238e3 100644 --- a/php/classes/class-qsm-install.php +++ b/php/classes/class-qsm-install.php @@ -2038,7 +2038,16 @@ public function update() { } update_option( 'mlw_quiz_master_version', $data ); - } + + // Update 9.1.3 + $mlw_questions_table = $wpdb->prefix . 'mlw_questions'; + if ( 'linked_question' != $wpdb->get_var( "SHOW COLUMNS FROM $mlw_questions_table LIKE 'linked_question'" ) ) { + $sql = "ALTER TABLE $mlw_questions_table ADD linked_question TEXT NULL DEFAULT '' AFTER category"; + $results = $wpdb->query( $sql ); + $update_sql = "UPDATE $mlw_questions_table SET linked_question = '' WHERE linked_question IS NULL"; + $results = $wpdb->query( $update_sql ); + } +} if ( ! get_option( 'mlw_advert_shows' ) ) { add_option( 'mlw_advert_shows', 'true' ); } diff --git a/php/classes/class-qsm-questions.php b/php/classes/class-qsm-questions.php index 52f6441e5..27978d649 100644 --- a/php/classes/class-qsm-questions.php +++ b/php/classes/class-qsm-questions.php @@ -270,6 +270,7 @@ private static function create_save_question( $data, $answers, $settings, $is_cr 'order' => 1, 'category' => '', 'multicategories' => '', + 'linked_question' => '', ); $data = wp_parse_args( $data, $defaults ); @@ -297,6 +298,14 @@ private static function create_save_question( $data, $answers, $settings, $is_cr if ( $trim_question_description ) { $question_name = trim( preg_replace( '/\s+/', ' ', $question_name ) ); } + $linked_question = sanitize_text_field( $data['linked_question'] ); + if ( $is_creating && isset($data['is_linking']) ) { + if ( 1 <= $data['is_linking'] ) { + $linked_question = $data['is_linking']; + }elseif ( 0 == $data['is_linking'] ) { + $linked_question = ''; + } + } $values = array( 'quiz_id' => intval( $data['quiz_id'] ), @@ -309,10 +318,11 @@ private static function create_save_question( $data, $answers, $settings, $is_cr 'question_type_new' => sanitize_text_field( $data['type'] ), 'question_settings' => maybe_serialize( $settings ), 'category' => sanitize_text_field( $data['category'] ), + 'linked_question' => $linked_question, 'deleted' => 0, ); $values = apply_filters( 'qsm_save_question_data', $values ); - + $types = array( '%d', '%s', @@ -324,6 +334,7 @@ private static function create_save_question( $data, $answers, $settings, $is_cr '%s', '%s', '%s', + '%s', '%d', ); @@ -351,44 +362,78 @@ private static function create_save_question( $data, $answers, $settings, $is_cr throw new Exception( $msg ); } - /** - * Process Question Categories - */ + // echo"
";
+		// print_r($data);
+		// echo"
"; + $base_question_id = $question_id; + $quiz_questions_array = array(); + $quiz_questions_array[ intval( $data['quiz_id'] ) ] = $question_id; + $linked_questions_array[] = $question_id; + $imploded_question_ids = $question_id; + if ( isset($linked_question) && "" != $linked_question ) { + $expolded_question_array = explode(',', $linked_question); + $linked_questions_array = array_merge($expolded_question_array, $linked_questions_array); + // preparing array for quiz question id + $imploded_question_ids = implode( ',', array_unique($linked_questions_array) ); + if ( ! empty($linked_questions_array) ) { + $quiz_results = $wpdb->get_results( "SELECT `quiz_id`, `question_id` FROM `{$wpdb->prefix}mlw_questions` WHERE `question_id` IN (" . $imploded_question_ids . ")" ); + foreach ( $quiz_results as $key => $value ) { + $quiz_questions_array[ $value->quiz_id ] = $value->question_id; + } + } + $values['linked_question'] = $imploded_question_ids; + } $question_terms_table = $wpdb->prefix . 'mlw_question_terms'; - $wpdb->delete( - $question_terms_table, - array( - 'question_id' => $question_id, - 'taxonomy' => 'qsm_category', - ) - ); - if ( ! empty( $data['multicategories'] ) ) { - foreach ( $data['multicategories'] as $term_id ) { - $term_rel_data = array( - 'question_id' => $question_id, - 'quiz_id' => intval( $data['quiz_id'] ), - 'term_id' => $term_id, + foreach ( $quiz_questions_array as $quiz_id => $question_id_loop ) { + $values['quiz_id'] = intval( $quiz_id ); + $results = $wpdb->update( + $wpdb->prefix . 'mlw_questions', + $values, + array( 'question_id' => intval($question_id_loop) ), + $types, + array( '%d' ) + ); + + /** + * Process Question Categories + */ + + $wpdb->delete( + $question_terms_table, + array( + 'question_id' => $question_id_loop, 'taxonomy' => 'qsm_category', - ); - // Check if the data already exists in the table - $data_exists = $wpdb->get_row($wpdb->prepare("SELECT * FROM $question_terms_table WHERE question_id = %s AND quiz_id = %s AND term_id = %s AND taxonomy = %s", $question_id, intval( $data['quiz_id'] ), $term_id, 'qsm_category' )); - if ( ! $data_exists ) { - $wpdb->insert( $question_terms_table, $term_rel_data ); + ) + ); + if ( ! empty( $data['multicategories'] ) ) { + foreach ( $data['multicategories'] as $term_id ) { + $term_rel_data = array( + 'question_id' => $question_id_loop, + 'quiz_id' => intval( $quiz_id ), + 'term_id' => $term_id, + 'taxonomy' => 'qsm_category', + ); + // Check if the data already exists in the table + $data_exists = $wpdb->get_row($wpdb->prepare("SELECT * FROM $question_terms_table WHERE question_id = %s AND quiz_id = %s AND term_id = %s AND taxonomy = %s", $question_id_loop, intval( $quiz_id ), $term_id, 'qsm_category' )); + if ( ! $data_exists ) { + $wpdb->insert( $question_terms_table, $term_rel_data ); + } } } - } - /** - * Hook after saving question - */ - if ( $is_creating ) { - do_action( 'qsm_question_added', $question_id, $values ); - } else { - do_action( 'qsm_question_updated', $question_id, $values ); + /** + * Hook after saving question + */ + + if ( $is_creating && $base_question_id == $question_id_loop ) { + do_action( 'qsm_question_added', $question_id_loop, $values ); + } else { + do_action( 'qsm_question_updated', $question_id_loop, $values ); + } + do_action( 'qsm_saved_question', $question_id_loop, $values ); + } - do_action( 'qsm_saved_question', $question_id, $values ); - - return $question_id; + return $base_question_id; } /** diff --git a/php/rest-api.php b/php/rest-api.php index 0c924004e..0355f1d32 100644 --- a/php/rest-api.php +++ b/php/rest-api.php @@ -271,6 +271,7 @@ function qsm_rest_get_bank_questions( WP_REST_Request $request ) { 'file_upload_type' => isset( $question['settings']['file_upload_type'] ) ? $question['settings']['file_upload_type'] : '', 'quiz_name' => isset( $quiz_name['quiz_name'] ) ? $quiz_name['quiz_name'] : '', 'question_title' => isset( $question['settings']['question_title'] ) ? $question['settings']['question_title'] : '', + 'linked_question' => array_filter( isset( $question['linked_question'] ) ? explode(',', $question['linked_question']) : array() ), ); $question_data = apply_filters( 'qsm_rest_api_filter_question_data', $question_data, $question, $request ); $question_array['questions'][] = $question_data; @@ -487,11 +488,22 @@ function qsm_rest_save_results( WP_REST_Request $request ) { function qsm_rest_get_question( WP_REST_Request $request ) { // Makes sure user is logged in. if ( is_user_logged_in() ) { + global $wpdb; $current_user = wp_get_current_user(); if ( 0 !== $current_user ) { $question = QSM_Questions::load_question( $request['id'] ); $categorysArray = QSM_Questions::get_question_categories( $question['question_id'] ); if ( ! empty( $question ) ) { + $linked_question_ids = array_filter( isset( $question['linked_question'] ) ? explode(',', $question['linked_question']) : array() ); + $quiz_name_by_question = array(); + if ( ! empty($linked_question_ids) ) { + $quiz_results = $wpdb->get_results( "SELECT `quiz_id`, `question_id` FROM `{$wpdb->prefix}mlw_questions` WHERE `question_id` IN (" . implode( ',', $linked_question_ids ) . ")" ); + foreach ( $quiz_results as $key => $value ) { + $quiz_name_in_loop = $wpdb->get_row( $wpdb->prepare( "SELECT quiz_name FROM {$wpdb->prefix}mlw_quizzes WHERE quiz_id = %d", $value->quiz_id ), ARRAY_A ); + $quiz_name_in_loop = isset( $quiz_name_in_loop['quiz_name'] ) ? $quiz_name_in_loop['quiz_name'] : ''; + $quiz_name_by_question[] = $quiz_name_in_loop; + } + } $question['page'] = isset( $question['page'] ) ? $question['page'] : 0; $question = array( 'id' => $question['question_id'], @@ -508,6 +520,8 @@ function qsm_rest_get_question( WP_REST_Request $request ) { 'answers' => $question['answers'], 'page' => $question['page'], 'question_title' => isset( $question['settings']['question_title'] ) ? $question['settings']['question_title'] : '', + 'link_quizzes' => $quiz_name_by_question, + 'merged_question' => implode(",", $linked_question_ids), ); } return $question; @@ -538,12 +552,31 @@ function qsm_rest_get_questions( WP_REST_Request $request ) { $questions = QSM_Questions::load_questions( 0 ); } global $wpdb; - $question_array = array(); + $stored_quiz_names = $procesed_question_ids = $question_array = array(); foreach ( $questions as $question ) { $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'] ); - + $quiz_name = isset( $quiz_name['quiz_name'] ) ? $quiz_name['quiz_name'] : ''; + $quiz_name_by_question = array(); + $procesed_question_ids[] = $question['question_id']; + $stored_quiz_names[ $question['question_id'] ] = $quiz_name; + $linked_question_ids = array_filter( isset( $question['linked_question'] ) ? explode(',', $question['linked_question']) : array() ); + if ( ! empty($linked_question_ids) ) { + $quiz_results = $wpdb->get_results( "SELECT `quiz_id`, `question_id` FROM `{$wpdb->prefix}mlw_questions` WHERE `question_id` IN (" . implode( ',', $linked_question_ids ) . ")" ); + foreach ( $quiz_results as $key => $value ) { + if ( ! in_array($value->question_id, $procesed_question_ids) ) { + $quiz_name_in_loop = $wpdb->get_row( $wpdb->prepare( "SELECT quiz_name FROM {$wpdb->prefix}mlw_quizzes WHERE quiz_id = %d", $value->quiz_id ), ARRAY_A ); + $quiz_name_in_loop = isset( $quiz_name_in_loop['quiz_name'] ) ? $quiz_name_in_loop['quiz_name'] : ''; + $quiz_name_by_question[] = $quiz_name_in_loop; + $procesed_question_ids[] = $value->question_id; + $stored_quiz_names[ $value->question_id ] = $quiz_name_in_loop; + } else { + $quiz_name_by_question[] = $stored_quiz_names[ $value->question_id ]; + } + } + } + $quiz_name_by_question = array_diff($quiz_name_by_question, [ $quiz_name ]); // remove current quiz id from the list $question_data = array( 'id' => $question['question_id'], 'quizID' => $question['quiz_id'], @@ -566,11 +599,13 @@ function qsm_rest_get_questions( WP_REST_Request $request ) { 'limit_multiple_response' => isset( $question['settings']['limit_multiple_response'] ) ? $question['settings']['limit_multiple_response'] : 0, 'file_upload_limit' => isset( $question['settings']['file_upload_limit'] ) ? $question['settings']['file_upload_limit'] : 0, 'file_upload_type' => isset( $question['settings']['file_upload_type'] ) ? $question['settings']['file_upload_type'] : '', - 'quiz_name' => isset( $quiz_name['quiz_name'] ) ? $quiz_name['quiz_name'] : '', + 'quiz_name' => $quiz_name, 'question_title' => isset( $question['settings']['question_title'] ) ? $question['settings']['question_title'] : '', 'featureImageID' => isset( $question['settings']['featureImageID'] ) ? $question['settings']['featureImageID'] : '', 'featureImageSrc' => isset( $question['settings']['featureImageSrc'] ) ? $question['settings']['featureImageSrc'] : '', 'settings' => $question['settings'], + 'link_quizzes' => $quiz_name_by_question, + 'merged_question' => implode(",", $linked_question_ids), ); $question_data = apply_filters( 'qsm_rest_api_filter_question_data', $question_data, $question, $request ); $question_array[] = $question_data; @@ -608,6 +643,8 @@ function qsm_rest_create_question( WP_REST_Request $request ) { 'order' => 1, 'category' => $request['category'], 'multicategories' => $request['multicategories'], + 'linked_question' => $request['merged_question'], + 'is_linking' => $request['is_linking'], ); $settings = array( 'required' => $request['required'], @@ -671,6 +708,7 @@ function qsm_rest_save_question( WP_REST_Request $request ) { 'order' => 1, 'category' => $request['category'], 'multicategories' => $request['multicategories'], + 'linked_question' => $request['merged_question'], ); $settings = array(); $settings['answerEditor'] = $request['answerEditor']; diff --git a/php/template-variables.php b/php/template-variables.php index 114b4c9a2..f71d70e81 100644 --- a/php/template-variables.php +++ b/php/template-variables.php @@ -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)); From dfa1ac5c9d7980b3839f04dab803eef53c075cc3 Mon Sep 17 00:00:00 2001 From: etchirag Date: Mon, 30 Sep 2024 13:34:31 +0530 Subject: [PATCH 23/49] Fixed issue with creating and loading first link question --- js/qsm-admin.js | 6 +++--- php/classes/class-qsm-install.php | 2 +- php/classes/class-qsm-questions.php | 3 --- php/rest-api.php | 19 +++++++++++++++---- 4 files changed, 19 insertions(+), 11 deletions(-) diff --git a/js/qsm-admin.js b/js/qsm-admin.js index 9c75581da..8ffc8c815 100644 --- a/js/qsm-admin.js +++ b/js/qsm-admin.js @@ -2048,15 +2048,16 @@ var qsm_link_button; }, addQuestionFromQuestionBank: function (questionID, is_linking = 0) { QSMAdmin.displayAlert(qsm_admin_messages.adding_question, 'info'); + let isLinkingData = is_linking == 1 ? questionID : 0; var model = new QSMQuestion.question({ id: questionID, - is_linking: is_linking == 1 ? questionID : 0, + is_linking: isLinkingData }); model.fetch({ headers: { 'X-WP-Nonce': qsmQuestionSettings.nonce }, - url: wpApiSettings.root + 'quiz-survey-master/v1/questions/' + questionID, + url: wpApiSettings.root + 'quiz-survey-master/v1/questions/' + questionID + '?is_linking=' + isLinkingData, success: QSMQuestion.questionBankSuccess, error: QSMAdmin.displayError }); @@ -2249,7 +2250,6 @@ var qsm_link_button; if(qsm_link_button) { qsm_link_button.html('').html(qsm_admin_messages.link_question); } - // qsm_link_button ? qsm_link_button.html('').html(qsm_admin_messages.link_question) : ""; if(import_button){ import_button.attr("onclick", "return confirm('" + qsm_admin_messages.confirm_message + " " + qsm_admin_messages.import_question_again + "');"); } diff --git a/php/classes/class-qsm-install.php b/php/classes/class-qsm-install.php index 5e13238e3..bc2fbf044 100644 --- a/php/classes/class-qsm-install.php +++ b/php/classes/class-qsm-install.php @@ -2047,7 +2047,7 @@ public function update() { $update_sql = "UPDATE $mlw_questions_table SET linked_question = '' WHERE linked_question IS NULL"; $results = $wpdb->query( $update_sql ); } -} + } if ( ! get_option( 'mlw_advert_shows' ) ) { add_option( 'mlw_advert_shows', 'true' ); } diff --git a/php/classes/class-qsm-questions.php b/php/classes/class-qsm-questions.php index 27978d649..18313ee19 100644 --- a/php/classes/class-qsm-questions.php +++ b/php/classes/class-qsm-questions.php @@ -362,9 +362,6 @@ private static function create_save_question( $data, $answers, $settings, $is_cr throw new Exception( $msg ); } - // echo"
";
-		// print_r($data);
-		// echo"
"; $base_question_id = $question_id; $quiz_questions_array = array(); $quiz_questions_array[ intval( $data['quiz_id'] ) ] = $question_id; diff --git a/php/rest-api.php b/php/rest-api.php index 0355f1d32..eb573c9b9 100644 --- a/php/rest-api.php +++ b/php/rest-api.php @@ -494,10 +494,21 @@ function qsm_rest_get_question( WP_REST_Request $request ) { $question = QSM_Questions::load_question( $request['id'] ); $categorysArray = QSM_Questions::get_question_categories( $question['question_id'] ); if ( ! empty( $question ) ) { - $linked_question_ids = array_filter( isset( $question['linked_question'] ) ? explode(',', $question['linked_question']) : array() ); + $is_linking = $request['is_linking']; + $comma_seprated_ids = ''; + if ( 1 <= $is_linking ) { + if ( isset( $question['linked_question'] ) && '' == $question['linked_question'] ) { + $comma_seprated_ids = $is_linking; + } else { + $expolded_question_array = explode(',', $question['linked_question']); + $expolded_question_array[] = $is_linking; + $comma_seprated_ids = implode( ',', array_unique($expolded_question_array) ); + } + } + $quiz_name_by_question = array(); - if ( ! empty($linked_question_ids) ) { - $quiz_results = $wpdb->get_results( "SELECT `quiz_id`, `question_id` FROM `{$wpdb->prefix}mlw_questions` WHERE `question_id` IN (" . implode( ',', $linked_question_ids ) . ")" ); + if ( ! empty($comma_seprated_ids) ) { + $quiz_results = $wpdb->get_results( "SELECT `quiz_id`, `question_id` FROM `{$wpdb->prefix}mlw_questions` WHERE `question_id` IN (" .$comma_seprated_ids. ")" ); foreach ( $quiz_results as $key => $value ) { $quiz_name_in_loop = $wpdb->get_row( $wpdb->prepare( "SELECT quiz_name FROM {$wpdb->prefix}mlw_quizzes WHERE quiz_id = %d", $value->quiz_id ), ARRAY_A ); $quiz_name_in_loop = isset( $quiz_name_in_loop['quiz_name'] ) ? $quiz_name_in_loop['quiz_name'] : ''; @@ -521,7 +532,7 @@ function qsm_rest_get_question( WP_REST_Request $request ) { 'page' => $question['page'], 'question_title' => isset( $question['settings']['question_title'] ) ? $question['settings']['question_title'] : '', 'link_quizzes' => $quiz_name_by_question, - 'merged_question' => implode(",", $linked_question_ids), + 'merged_question' => $comma_seprated_ids, ); } return $question; From 3836bf9363ae1ce5ba941369ac6b8a949b9fa9ce Mon Sep 17 00:00:00 2001 From: etchirag Date: Tue, 1 Oct 2024 00:30:31 +0530 Subject: [PATCH 24/49] Minor changes --- css/qsm-admin.css | 3 ++- js/qsm-admin.js | 9 +++------ php/admin/options-page-questions-tab.php | 10 ++-------- php/classes/class-qsm-install.php | 10 +++++----- 4 files changed, 12 insertions(+), 20 deletions(-) diff --git a/css/qsm-admin.css b/css/qsm-admin.css index 27b9e338b..7cd2ceded 100644 --- a/css/qsm-admin.css +++ b/css/qsm-admin.css @@ -1487,10 +1487,11 @@ span.qsm-linked-list-item { background: #f0f0f1; } -div.qsm-linked-list-inside a.qsm-unlink-the-question { +div.qsm-linked-list-inside span.qsm-unlink-the-question { color: #DC3232; font-weight: 500; max-width: 60px; + cursor: pointer; } .qsm-linked-list-div-block p { diff --git a/js/qsm-admin.js b/js/qsm-admin.js index 7b1acbd3a..0cbff63aa 100644 --- a/js/qsm-admin.js +++ b/js/qsm-admin.js @@ -2803,7 +2803,6 @@ var qsm_link_button; // Ensure each quizName is a valid non-empty string if (quizName && typeof quizName == 'string' && quizName.trim().length > 0) { let link = $('') - .attr('href', 'javascript:void(0)') .attr('class', 'qsm-linked-list-item') .attr('title', quizName) .text(quizName.length > 25 ? quizName.substring(0, 25) + '...' : quizName); @@ -2814,8 +2813,7 @@ var qsm_link_button; }); // Add an "Unlink" link at the end - let unlink = $('') - .attr('href', 'javascript:void(0)') + let unlink = $('') .attr('class', 'qsm-unlink-the-question button button-danger') .attr('data-question-id', questionID) .text(qsm_admin_messages.unlink_question); @@ -3298,7 +3296,7 @@ var qsm_link_button; $(document).on('click', '.qsm-popup-bank .import-button', function (event) { event.preventDefault(); qsm_link_button = ''; - $(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')); @@ -3308,7 +3306,7 @@ var qsm_link_button; $(document).on('click', '.qsm-popup-bank .link-question', function (event) { event.preventDefault(); - $(this).text('').text(qsm_admin_messages.linking_question); + $(this).text(qsm_admin_messages.linking_question); qsm_link_button = $(this); $('.link-question').addClass('disable_import'); // 1 for the linking the questions default is 0 @@ -3332,7 +3330,6 @@ var qsm_link_button; nonce: qsmQuestionSettings.unlinkNonce }, success: function (response) { - console.log(response); $(document).find('.qsm-linked-list-div-block').remove(); } }); diff --git a/php/admin/options-page-questions-tab.php b/php/admin/options-page-questions-tab.php index 471ff67d2..638fb63c2 100644 --- a/php/admin/options-page-questions-tab.php +++ b/php/admin/options-page-questions-tab.php @@ -1275,7 +1275,7 @@ function qsm_bulk_delete_question_from_database() { */ function qsm_get_unique_linked_question_ids_to_remove( $question_ids ) { global $wpdb; - $current_linked_questions = array(); + $all_ids = array(); foreach ( $question_ids as $id ) { $sql = $wpdb->prepare( "SELECT linked_question FROM {$wpdb->prefix}mlw_questions WHERE question_id = %d", @@ -1283,13 +1283,7 @@ function qsm_get_unique_linked_question_ids_to_remove( $question_ids ) { ); $linked_question = $wpdb->get_var($sql); if ( ! empty($linked_question) ) { - $current_linked_questions[] = $linked_question; - } - } - $all_ids = array(); - foreach ( $current_linked_questions as $linked_questions ) { - if ( ! empty($linked_questions) ) { - $all_ids = array_merge($all_ids, explode(',', $linked_questions)); + $all_ids = array_merge($all_ids, explode(',', $linked_question)); } } return $all_ids; diff --git a/php/classes/class-qsm-install.php b/php/classes/class-qsm-install.php index bc2fbf044..cbb405613 100644 --- a/php/classes/class-qsm-install.php +++ b/php/classes/class-qsm-install.php @@ -2042,11 +2042,11 @@ public function update() { // Update 9.1.3 $mlw_questions_table = $wpdb->prefix . 'mlw_questions'; if ( 'linked_question' != $wpdb->get_var( "SHOW COLUMNS FROM $mlw_questions_table LIKE 'linked_question'" ) ) { - $sql = "ALTER TABLE $mlw_questions_table ADD linked_question TEXT NULL DEFAULT '' AFTER category"; - $results = $wpdb->query( $sql ); - $update_sql = "UPDATE $mlw_questions_table SET linked_question = '' WHERE linked_question IS NULL"; - $results = $wpdb->query( $update_sql ); - } + $sql = 'ALTER TABLE ' . $mlw_questions_table . ' ADD linked_question TEXT NULL DEFAULT \'\' AFTER category'; + $results = $mlwQuizMasterNext->wpdb_alter_table_query( $sql ); + $update_sql = 'UPDATE ' . $mlw_questions_table . ' SET linked_question = \'\' WHERE linked_question IS NULL'; + $results = $mlwQuizMasterNext->wpdb_alter_table_query( $update_sql ); + } } if ( ! get_option( 'mlw_advert_shows' ) ) { add_option( 'mlw_advert_shows', 'true' ); From fe96771a1b85a13aea42b72ca3551253307b35fc Mon Sep 17 00:00:00 2001 From: PranavAwasthi Date: Tue, 1 Oct 2024 13:10:21 +0530 Subject: [PATCH 25/49] Modify permissions for Editor role --- mlw_quizmaster2.php | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/mlw_quizmaster2.php b/mlw_quizmaster2.php index d94271979..79a383969 100644 --- a/mlw_quizmaster2.php +++ b/mlw_quizmaster2.php @@ -672,8 +672,6 @@ public function register_quiz_post_types() { 'edit_private_posts' => 'edit_private_qsm_quizzes', 'edit_published_posts' => 'edit_published_qsm_quizzes', 'create_posts' => 'create_qsm_quizzes', - 'manage_categories' => 'manage_qsm_quiz_categories', - 'manage_categories' => 'manage_qsm_quiz_answer_label', 'moderate_comments' => 'view_qsm_quiz_result', ); @@ -705,6 +703,12 @@ 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 ); } @@ -725,16 +729,22 @@ public function qsm_add_user_capabilities() { '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', From c9fdafdacb330bf4aef355fc80dfa8c84c1122f6 Mon Sep 17 00:00:00 2001 From: Mohammad Zubair Ali Date: Tue, 1 Oct 2024 13:48:09 +0530 Subject: [PATCH 26/49] fixed issue with contact form location and hide issue --- php/admin/options-page-contact-tab.php | 9 +++------ php/classes/class-qsm-install.php | 6 +++--- php/classes/class-qsm-settings.php | 10 +++++++--- 3 files changed, 13 insertions(+), 12 deletions(-) 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/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..6c0a79ea3 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 From d76f3b844a9adc869ad982b096d55a5575670def Mon Sep 17 00:00:00 2001 From: etchirag Date: Tue, 1 Oct 2024 15:13:16 +0530 Subject: [PATCH 27/49] Updated question count after removing questions --- php/admin/options-page-questions-tab.php | 85 ++++++++++++++++++++++-- 1 file changed, 80 insertions(+), 5 deletions(-) diff --git a/php/admin/options-page-questions-tab.php b/php/admin/options-page-questions-tab.php index 638fb63c2..b13b42b03 100644 --- a/php/admin/options-page-questions-tab.php +++ b/php/admin/options-page-questions-tab.php @@ -1173,15 +1173,19 @@ function qsm_delete_question_from_database() { if ( ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['nonce'] ) ), 'delete_question_from_database' ) ) { wp_send_json_error( __( 'Nonce verification failed.', 'quiz-master-next' ) ); } - $question_id = isset( $_POST['question_id'] ) ? intval( $_POST['question_id'] ) : 0; + $base_question_id = $question_id = isset( $_POST['question_id'] ) ? intval( $_POST['question_id'] ) : 0; if ( $question_id ) { global $wpdb, $mlwQuizMasterNext; + $update_qpages_after_delete = array(); $dependent_question_ids = qsm_get_unique_linked_question_ids_to_remove(array( $question_id ) ); $question_id = array_merge($dependent_question_ids, array( $question_id ) ); $question_id = array_unique($question_id); $question_id = array_filter($question_id); $placeholders = array_fill( 0, count( $question_id ), '%d' ); - + if ( ! empty($dependent_question_ids) ) { + $dependent_question_ids = array_diff($dependent_question_ids, [ $base_question_id ] ); + $update_qpages_after_delete = qsm_process_to_update_qpages_after_unlink($dependent_question_ids); + } // Construct the query with placeholders $query = sprintf( "DELETE FROM {$wpdb->prefix}mlw_questions WHERE question_id IN (%s)", @@ -1192,6 +1196,13 @@ function qsm_delete_question_from_database() { $query = $wpdb->prepare( $query, $question_id ); $results = $wpdb->query( $query ); if ( $results ) { + if ( ! empty($update_qpages_after_delete) ) { + foreach ( $update_qpages_after_delete as $quiz_id => $aftervalue ) { + $mlwQuizMasterNext->pluginHelper->prepare_quiz( $quiz_id ); + $mlwQuizMasterNext->pluginHelper->update_quiz_setting( 'qpages', $aftervalue['qpages'] ); + $mlwQuizMasterNext->pluginHelper->update_quiz_setting( 'pages', $aftervalue['pages'] ); + } + } wp_send_json_success( __( 'Question removed Successfully.', 'quiz-master-next' ) ); }else { wp_send_json_error( __( 'Question delete failed!', 'quiz-master-next' ) ); @@ -1230,13 +1241,16 @@ function qsm_bulk_delete_question_from_database() { } ); // Sanitize and validate the IDs - $question_id = array_map( 'intval', $question_id ); + $base_question_ids = $question_id = array_map( 'intval', $question_id ); if ( ! empty( $question_id ) ) { global $wpdb; - + $update_qpages_after_delete = array(); $dependent_question_ids = qsm_get_unique_linked_question_ids_to_remove($question_id); - + if ( ! empty($dependent_question_ids) ) { + $dependent_question_ids = array_diff($dependent_question_ids, [ $base_question_id ] ); + $update_qpages_after_delete = qsm_process_to_update_qpages_after_unlink($dependent_question_ids); + } $question_id = array_merge($dependent_question_ids, $question_id); $question_id = array_unique($question_id); // Ensure all IDs are unique $question_id = array_filter($question_id); // Remove empty values @@ -1254,6 +1268,13 @@ function qsm_bulk_delete_question_from_database() { $results = $wpdb->query( $query ); if ( $results ) { + if ( ! empty($update_qpages_after_delete) ) { + foreach ( $update_qpages_after_delete as $quiz_id => $aftervalue ) { + $mlwQuizMasterNext->pluginHelper->prepare_quiz( $quiz_id ); + $mlwQuizMasterNext->pluginHelper->update_quiz_setting( 'qpages', $aftervalue['qpages'] ); + $mlwQuizMasterNext->pluginHelper->update_quiz_setting( 'pages', $aftervalue['pages'] ); + } + } wp_send_json_success( __( 'Questions removed Successfully.', 'quiz-master-next' ) ); }else { $mlwQuizMasterNext->log_manager->add( __('Error 0001 delete questions failed - question IDs:', 'quiz-master-next') . $question_id, '
Error:' . $wpdb->last_error . ' from ' . $wpdb->last_query, 0, 'error' ); @@ -1265,6 +1286,60 @@ function qsm_bulk_delete_question_from_database() { } add_action( 'wp_ajax_qsm_bulk_delete_question_from_database', 'qsm_bulk_delete_question_from_database' ); +/** + * returns pages and qpages for dependent question ids for update after deleting questions + * + * @param array $dependent_question_ids An array of question IDs. + * @since 9.1.3 + */ +function qsm_process_to_update_qpages_after_unlink( $dependent_question_ids ) { + $comma_seprated_ids = implode( ',', array_unique($dependent_question_ids) ); + $qpages_array = array(); + if ( ! empty($comma_seprated_ids) ) { + global $wpdb, $mlwQuizMasterNext; + $quiz_results = $wpdb->get_results( "SELECT `quiz_id`, `question_id` FROM `{$wpdb->prefix}mlw_questions` WHERE `question_id` IN (" .$comma_seprated_ids. ")" ); + if ( ! empty($quiz_results) ) { + foreach ( $quiz_results as $key => $single_quiz ) { + $quiz_id = $single_quiz->quiz_id; + $mlwQuizMasterNext->pluginHelper->prepare_quiz( $quiz_id ); + $pages = $mlwQuizMasterNext->pluginHelper->get_quiz_setting( 'pages', array() ); + $clone_qpages = $qpages = $mlwQuizMasterNext->pluginHelper->get_quiz_setting( 'qpages', array() ); + if ( ! empty($clone_qpages) ) { + foreach ( $clone_qpages as $clonekey => $clonevalue ) { + if ( ! empty($clonevalue['questions']) ) { + if ( in_array($single_quiz->question_id, $clonevalue['questions']) ) { + $clone_qpages[ $clonekey ]['questions'] = array_diff($clonevalue['questions'], [ $single_quiz->question_id ]); + $pages[ $clonekey ] = array_diff($pages[ $clonekey ], [ $single_quiz->question_id ]); + } + } + } + $qpages = $clone_qpages; + } + //merge duplicate questions + $all_questions = array(); + foreach ( $pages as $page_key => $questions ) { + $page_questions = array(); + $questions = array_unique( $questions ); + foreach ( $questions as $id ) { + if ( ! in_array( $id, $all_questions, true ) ) { + $page_questions[] = $id; + } + } + $all_questions = array_merge( $all_questions, $questions ); + $pages[ $page_key ] = $page_questions; + if ( isset( $qpages[ $page_key ] ) ) { + $qpages[ $page_key ]['questions'] = $page_questions; + } + } + $qpages_array[ $quiz_id ] = array( + 'pages' => $pages, + 'qpages' => $qpages, + ); + } + } + } + return $qpages_array; +} /** * Get Unique Linked Question IDs From 533a9c594092bcd78451b8e005e332a5d7f504bb Mon Sep 17 00:00:00 2001 From: etchirag Date: Tue, 1 Oct 2024 15:23:53 +0530 Subject: [PATCH 28/49] closed model after link or import question --- js/qsm-admin.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/js/qsm-admin.js b/js/qsm-admin.js index 0cbff63aa..ce913e105 100644 --- a/js/qsm-admin.js +++ b/js/qsm-admin.js @@ -3300,7 +3300,7 @@ var qsm_link_button; import_button = $(this); $('.import-button').addClass('disable_import'); QSMQuestion.addQuestionFromQuestionBank($(this).data('question-id')); - // MicroModal.close('modal-2'); + MicroModal.close('modal-2'); }); @@ -3311,6 +3311,7 @@ var qsm_link_button; $('.link-question').addClass('disable_import'); // 1 for the linking the questions default is 0 QSMQuestion.addQuestionFromQuestionBank($(this).data('question-id'), 1); + MicroModal.close('modal-2'); }); jQuery(document).on('click', '.qsm-linked-list-div-block .qsm-linked-list-view-button', function () { From b90bc18d5a096d9bb0921b2a4273632cef20e759 Mon Sep 17 00:00:00 2001 From: Mohammad Zubair Ali Date: Tue, 1 Oct 2024 16:08:56 +0530 Subject: [PATCH 29/49] fixed php warnings --- 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 8432fd699..c95b9f003 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'], From 24f632aef38a4c64b76645a207128a2a95840833 Mon Sep 17 00:00:00 2001 From: PranavAwasthi Date: Thu, 3 Oct 2024 11:16:47 +0530 Subject: [PATCH 30/49] Fixed fatal error for remove_cap --- mlw_quizmaster2.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/mlw_quizmaster2.php b/mlw_quizmaster2.php index 79a383969..5f5a58026 100644 --- a/mlw_quizmaster2.php +++ b/mlw_quizmaster2.php @@ -765,7 +765,9 @@ public function qsm_add_user_capabilities() { // Remove all capabilities first. foreach ( $administrator_capabilities as $cap ) { - $role->remove_cap( $cap ); + if ( $role->has_cap( $cap ) ) { + $role->remove_cap( $cap ); + } } // Dynamically determine the capabilities to add based on the current user role. From f6d8b54d7c9e088e3900399d71a351a456d1ab6d Mon Sep 17 00:00:00 2001 From: PranavAwasthi Date: Thu, 3 Oct 2024 12:41:09 +0530 Subject: [PATCH 31/49] Fixed hook for add_user_capabilites function --- mlw_quizmaster2.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/mlw_quizmaster2.php b/mlw_quizmaster2.php index 5f5a58026..0dd27bca8 100644 --- a/mlw_quizmaster2.php +++ b/mlw_quizmaster2.php @@ -345,8 +345,8 @@ 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_init', array( $this, 'qsm_add_user_capabilities' ) ); 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']) ) { @@ -760,7 +760,8 @@ public function qsm_add_user_capabilities() { $user = wp_get_current_user(); $roles = (array) $user->roles; $rolename = $roles[0]; - + // print_r($roles); + // die; $role = get_role( $rolename ); // Remove all capabilities first. From 506aafab4a97fe3b7c8b1cc3030945392983e751 Mon Sep 17 00:00:00 2001 From: PranavAwasthi Date: Thu, 3 Oct 2024 13:34:42 +0530 Subject: [PATCH 32/49] Fixed php warning --- php/classes/class-qmn-quiz-manager.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/php/classes/class-qmn-quiz-manager.php b/php/classes/class-qmn-quiz-manager.php index 8432fd699..f492bcef1 100644 --- a/php/classes/class-qmn-quiz-manager.php +++ b/php/classes/class-qmn-quiz-manager.php @@ -597,7 +597,8 @@ 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 ) ? $qmn_quiz_options->quiz_processing_message : ''; + $quiz_processing_message = $mlwQuizMasterNext->pluginHelper->qsm_language_support( $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'], From 55ae0a40d9f02d3a1d9d5710fee7e4f66adb2f27 Mon Sep 17 00:00:00 2001 From: PranavAwasthi Date: Thu, 3 Oct 2024 13:36:58 +0530 Subject: [PATCH 33/49] removed commented code --- mlw_quizmaster2.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/mlw_quizmaster2.php b/mlw_quizmaster2.php index 0dd27bca8..6e5acc3c8 100644 --- a/mlw_quizmaster2.php +++ b/mlw_quizmaster2.php @@ -760,8 +760,7 @@ public function qsm_add_user_capabilities() { $user = wp_get_current_user(); $roles = (array) $user->roles; $rolename = $roles[0]; - // print_r($roles); - // die; + $role = get_role( $rolename ); // Remove all capabilities first. From f197752c9499716789f32032a58354dcdac20d73 Mon Sep 17 00:00:00 2001 From: PranavAwasthi Date: Thu, 3 Oct 2024 15:40:00 +0530 Subject: [PATCH 34/49] Fixed result page permissions for editor --- php/admin/admin-results-details-page.php | 2 +- php/admin/admin-results-page.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/php/admin/admin-results-details-page.php b/php/admin/admin-results-details-page.php index 3cf53169f..59825ee2b 100644 --- a/php/admin/admin-results-details-page.php +++ b/php/admin/admin-results-details-page.php @@ -71,7 +71,7 @@ function qsm_generate_results_details_tab() { $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( 'edit_others_qsm_quizzes' ) ) { + if ( ( ! current_user_can( 'view_qsm_quiz_result' ) || intval($post_author) != get_current_user_id()) && ! current_user_can( 'delete_others_qsm_quizzes' ) ) { return; } diff --git a/php/admin/admin-results-page.php b/php/admin/admin-results-page.php index d0afd9db9..4412152f9 100644 --- a/php/admin/admin-results-page.php +++ b/php/admin/admin-results-page.php @@ -529,7 +529,7 @@ function qsm_results_overview_tab_content() {
user == get_current_user_id() ) || current_user_can( 'edit_others_qsm_quizzes' ) ) { + if ( ( current_user_can( 'view_qsm_quiz_result' ) && $quiz_infos[ $x ]->user == get_current_user_id() ) || current_user_can( 'delete_others_qsm_quizzes' ) ) { ?> | From 2be506290154e4093c60e144821327bd1e5dd6ad Mon Sep 17 00:00:00 2001 From: PranavAwasthi Date: Thu, 3 Oct 2024 16:13:48 +0530 Subject: [PATCH 35/49] Fixed html element show up on result page --- php/template-variables.php | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/php/template-variables.php b/php/template-variables.php index 114b4c9a2..ad3568651 100644 --- a/php/template-variables.php +++ b/php/template-variables.php @@ -69,6 +69,9 @@ * Show particular question answer. */ function qsm_variable_single_question_answer( $content, $mlw_quiz_array ) { + // echo '
';
+	// print_r($mlw_quiz_array);
+	// echo '
'; $quiz_id = is_object( $mlw_quiz_array ) ? $mlw_quiz_array->quiz_id : $mlw_quiz_array['quiz_id']; while ( false !== strpos( $content, '%QUESTION_ANSWER_' ) ) { $question_id = mlw_qmn_get_string_between( $content, '%QUESTION_ANSWER_', '%' ); @@ -1366,12 +1369,12 @@ function qsm_questions_answers_shortcode_to_text( $mlw_quiz_array, $qmn_question 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 ); + $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 ); From 00d9f989df4817cce2fefb6ba92ed2a71603ae50 Mon Sep 17 00:00:00 2001 From: PranavAwasthi Date: Thu, 3 Oct 2024 16:18:07 +0530 Subject: [PATCH 36/49] removed commented code --- php/template-variables.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/php/template-variables.php b/php/template-variables.php index 15597e62b..8f6fce96c 100644 --- a/php/template-variables.php +++ b/php/template-variables.php @@ -69,9 +69,6 @@ * Show particular question answer. */ function qsm_variable_single_question_answer( $content, $mlw_quiz_array ) { - // echo '
';
-	// print_r($mlw_quiz_array);
-	// echo '
'; $quiz_id = is_object( $mlw_quiz_array ) ? $mlw_quiz_array->quiz_id : $mlw_quiz_array['quiz_id']; while ( false !== strpos( $content, '%QUESTION_ANSWER_' ) ) { $question_id = mlw_qmn_get_string_between( $content, '%QUESTION_ANSWER_', '%' ); From 50fd21cc25ac8b2f4bf272178e6f5e721991479e Mon Sep 17 00:00:00 2001 From: PranavAwasthi Date: Thu, 3 Oct 2024 16:57:01 +0530 Subject: [PATCH 37/49] escaped user entered data --- php/template-variables.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/php/template-variables.php b/php/template-variables.php index 8f6fce96c..564fe870e 100644 --- a/php/template-variables.php +++ b/php/template-variables.php @@ -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 . '' . $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 ); } else { - $mlw_question_answer_display = str_replace( '%USER_ANSWER%', $open_span_tag . ''. $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 ); From 2d5f7a0a362aa2f20ec8e0c649bd6fff94cc6206 Mon Sep 17 00:00:00 2001 From: manandeep singh Date: Thu, 3 Oct 2024 17:40:03 +0530 Subject: [PATCH 38/49] Fix Plugin css affecting Wordpress --- css/qsm-admin.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/css/qsm-admin.css b/css/qsm-admin.css index 63a049e03..237a159b1 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%; } From 8169a2d40079a27e926a02bde79720d014497e6f Mon Sep 17 00:00:00 2001 From: etchirag Date: Fri, 4 Oct 2024 12:58:55 +0530 Subject: [PATCH 39/49] Minor changes --- php/rest-api.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/rest-api.php b/php/rest-api.php index eb573c9b9..5591619c0 100644 --- a/php/rest-api.php +++ b/php/rest-api.php @@ -575,7 +575,7 @@ function qsm_rest_get_questions( WP_REST_Request $request ) { $linked_question_ids = array_filter( isset( $question['linked_question'] ) ? explode(',', $question['linked_question']) : array() ); if ( ! empty($linked_question_ids) ) { $quiz_results = $wpdb->get_results( "SELECT `quiz_id`, `question_id` FROM `{$wpdb->prefix}mlw_questions` WHERE `question_id` IN (" . implode( ',', $linked_question_ids ) . ")" ); - foreach ( $quiz_results as $key => $value ) { + foreach ( $quiz_results as $value ) { if ( ! in_array($value->question_id, $procesed_question_ids) ) { $quiz_name_in_loop = $wpdb->get_row( $wpdb->prepare( "SELECT quiz_name FROM {$wpdb->prefix}mlw_quizzes WHERE quiz_id = %d", $value->quiz_id ), ARRAY_A ); $quiz_name_in_loop = isset( $quiz_name_in_loop['quiz_name'] ) ? $quiz_name_in_loop['quiz_name'] : ''; From 4dd3513fb1e83d754de16fb7d3587da931a64264 Mon Sep 17 00:00:00 2001 From: Mohammad Zubair Ali Date: Fri, 4 Oct 2024 13:07:14 +0530 Subject: [PATCH 40/49] update change 9.2.0 --- assets/Premium Bundle.png | Bin 814 -> 0 bytes assets/Starter Bundle.png | Bin 794 -> 0 bytes mlw_quizmaster2.php | 38 ++++++++++++++--------------- php/admin/admin-results-page.php | 6 ++--- php/admin/quizzes-page.php | 8 +++--- php/classes/class-qsm-settings.php | 8 +++--- readme.txt | 10 +++++++- 7 files changed, 39 insertions(+), 31 deletions(-) delete mode 100644 assets/Premium Bundle.png delete mode 100644 assets/Starter Bundle.png diff --git a/assets/Premium Bundle.png b/assets/Premium Bundle.png deleted file mode 100644 index 7ee6274387960493181c1dcd6410fa8652be2340..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 814 zcmV+}1JV46P)Px%=t)FDR9Fe^mg{lbKn#SfObTELDuE@agQ$bB1eV|uTmoHznGV!}*n!kRlnR`0 z9fAg5cSnoVuV4mqxWi(x_t4|%DPZsK?=Sdoya>R$6u1UIcME|)oVd7O0$&aD3v<=QxwrMSw>|f{6+Qv#vPXL5j$j zz|F+Xh}7fGET=IfP*_|wviq;qH})~)y6!7Jdf2Q<#AL4BK-1>$dvjjU|2W|Ub_p20 zFTJ;)c<<7+fYLS?94W|M(aD2ZuU*c<8$s@IinWF-H?-PgNuC^F#N)Ac zN|&}k`+eR*$dyZaAviI(KNhT`By;VcZa1OZg1;ir(tQ{O? z`aJ@eIvrQ{(6F$LezSmav@@4`bl7R>{T6dZHA;RgQ1c45ir@?K`W;WTU;IWNC&38R z8*3I^=6RCHEy8tPz^C5b={cIuPyqb8fOP*^-H+hdFW^znkvRVbKiJ#9Ksw?-{dTjn z>Ff9h59K_edL0-2{bDzH;_hd!nflc0&Ar;>mslI-ifXMEe!Gx|?9NB8Z zJdud;D?Vl2HItmXUe#_R&V1yY$S2eluq>kTHfrjJDw4u>~d3R!#V?4Te z7#>tRT-Q2+n{ diff --git a/assets/Starter Bundle.png b/assets/Starter Bundle.png deleted file mode 100644 index 9e5a54fd6d44eb7e50eedb77852b87890d64b507..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 794 zcmV+#1LgdQP)Px%)Ja4^R9FeUn2mAUFbsvOPM{5sCEz{dGajX3tuCbT+uNm zT~wcHRUl-}P)s1dC}_ocN)>Mr7e(3h*awP$eoIR?5hIDY!SJ)nK-Qi52&+ru^dm~l+y^8aPDWk zgj-xQ`KEH#K*Zbqlm$!>_lDvcqz@?fpHls(DagdT{T0DTLHP~h@0Y9_e88b#qRT-vcYc&UkD`k4cT$-z2a(63>a`yWbTf_7-5}0B-bLr=IzXGJsod z6urbpj@Ady%6{%HMrn7;R0BNq{0N17ESgRC2w-Fd3j+)0 zuNf(yLn{hZ!a`n&zbz0JLR;ZbZ7kwn1tCFhKHVcgha4~yo32Y%Bm~C{NiO6(F(B*p zi1|9tF*|~;;*16B%9E1g7UadyiAVV2?}O88!xuA-f5LYe^9y;Fe}T-=r!{btCOXcQ z^=0%ZG%eqlm2oBZ>IpGF@w`J6ZelLe8WJI#vo1vdxSvaq{Z!8CeMsF*u^~qYzQm=& zu~oUe)iJ8XU2HWna=J*}Ny}Lsr%)3VyI6_H8G<}#&0B?|P>;*UR$B?c%E2V(XwC7s Y|5fgO_Qn){7ytkO07*qoM6N<$f(Jrr1ONa4 diff --git a/mlw_quizmaster2.php b/mlw_quizmaster2.php index 6e5acc3c8..acafbcc29 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 @@ -703,11 +703,11 @@ public function register_quiz_post_types() { 'show_in_rest' => true, 'show_tagcloud' => false, 'rewrite' => false, - 'capabilities' => array( + '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', + 'delete_terms' => 'delete_qsm_quiz_categories', + 'assign_terms' => 'assign_qsm_quiz_categories', ), ); register_taxonomy( 'qsm_category', array( 'qsm-taxonomy' ), $taxonomy_args ); @@ -756,20 +756,20 @@ public function qsm_add_user_capabilities() { '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( @@ -777,7 +777,7 @@ public function qsm_add_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 ); @@ -830,16 +830,16 @@ public function setup_admin_menu() { $settings = (array) get_option( 'qmn-settings' ); 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', + + $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 ) { diff --git a/php/admin/admin-results-page.php b/php/admin/admin-results-page.php index 4412152f9..7647e67d3 100644 --- a/php/admin/admin-results-page.php +++ b/php/admin/admin-results-page.php @@ -529,11 +529,11 @@ function qsm_results_overview_tab_content() {
user == get_current_user_id() ) || current_user_can( 'delete_others_qsm_quizzes' ) ) { + if ( ( current_user_can( 'view_qsm_quiz_result' ) && get_current_user_id() == $quiz_infos[ $x ]->user ) || current_user_can( 'delete_others_qsm_quizzes' ) ) { ?> - | + | - | + |
diff --git a/php/admin/quizzes-page.php b/php/admin/quizzes-page.php index f587b69ae..4ca12112a 100644 --- a/php/admin/quizzes-page.php +++ b/php/admin/quizzes-page.php @@ -180,16 +180,16 @@ public function qsm_post_row_actions( $actions, $post ) { $quiz_id = get_post_meta( $post->ID, 'quiz_id', true ); if ( ! empty( $quiz_id ) ) { $actions = array(); - if ( ( current_user_can( 'edit_qsm_quiz', $post->ID ) && $post->post_author == get_current_user_id() ) || current_user_can( 'edit_others_qsm_quizzes' ) ) { + 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 ) && $post->post_author == get_current_user_id() ) || current_user_can( 'edit_others_qsm_quizzes' ) ) { + 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 ) && $post->post_author == get_current_user_id() ) || current_user_can( 'delete_others_qsm_quizzes' ) ) { + 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' ) && $post->post_author == get_current_user_id() ) || current_user_can( 'edit_others_qsm_quizzes' ) ) { + 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'] ) ) { diff --git a/php/classes/class-qsm-settings.php b/php/classes/class-qsm-settings.php index 6c0a79ea3..5046ca6e8 100644 --- a/php/classes/class-qsm-settings.php +++ b/php/classes/class-qsm-settings.php @@ -471,10 +471,10 @@ public function get_quiz_options() { } $text = $this->get_setting('quiz_text'); - if (is_array($text)) { - foreach ($text as $key => $value) { - if (!empty($value)) { - $quiz_options[$key] = $value; + if ( is_array($text) ) { + foreach ( $text as $key => $value ) { + if ( ! empty($value) ) { + $quiz_options[ $key ] = $value; } } } diff --git a/readme.txt b/readme.txt index afe42c83c..a0daaa7d7 100644 --- a/readme.txt +++ b/readme.txt @@ -4,7 +4,7 @@ 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 @@ -189,6 +189,14 @@ QSM is designed to be compatible with most WordPress plugins and themes. However 18. Database == Changelog == += 9.2.0 ( October 04, 2024 ) = +* Feature: Added an option to link a question to multiple quizzes +* 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 From 705193bfcfa0d3c21b996c7249cf0cd41b70cc9b Mon Sep 17 00:00:00 2001 From: etchirag Date: Fri, 4 Oct 2024 13:09:19 +0530 Subject: [PATCH 41/49] Fixed sonar cloud issues --- js/qsm-admin.js | 6 ++++-- php/admin/options-page-questions-tab.php | 14 ++++++-------- php/classes/class-qsm-questions.php | 3 +-- php/rest-api.php | 2 +- 4 files changed, 12 insertions(+), 13 deletions(-) diff --git a/js/qsm-admin.js b/js/qsm-admin.js index ce913e105..2cd08aab8 100644 --- a/js/qsm-admin.js +++ b/js/qsm-admin.js @@ -2246,9 +2246,11 @@ var qsm_link_button; $('.import-button, .link-question').removeClass('disable_import'); QSMQuestion.countTotal(); - import_button ? import_button.html('').html(qsm_admin_messages.add_question) : ""; + if(import_button){ + import_button.html(qsm_admin_messages.add_question); + } if(qsm_link_button) { - qsm_link_button.html('').html(qsm_admin_messages.link_question); + qsm_link_button.html(qsm_admin_messages.link_question); } if(import_button){ import_button.attr("onclick", "return confirm('" + qsm_admin_messages.confirm_message + " " + qsm_admin_messages.import_question_again + "');"); diff --git a/php/admin/options-page-questions-tab.php b/php/admin/options-page-questions-tab.php index b13b42b03..5139748ca 100644 --- a/php/admin/options-page-questions-tab.php +++ b/php/admin/options-page-questions-tab.php @@ -940,7 +940,7 @@ function qsm_process_unlink_question_from_list_by_question_id( $question_id ) { $updated_linked_list = implode(',', array_filter($current_links)); $linked_ids = explode(',', $updated_linked_list); foreach ( $linked_ids as $linked_id ) { - $result = $wpdb->update( + $wpdb->update( $wpdb->prefix . 'mlw_questions', array( 'linked_question' => $updated_linked_list ), array( 'question_id' => intval($linked_id) ), @@ -1248,7 +1248,7 @@ function qsm_bulk_delete_question_from_database() { $update_qpages_after_delete = array(); $dependent_question_ids = qsm_get_unique_linked_question_ids_to_remove($question_id); if ( ! empty($dependent_question_ids) ) { - $dependent_question_ids = array_diff($dependent_question_ids, [ $base_question_id ] ); + $dependent_question_ids = array_diff($dependent_question_ids, [ $base_question_ids ] ); $update_qpages_after_delete = qsm_process_to_update_qpages_after_unlink($dependent_question_ids); } $question_id = array_merge($dependent_question_ids, $question_id); @@ -1299,18 +1299,16 @@ function qsm_process_to_update_qpages_after_unlink( $dependent_question_ids ) { global $wpdb, $mlwQuizMasterNext; $quiz_results = $wpdb->get_results( "SELECT `quiz_id`, `question_id` FROM `{$wpdb->prefix}mlw_questions` WHERE `question_id` IN (" .$comma_seprated_ids. ")" ); if ( ! empty($quiz_results) ) { - foreach ( $quiz_results as $key => $single_quiz ) { + foreach ( $quiz_results as $single_quiz ) { $quiz_id = $single_quiz->quiz_id; $mlwQuizMasterNext->pluginHelper->prepare_quiz( $quiz_id ); $pages = $mlwQuizMasterNext->pluginHelper->get_quiz_setting( 'pages', array() ); $clone_qpages = $qpages = $mlwQuizMasterNext->pluginHelper->get_quiz_setting( 'qpages', array() ); if ( ! empty($clone_qpages) ) { foreach ( $clone_qpages as $clonekey => $clonevalue ) { - if ( ! empty($clonevalue['questions']) ) { - if ( in_array($single_quiz->question_id, $clonevalue['questions']) ) { - $clone_qpages[ $clonekey ]['questions'] = array_diff($clonevalue['questions'], [ $single_quiz->question_id ]); - $pages[ $clonekey ] = array_diff($pages[ $clonekey ], [ $single_quiz->question_id ]); - } + if ( ! empty($clonevalue['questions']) && in_array($single_quiz->question_id, $clonevalue['questions']) ) { + $clone_qpages[ $clonekey ]['questions'] = array_diff($clonevalue['questions'], [ $single_quiz->question_id ]); + $pages[ $clonekey ] = array_diff($pages[ $clonekey ], [ $single_quiz->question_id ]); } } $qpages = $clone_qpages; diff --git a/php/classes/class-qsm-questions.php b/php/classes/class-qsm-questions.php index 18313ee19..a0cabf383 100644 --- a/php/classes/class-qsm-questions.php +++ b/php/classes/class-qsm-questions.php @@ -366,7 +366,6 @@ private static function create_save_question( $data, $answers, $settings, $is_cr $quiz_questions_array = array(); $quiz_questions_array[ intval( $data['quiz_id'] ) ] = $question_id; $linked_questions_array[] = $question_id; - $imploded_question_ids = $question_id; if ( isset($linked_question) && "" != $linked_question ) { $expolded_question_array = explode(',', $linked_question); $linked_questions_array = array_merge($expolded_question_array, $linked_questions_array); @@ -383,7 +382,7 @@ private static function create_save_question( $data, $answers, $settings, $is_cr $question_terms_table = $wpdb->prefix . 'mlw_question_terms'; foreach ( $quiz_questions_array as $quiz_id => $question_id_loop ) { $values['quiz_id'] = intval( $quiz_id ); - $results = $wpdb->update( + $wpdb->update( $wpdb->prefix . 'mlw_questions', $values, array( 'question_id' => intval($question_id_loop) ), diff --git a/php/rest-api.php b/php/rest-api.php index 5591619c0..d59d4d80b 100644 --- a/php/rest-api.php +++ b/php/rest-api.php @@ -509,7 +509,7 @@ function qsm_rest_get_question( WP_REST_Request $request ) { $quiz_name_by_question = array(); if ( ! empty($comma_seprated_ids) ) { $quiz_results = $wpdb->get_results( "SELECT `quiz_id`, `question_id` FROM `{$wpdb->prefix}mlw_questions` WHERE `question_id` IN (" .$comma_seprated_ids. ")" ); - foreach ( $quiz_results as $key => $value ) { + foreach ( $quiz_results as $value ) { $quiz_name_in_loop = $wpdb->get_row( $wpdb->prepare( "SELECT quiz_name FROM {$wpdb->prefix}mlw_quizzes WHERE quiz_id = %d", $value->quiz_id ), ARRAY_A ); $quiz_name_in_loop = isset( $quiz_name_in_loop['quiz_name'] ) ? $quiz_name_in_loop['quiz_name'] : ''; $quiz_name_by_question[] = $quiz_name_in_loop; From 71dab31103da2139fd47a8d69a93ea3b9acf4ec9 Mon Sep 17 00:00:00 2001 From: manandeep singh Date: Mon, 7 Oct 2024 12:18:01 +0530 Subject: [PATCH 42/49] fix advance timer issues with qsm timer --- js/qsm-quiz.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/js/qsm-quiz.js b/js/qsm-quiz.js index 7ec401320..5f08c5b76 100644 --- a/js/qsm-quiz.js +++ b/js/qsm-quiz.js @@ -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) { @@ -176,6 +177,9 @@ var qsmTimerInterval = []; } } var display = QSM.secondsToTimer(secondsRemaining); + if(qsm_timer_consumed_obj.qmn_count_upward_status == true){ + display = QSM.secondsToTimer(secondsConsumed); + } var systemTime = new Date().getTime() / 1000; systemTime = Math.round(systemTime); if ('1' === qmn_quiz_data[quizID].not_allow_after_expired_time && systemTime > qmn_quiz_data[quizID].scheduled_time_end) { @@ -2079,4 +2083,7 @@ jQuery(document).keydown(function(event) { } jQuery(document).trigger('qsm_keyboard_quiz_action_end', event); } -}); \ No newline at end of file +}); +const qsm_timer_consumed_obj = { + qmn_count_upward_status : false +} \ No newline at end of file From 7f115a99c2c0f11c1e9d10de34aa23715c4d4321 Mon Sep 17 00:00:00 2001 From: manandeep singh Date: Mon, 7 Oct 2024 12:30:48 +0530 Subject: [PATCH 43/49] Fix timer issues --- js/qsm-quiz.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/qsm-quiz.js b/js/qsm-quiz.js index 5f08c5b76..903727e12 100644 --- a/js/qsm-quiz.js +++ b/js/qsm-quiz.js @@ -177,7 +177,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; From 0657c25cb38763633d15776126f0db143a6e0e80 Mon Sep 17 00:00:00 2001 From: Mohammad Zubair Ali Date: Mon, 7 Oct 2024 12:45:46 +0530 Subject: [PATCH 44/49] update changlog --- readme.txt | 73 +++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 61 insertions(+), 12 deletions(-) diff --git a/readme.txt b/readme.txt index a0daaa7d7..2e1b4b3d5 100644 --- a/readme.txt +++ b/readme.txt @@ -8,19 +8,30 @@ 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 == From 7e49daf5665b2cb264aa3f8256a2004c77e50de2 Mon Sep 17 00:00:00 2001 From: Mohammad Zubair Ali Date: Mon, 7 Oct 2024 16:45:58 +0530 Subject: [PATCH 45/49] fixed wpcs --- php/admin/options-page-questions-tab.php | 14 +++++++------- php/classes/class-qsm-questions.php | 16 ++++++++-------- php/rest-api.php | 6 +++--- readme.txt | 2 +- 4 files changed, 19 insertions(+), 19 deletions(-) diff --git a/php/admin/options-page-questions-tab.php b/php/admin/options-page-questions-tab.php index 5139748ca..96bfb3254 100644 --- a/php/admin/options-page-questions-tab.php +++ b/php/admin/options-page-questions-tab.php @@ -887,7 +887,7 @@ class="save-page-button button button-primary">prefix}mlw_questions WHERE question_id IN (%s)", @@ -1265,7 +1265,7 @@ function qsm_bulk_delete_question_from_database() { // Prepare the query $query = $wpdb->prepare( $query, $question_id ); - + $results = $wpdb->query( $query ); if ( $results ) { if ( ! empty($update_qpages_after_delete) ) { @@ -1296,7 +1296,7 @@ function qsm_process_to_update_qpages_after_unlink( $dependent_question_ids ) { $comma_seprated_ids = implode( ',', array_unique($dependent_question_ids) ); $qpages_array = array(); if ( ! empty($comma_seprated_ids) ) { - global $wpdb, $mlwQuizMasterNext; + global $wpdb, $mlwQuizMasterNext; $quiz_results = $wpdb->get_results( "SELECT `quiz_id`, `question_id` FROM `{$wpdb->prefix}mlw_questions` WHERE `question_id` IN (" .$comma_seprated_ids. ")" ); if ( ! empty($quiz_results) ) { foreach ( $quiz_results as $single_quiz ) { @@ -1306,7 +1306,7 @@ function qsm_process_to_update_qpages_after_unlink( $dependent_question_ids ) { $clone_qpages = $qpages = $mlwQuizMasterNext->pluginHelper->get_quiz_setting( 'qpages', array() ); if ( ! empty($clone_qpages) ) { foreach ( $clone_qpages as $clonekey => $clonevalue ) { - if ( ! empty($clonevalue['questions']) && in_array($single_quiz->question_id, $clonevalue['questions']) ) { + if ( ! empty($clonevalue['questions']) && in_array( intval( $single_quiz->question_id ), $clonevalue['questions'], true) ) { $clone_qpages[ $clonekey ]['questions'] = array_diff($clonevalue['questions'], [ $single_quiz->question_id ]); $pages[ $clonekey ] = array_diff($pages[ $clonekey ], [ $single_quiz->question_id ]); } @@ -1347,7 +1347,7 @@ function qsm_process_to_update_qpages_after_unlink( $dependent_question_ids ) { * @since 9.1.3 */ function qsm_get_unique_linked_question_ids_to_remove( $question_ids ) { - global $wpdb; + global $wpdb; $all_ids = array(); foreach ( $question_ids as $id ) { $sql = $wpdb->prepare( diff --git a/php/classes/class-qsm-questions.php b/php/classes/class-qsm-questions.php index a0cabf383..17a83eee6 100644 --- a/php/classes/class-qsm-questions.php +++ b/php/classes/class-qsm-questions.php @@ -305,7 +305,7 @@ private static function create_save_question( $data, $answers, $settings, $is_cr }elseif ( 0 == $data['is_linking'] ) { $linked_question = ''; } - } + } $values = array( 'quiz_id' => intval( $data['quiz_id'] ), @@ -322,7 +322,7 @@ private static function create_save_question( $data, $answers, $settings, $is_cr 'deleted' => 0, ); $values = apply_filters( 'qsm_save_question_data', $values ); - + $types = array( '%d', '%s', @@ -389,11 +389,11 @@ private static function create_save_question( $data, $answers, $settings, $is_cr $types, array( '%d' ) ); - + /** * Process Question Categories */ - + $wpdb->delete( $question_terms_table, array( @@ -420,14 +420,14 @@ private static function create_save_question( $data, $answers, $settings, $is_cr /** * Hook after saving question */ - - if ( $is_creating && $base_question_id == $question_id_loop ) { + + if ( $is_creating && $base_question_id == $question_id_loop ) { do_action( 'qsm_question_added', $question_id_loop, $values ); } else { do_action( 'qsm_question_updated', $question_id_loop, $values ); } - do_action( 'qsm_saved_question', $question_id_loop, $values ); - + do_action( 'qsm_saved_question', $question_id_loop, $values ); + } return $base_question_id; } diff --git a/php/rest-api.php b/php/rest-api.php index d59d4d80b..a02ae73e2 100644 --- a/php/rest-api.php +++ b/php/rest-api.php @@ -505,7 +505,7 @@ function qsm_rest_get_question( WP_REST_Request $request ) { $comma_seprated_ids = implode( ',', array_unique($expolded_question_array) ); } } - + $quiz_name_by_question = array(); if ( ! empty($comma_seprated_ids) ) { $quiz_results = $wpdb->get_results( "SELECT `quiz_id`, `question_id` FROM `{$wpdb->prefix}mlw_questions` WHERE `question_id` IN (" .$comma_seprated_ids. ")" ); @@ -576,7 +576,7 @@ function qsm_rest_get_questions( WP_REST_Request $request ) { if ( ! empty($linked_question_ids) ) { $quiz_results = $wpdb->get_results( "SELECT `quiz_id`, `question_id` FROM `{$wpdb->prefix}mlw_questions` WHERE `question_id` IN (" . implode( ',', $linked_question_ids ) . ")" ); foreach ( $quiz_results as $value ) { - if ( ! in_array($value->question_id, $procesed_question_ids) ) { + if ( ! in_array( intval( $value->question_id ), $procesed_question_ids, true) ) { $quiz_name_in_loop = $wpdb->get_row( $wpdb->prepare( "SELECT quiz_name FROM {$wpdb->prefix}mlw_quizzes WHERE quiz_id = %d", $value->quiz_id ), ARRAY_A ); $quiz_name_in_loop = isset( $quiz_name_in_loop['quiz_name'] ) ? $quiz_name_in_loop['quiz_name'] : ''; $quiz_name_by_question[] = $quiz_name_in_loop; @@ -655,7 +655,7 @@ function qsm_rest_create_question( WP_REST_Request $request ) { 'category' => $request['category'], 'multicategories' => $request['multicategories'], 'linked_question' => $request['merged_question'], - 'is_linking' => $request['is_linking'], + 'is_linking' => $request['is_linking'], ); $settings = array( 'required' => $request['required'], diff --git a/readme.txt b/readme.txt index 2e1b4b3d5..ff134883d 100644 --- a/readme.txt +++ b/readme.txt @@ -238,7 +238,7 @@ As a WordPress quiz maker, QSM is designed to be compatible with most other plug 18. Database == Changelog == -= 9.2.0 ( October 04, 2024 ) = += 9.2.0 ( October 07, 2024 ) = * Feature: Added an option to link a question to multiple quizzes * Bug: Resolved HTML tag issue with the %USER_ANSWER% variable * Bug: Fixed the issue with contact form position settings From 1ee66de117b65a59fda1bda6ceb0d426cb7759b3 Mon Sep 17 00:00:00 2001 From: PranavAwasthi Date: Mon, 7 Oct 2024 18:50:49 +0530 Subject: [PATCH 46/49] Added two hooks --- php/admin/options-page-style-tab.php | 1 + php/admin/options-page-text-tab.php | 1 + 2 files changed, 2 insertions(+) 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() {
  • +
    From 170500ac34f93b6aca115314fe4e2e32000e04b7 Mon Sep 17 00:00:00 2001 From: Mohammad Zubair Ali Date: Mon, 7 Oct 2024 19:01:29 +0530 Subject: [PATCH 47/49] fixed issue with delete quiz permission --- php/classes/class-qmn-quiz-creator.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/classes/class-qmn-quiz-creator.php b/php/classes/class-qmn-quiz-creator.php index 2a17e95dd..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_qsm_quiz', $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; } From 283360f4b127cddbae3b0dc53a1a169b510fc048 Mon Sep 17 00:00:00 2001 From: etchirag Date: Mon, 7 Oct 2024 19:36:34 +0530 Subject: [PATCH 48/49] Fixed issue with importing quetoins --- js/qsm-admin.js | 23 +++++++++++++++++++++++ php/rest-api.php | 3 ++- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/js/qsm-admin.js b/js/qsm-admin.js index 2cd08aab8..4bf0de555 100644 --- a/js/qsm-admin.js +++ b/js/qsm-admin.js @@ -2029,6 +2029,26 @@ var qsm_link_button; } if ( 1 > questions.length ) { $('#question-bank').append('
    ' + qsm_admin_messages.questions_not_found + '
    '); + } else { + $('.question-bank-question').each(function () { + let questionId = $(this).data('question-id'); + if (QSMQuestion.questions.some(q => q.get('id') == questionId)) { + let $linkButton = $(this).find('.link-question'); + if ($linkButton.length) { + $linkButton.prop('disabled', true).addClass('disabled'); + } + } + QSMQuestion.questions.each(function (question) { + let merged_questions = question.get('merged_question'); + let questionsArray = merged_questions ? merged_questions.split(',').map(q => q.trim()) : []; + questionsArray.forEach(function (id) { + let parentElement = $('.question-bank-question[data-question-id="' + id + '"]'); + if (parentElement.length) { + parentElement.remove(); // Remove the element if it exists + } + }); + }); + }); } }, addQuestionToQuestionBank: function (question) { @@ -3324,6 +3344,7 @@ var qsm_link_button; }); jQuery(document).on('click', '.qsm-linked-list-div-block .qsm-unlink-the-question', function () { + var to_be_unlink_question = jQuery(this).data('question-id'); $.ajax({ url: ajaxurl, method: 'POST', @@ -3334,6 +3355,8 @@ var qsm_link_button; }, success: function (response) { $(document).find('.qsm-linked-list-div-block').remove(); + let question = QSMQuestion.questions.get(to_be_unlink_question); + question.set('merged_question', ''); } }); }); diff --git a/php/rest-api.php b/php/rest-api.php index d59d4d80b..4970dda8f 100644 --- a/php/rest-api.php +++ b/php/rest-api.php @@ -500,7 +500,8 @@ function qsm_rest_get_question( WP_REST_Request $request ) { if ( isset( $question['linked_question'] ) && '' == $question['linked_question'] ) { $comma_seprated_ids = $is_linking; } else { - $expolded_question_array = explode(',', $question['linked_question']); + $linked_question = isset($question['linked_question']) ? $question['linked_question'] : ''; + $exploded_question_array = explode(',', $linked_question); $expolded_question_array[] = $is_linking; $comma_seprated_ids = implode( ',', array_unique($expolded_question_array) ); } From 6c727e7be0d6908c911ad2a16020efa1d86dbebd Mon Sep 17 00:00:00 2001 From: etchirag Date: Mon, 7 Oct 2024 20:55:53 +0530 Subject: [PATCH 49/49] Removed linked question functionality from dev branch --- css/qsm-admin.css | 85 --------- js/qsm-admin.js | 102 +---------- mlw_quizmaster2.php | 5 - php/admin/options-page-questions-tab.php | 216 +---------------------- php/classes/class-qsm-install.php | 9 - php/classes/class-qsm-questions.php | 107 ++++------- php/rest-api.php | 56 +----- 7 files changed, 46 insertions(+), 534 deletions(-) diff --git a/css/qsm-admin.css b/css/qsm-admin.css index dcc71bd42..f15f72b61 100644 --- a/css/qsm-admin.css +++ b/css/qsm-admin.css @@ -1459,91 +1459,6 @@ td.scheduled_time_start { box-sizing: border-box; } -#post-body-content .qsm-popup-upgrade-warning img { - width: auto; - height: 15px; - margin-right: 8px; -} - -.qsm-linked-list-div-block { - padding: 4px; - margin: 5px 0; - margin-top: -20px; - width: max-content; - background-color: #ffe684; - border-radius: 2px; -} - -span.qsm-linked-list-view-button { - cursor: pointer; - color: #135e96; - text-decoration: underline; - font-weight: 500; -} - -span.qsm-linked-list-item { - margin: 0 0 5px 0; - padding: 5px; - background: #f0f0f1; -} - -div.qsm-linked-list-inside span.qsm-unlink-the-question { - color: #DC3232; - font-weight: 500; - max-width: 60px; - cursor: pointer; -} - -.qsm-linked-list-div-block p { - margin: 0; - font-size: 13px; - color: #856404; -} - -.qsm-linked-list-container { - position: absolute; -} - -.qsm-linked-list-div-block .qsm-linked-list-inside { - position: relative; - right: -155px; - top: 20px; - z-index: 999; - width: 350px; - padding: 10px; - box-sizing: border-box; - border-radius: 4px; - background: #ffffff; - border: 1px solid #dfd4d4; - box-shadow: 0 0 6px 2px #ddd; - display: grid; - grid-template-columns: 1fr; -} - -.qsm-linked-list-div-block .qsm-linked-list-inside:before { - content: " "; - position: absolute; - top: -24px; - left: 28%; - margin-left: -12px; - border-width: 12px; - border-style: solid; - border-color: transparent transparent #ffffff transparent; - z-index: 1; -} - -.qsm-linked-list-div-block .qsm-linked-list-inside:after { - content: " "; - position: absolute; - top: -26px; - left: 28%; - margin-left: -12px; - border-width: 12px; - border-style: solid; - border-color: transparent transparent #dfd4d4 transparent; - z-index: 0; -} - .qsm-text-main-wrap #postbox-container-1 { position: relative; diff --git a/js/qsm-admin.js b/js/qsm-admin.js index 4bf0de555..277e3378e 100644 --- a/js/qsm-admin.js +++ b/js/qsm-admin.js @@ -1899,7 +1899,6 @@ var QSMContact; */ var QSMQuestion; var import_button; -var qsm_link_button; (function ($) { if (jQuery('body').hasClass('admin_page_mlw_quiz_options')) { if (window.location.href.indexOf('&tab') == -1 || window.location.href.indexOf('tab=questions') > 0) { @@ -2029,26 +2028,6 @@ var qsm_link_button; } if ( 1 > questions.length ) { $('#question-bank').append('
    ' + qsm_admin_messages.questions_not_found + '
    '); - } else { - $('.question-bank-question').each(function () { - let questionId = $(this).data('question-id'); - if (QSMQuestion.questions.some(q => q.get('id') == questionId)) { - let $linkButton = $(this).find('.link-question'); - if ($linkButton.length) { - $linkButton.prop('disabled', true).addClass('disabled'); - } - } - QSMQuestion.questions.each(function (question) { - let merged_questions = question.get('merged_question'); - let questionsArray = merged_questions ? merged_questions.split(',').map(q => q.trim()) : []; - questionsArray.forEach(function (id) { - let parentElement = $('.question-bank-question[data-question-id="' + id + '"]'); - if (parentElement.length) { - parentElement.remove(); // Remove the element if it exists - } - }); - }); - }); } }, addQuestionToQuestionBank: function (question) { @@ -2062,22 +2041,19 @@ var qsm_link_button; type: question.type, question: questionText, category: question.category, - quiz_name: question.quiz_name, - linked_question: question.linked_question.join(',') + quiz_name: question.quiz_name })); }, - addQuestionFromQuestionBank: function (questionID, is_linking = 0) { + addQuestionFromQuestionBank: function (questionID) { QSMAdmin.displayAlert(qsm_admin_messages.adding_question, 'info'); - let isLinkingData = is_linking == 1 ? questionID : 0; var model = new QSMQuestion.question({ - id: questionID, - is_linking: isLinkingData + id: questionID }); model.fetch({ headers: { 'X-WP-Nonce': qsmQuestionSettings.nonce }, - url: wpApiSettings.root + 'quiz-survey-master/v1/questions/' + questionID + '?is_linking=' + isLinkingData, + url: wpApiSettings.root + 'quiz-survey-master/v1/questions/' + questionID, success: QSMQuestion.questionBankSuccess, error: QSMAdmin.displayError }); @@ -2269,18 +2245,10 @@ var qsm_link_button; if(import_button){ import_button.html(qsm_admin_messages.add_question); } - if(qsm_link_button) { - qsm_link_button.html(qsm_admin_messages.link_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')); - console.log(qsm_link_button); - if(qsm_link_button == ''){ - $(document).find('.qsm-linked-list-inside').hide().empty(); - $(document).find('.qsm-linked-list-div-block').hide(); - } // $('#save-popup-button').trigger('click'); }, addNewQuestion: function (model) { @@ -2816,31 +2784,6 @@ var qsm_link_button; $('#image_size_area').show(); } - let link_quizzes_array = question.get('link_quizzes'); - - $('.qsm-linked-list-inside').hide().empty(); - $('.qsm-linked-list-div-block').hide(); - if (typeof link_quizzes_array == 'object' && link_quizzes_array != null && Object.keys(link_quizzes_array).length > 0) { - Object.values(link_quizzes_array).forEach(function(quizName) { - // Ensure each quizName is a valid non-empty string - if (quizName && typeof quizName == 'string' && quizName.trim().length > 0) { - let link = $('') - .attr('class', 'qsm-linked-list-item') - .attr('title', quizName) - .text(quizName.length > 25 ? quizName.substring(0, 25) + '...' : quizName); - - $('.qsm-linked-list-div-block').show(); - $('.qsm-linked-list-inside').append(link); - } - }); - - // Add an "Unlink" link at the end - let unlink = $('') - .attr('class', 'qsm-unlink-the-question button button-danger') - .attr('data-question-id', questionID) - .text(qsm_admin_messages.unlink_question); - $('.qsm-linked-list-inside').append(unlink); - } jQuery(document).trigger('qsm_open_edit_popup', [questionID, CurrentElement]); }, openEditPagePopup: function (pageID) { @@ -3317,7 +3260,6 @@ var qsm_link_button; $(document).on('click', '.qsm-popup-bank .import-button', function (event) { event.preventDefault(); - qsm_link_button = ''; $(this).text(qsm_admin_messages.adding_question); import_button = $(this); $('.import-button').addClass('disable_import'); @@ -3325,45 +3267,9 @@ var qsm_link_button; MicroModal.close('modal-2'); }); - - $(document).on('click', '.qsm-popup-bank .link-question', function (event) { - event.preventDefault(); - $(this).text(qsm_admin_messages.linking_question); - qsm_link_button = $(this); - $('.link-question').addClass('disable_import'); - // 1 for the linking the questions default is 0 - QSMQuestion.addQuestionFromQuestionBank($(this).data('question-id'), 1); - MicroModal.close('modal-2'); - }); - - jQuery(document).on('click', '.qsm-linked-list-div-block .qsm-linked-list-view-button', function () { - let $this = jQuery(this); - let $inside = $this.parents('.qsm-linked-list-div-block').find('.qsm-linked-list-inside'); - $inside.toggle(); - $inside.is(':visible') ? $this.text(qsmQuestionSettings.linked_close) : $this.text(qsmQuestionSettings.linked_view); - }); - - jQuery(document).on('click', '.qsm-linked-list-div-block .qsm-unlink-the-question', function () { - var to_be_unlink_question = jQuery(this).data('question-id'); - $.ajax({ - url: ajaxurl, - method: 'POST', - data: { - action: 'qsm_unlink_question_from_list', - question_id: jQuery(this).data('question-id'), - nonce: qsmQuestionSettings.unlinkNonce - }, - success: function (response) { - $(document).find('.qsm-linked-list-div-block').remove(); - let question = QSMQuestion.questions.get(to_be_unlink_question); - question.set('merged_question', ''); - } - }); - }); //Click on selected question button. $('.qsm-popup-bank').on('click', '#qsm-import-selected-question', function (event) { var $total_selction = $('#question-bank').find('[name="qsm-question-checkbox[]"]:checked').length; - qsm_link_button = ''; if ($total_selction === 0) { alert(qsm_admin_messages.no_question_selected); } else { diff --git a/mlw_quizmaster2.php b/mlw_quizmaster2.php index 57d77da8a..ce63fc21e 100644 --- a/mlw_quizmaster2.php +++ b/mlw_quizmaster2.php @@ -525,13 +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', 'quiz-master-next'), 'question_created' => __('Question created!', 'quiz-master-next'), 'new_question' => __('Your new question!', 'quiz-master-next'), - 'unlink_question' => __('Unlink', 'quiz-master-next'), - 'adding_question' => __('Adding...', 'quiz-master-next'), - 'linking_question' => __('Linking...', 'quiz-master-next'), - 'link_question' => __('Link', 'quiz-master-next'), 'creating_question' => __('Creating question...', 'quiz-master-next'), 'duplicating_question' => __('Duplicating question...', 'quiz-master-next'), 'saving_question' => __('Saving question...', 'quiz-master-next'), diff --git a/php/admin/options-page-questions-tab.php b/php/admin/options-page-questions-tab.php index 5139748ca..4ad17e243 100644 --- a/php/admin/options-page-questions-tab.php +++ b/php/admin/options-page-questions-tab.php @@ -88,14 +88,11 @@ function qsm_options_questions_tab_content() { $json_data = array( 'quizID' => $quiz_id, 'answerText' => __( 'Answer', 'quiz-master-next' ), - 'linked_view' => __( 'View', 'quiz-master-next' ), - 'linked_close' => __( 'Close', 'quiz-master-next' ), 'nonce' => wp_create_nonce( 'wp_rest' ), 'pages' => $pages, 'qpages' => $qpages, 'qsm_user_ve' => get_user_meta( $user_id, 'rich_editing', true ), 'saveNonce' => wp_create_nonce( 'ajax-nonce-sandy-page' ), - 'unlinkNonce' => wp_create_nonce( 'ajax-nonce-unlink-question' ), 'categories' => $question_categories, 'form_type' => $form_type, 'quiz_system' => $quiz_system, @@ -283,12 +280,6 @@ class="save-page-button button button-primary">
    -
    -

    -
    -
    -
    -
    @@ -884,80 +875,6 @@ class="save-page-button button button-primary"> __( - 'Nonce verification failed.', - 'quiz-master-next' - ), - )); - } - $question_id = isset( $_POST['question_id'] ) ? intval( $_POST['question_id'] ) : 0; - if ( $question_id > 0 ) { - qsm_process_unlink_question_from_list_by_question_id($question_id); - wp_send_json_success( array( - 'message' => __( - 'Question is unlinked from all quizzes.', - 'quiz-master-next' - ), - )); - } else { - wp_send_json_error( array( - 'message' => __( - 'Invalid question ID.', - 'quiz-master-next' - ), - )); - } -} -add_action( 'wp_ajax_qsm_unlink_question_from_list', 'qsm_ajax_unlink_question_from_list' ); - -/** - * Unlinks a question from all quizzes it is associated with. - * @since 9.1.3 - * @param int $question_id The ID of the question to unlink. - * @return void - */ -function qsm_process_unlink_question_from_list_by_question_id( $question_id ) { - global $wpdb; - $current_linked_questions = $wpdb->get_var( $wpdb->prepare( - "SELECT linked_question FROM {$wpdb->prefix}mlw_questions WHERE question_id = %d", - $question_id - ) ); - - if ( $current_linked_questions ) { - $current_links = explode(',', $current_linked_questions); - $current_links = array_map('trim', $current_links); - $current_links = array_diff($current_links, [ $question_id ]); - $updated_linked_list = implode(',', array_filter($current_links)); - $linked_ids = explode(',', $updated_linked_list); - foreach ( $linked_ids as $linked_id ) { - $wpdb->update( - $wpdb->prefix . 'mlw_questions', - array( 'linked_question' => $updated_linked_list ), - array( 'question_id' => intval($linked_id) ), - array( '%s' ), - array( '%d' ) - ); - } - $wpdb->update( - $wpdb->prefix . 'mlw_questions', - array( 'linked_question' => '' ), - array( 'question_id' => intval($question_id) ), - array( '%s' ), - array( '%d' ) - ); - } -} - /** * Saves the pages and order from the Questions tab * @@ -1173,36 +1090,11 @@ function qsm_delete_question_from_database() { if ( ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['nonce'] ) ), 'delete_question_from_database' ) ) { wp_send_json_error( __( 'Nonce verification failed.', 'quiz-master-next' ) ); } - $base_question_id = $question_id = isset( $_POST['question_id'] ) ? intval( $_POST['question_id'] ) : 0; + $question_id = isset( $_POST['question_id'] ) ? intval( $_POST['question_id'] ) : 0; if ( $question_id ) { global $wpdb, $mlwQuizMasterNext; - $update_qpages_after_delete = array(); - $dependent_question_ids = qsm_get_unique_linked_question_ids_to_remove(array( $question_id ) ); - $question_id = array_merge($dependent_question_ids, array( $question_id ) ); - $question_id = array_unique($question_id); - $question_id = array_filter($question_id); - $placeholders = array_fill( 0, count( $question_id ), '%d' ); - if ( ! empty($dependent_question_ids) ) { - $dependent_question_ids = array_diff($dependent_question_ids, [ $base_question_id ] ); - $update_qpages_after_delete = qsm_process_to_update_qpages_after_unlink($dependent_question_ids); - } - // Construct the query with placeholders - $query = sprintf( - "DELETE FROM {$wpdb->prefix}mlw_questions WHERE question_id IN (%s)", - implode( ', ', $placeholders ) - ); - - // Prepare the query - $query = $wpdb->prepare( $query, $question_id ); - $results = $wpdb->query( $query ); + $results = $wpdb->delete( $wpdb->prefix . 'mlw_questions', array( 'question_id' => $question_id ) ); if ( $results ) { - if ( ! empty($update_qpages_after_delete) ) { - foreach ( $update_qpages_after_delete as $quiz_id => $aftervalue ) { - $mlwQuizMasterNext->pluginHelper->prepare_quiz( $quiz_id ); - $mlwQuizMasterNext->pluginHelper->update_quiz_setting( 'qpages', $aftervalue['qpages'] ); - $mlwQuizMasterNext->pluginHelper->update_quiz_setting( 'pages', $aftervalue['pages'] ); - } - } wp_send_json_success( __( 'Question removed Successfully.', 'quiz-master-next' ) ); }else { wp_send_json_error( __( 'Question delete failed!', 'quiz-master-next' ) ); @@ -1241,20 +1133,10 @@ function qsm_bulk_delete_question_from_database() { } ); // Sanitize and validate the IDs - $base_question_ids = $question_id = array_map( 'intval', $question_id ); + $question_id = array_map( 'intval', $question_id ); - if ( ! empty( $question_id ) ) { - global $wpdb; - $update_qpages_after_delete = array(); - $dependent_question_ids = qsm_get_unique_linked_question_ids_to_remove($question_id); - if ( ! empty($dependent_question_ids) ) { - $dependent_question_ids = array_diff($dependent_question_ids, [ $base_question_ids ] ); - $update_qpages_after_delete = qsm_process_to_update_qpages_after_unlink($dependent_question_ids); - } - $question_id = array_merge($dependent_question_ids, $question_id); - $question_id = array_unique($question_id); // Ensure all IDs are unique - $question_id = array_filter($question_id); // Remove empty values - + if ( ! empty( $question_id ) ) { + // Generate placeholders for each ID $placeholders = array_fill( 0, count( $question_id ), '%d' ); // Construct the query with placeholders @@ -1268,13 +1150,6 @@ function qsm_bulk_delete_question_from_database() { $results = $wpdb->query( $query ); if ( $results ) { - if ( ! empty($update_qpages_after_delete) ) { - foreach ( $update_qpages_after_delete as $quiz_id => $aftervalue ) { - $mlwQuizMasterNext->pluginHelper->prepare_quiz( $quiz_id ); - $mlwQuizMasterNext->pluginHelper->update_quiz_setting( 'qpages', $aftervalue['qpages'] ); - $mlwQuizMasterNext->pluginHelper->update_quiz_setting( 'pages', $aftervalue['pages'] ); - } - } wp_send_json_success( __( 'Questions removed Successfully.', 'quiz-master-next' ) ); }else { $mlwQuizMasterNext->log_manager->add( __('Error 0001 delete questions failed - question IDs:', 'quiz-master-next') . $question_id, '
    Error:' . $wpdb->last_error . ' from ' . $wpdb->last_query, 0, 'error' ); @@ -1286,82 +1161,6 @@ function qsm_bulk_delete_question_from_database() { } add_action( 'wp_ajax_qsm_bulk_delete_question_from_database', 'qsm_bulk_delete_question_from_database' ); -/** - * returns pages and qpages for dependent question ids for update after deleting questions - * - * @param array $dependent_question_ids An array of question IDs. - * @since 9.1.3 - */ -function qsm_process_to_update_qpages_after_unlink( $dependent_question_ids ) { - $comma_seprated_ids = implode( ',', array_unique($dependent_question_ids) ); - $qpages_array = array(); - if ( ! empty($comma_seprated_ids) ) { - global $wpdb, $mlwQuizMasterNext; - $quiz_results = $wpdb->get_results( "SELECT `quiz_id`, `question_id` FROM `{$wpdb->prefix}mlw_questions` WHERE `question_id` IN (" .$comma_seprated_ids. ")" ); - if ( ! empty($quiz_results) ) { - foreach ( $quiz_results as $single_quiz ) { - $quiz_id = $single_quiz->quiz_id; - $mlwQuizMasterNext->pluginHelper->prepare_quiz( $quiz_id ); - $pages = $mlwQuizMasterNext->pluginHelper->get_quiz_setting( 'pages', array() ); - $clone_qpages = $qpages = $mlwQuizMasterNext->pluginHelper->get_quiz_setting( 'qpages', array() ); - if ( ! empty($clone_qpages) ) { - foreach ( $clone_qpages as $clonekey => $clonevalue ) { - if ( ! empty($clonevalue['questions']) && in_array($single_quiz->question_id, $clonevalue['questions']) ) { - $clone_qpages[ $clonekey ]['questions'] = array_diff($clonevalue['questions'], [ $single_quiz->question_id ]); - $pages[ $clonekey ] = array_diff($pages[ $clonekey ], [ $single_quiz->question_id ]); - } - } - $qpages = $clone_qpages; - } - //merge duplicate questions - $all_questions = array(); - foreach ( $pages as $page_key => $questions ) { - $page_questions = array(); - $questions = array_unique( $questions ); - foreach ( $questions as $id ) { - if ( ! in_array( $id, $all_questions, true ) ) { - $page_questions[] = $id; - } - } - $all_questions = array_merge( $all_questions, $questions ); - $pages[ $page_key ] = $page_questions; - if ( isset( $qpages[ $page_key ] ) ) { - $qpages[ $page_key ]['questions'] = $page_questions; - } - } - $qpages_array[ $quiz_id ] = array( - 'pages' => $pages, - 'qpages' => $qpages, - ); - } - } - } - return $qpages_array; -} - -/** - * Get Unique Linked Question IDs - * - * @param array $question_ids An array of question IDs to query for linked questions. - * @return array $unique_ids An array of unique question IDs extracted from the linked questions. - * @since 9.1.3 - */ -function qsm_get_unique_linked_question_ids_to_remove( $question_ids ) { - global $wpdb; - $all_ids = array(); - foreach ( $question_ids as $id ) { - $sql = $wpdb->prepare( - "SELECT linked_question FROM {$wpdb->prefix}mlw_questions WHERE question_id = %d", - $id - ); - $linked_question = $wpdb->get_var($sql); - if ( ! empty($linked_question) ) { - $all_ids = array_merge($all_ids, explode(',', $linked_question)); - } - } - return $all_ids; -} - add_action( 'wp_ajax_save_new_category', 'qsm_save_new_category' ); function qsm_save_new_category() { $category = isset( $_POST['name'] ) ? sanitize_text_field( wp_unslash( $_POST['name'] ) ) : ''; @@ -1441,10 +1240,7 @@ function qsm_options_questions_tab_template() {

    {{{data.question}}}

    Quiz Name: {{data.quiz_name}} <# if ( data.category != '' ) { #> Category: {{data.category}} <# } #>

    -
    - - -
    +
    diff --git a/php/classes/class-qsm-install.php b/php/classes/class-qsm-install.php index 7abd66c04..134d91bc3 100644 --- a/php/classes/class-qsm-install.php +++ b/php/classes/class-qsm-install.php @@ -2038,15 +2038,6 @@ public function update() { } update_option( 'mlw_quiz_master_version', $data ); - - // Update 9.1.3 - $mlw_questions_table = $wpdb->prefix . 'mlw_questions'; - if ( 'linked_question' != $wpdb->get_var( "SHOW COLUMNS FROM $mlw_questions_table LIKE 'linked_question'" ) ) { - $sql = 'ALTER TABLE ' . $mlw_questions_table . ' ADD linked_question TEXT NULL DEFAULT \'\' AFTER category'; - $results = $mlwQuizMasterNext->wpdb_alter_table_query( $sql ); - $update_sql = 'UPDATE ' . $mlw_questions_table . ' SET linked_question = \'\' WHERE linked_question IS NULL'; - $results = $mlwQuizMasterNext->wpdb_alter_table_query( $update_sql ); - } } if ( ! get_option( 'mlw_advert_shows' ) ) { add_option( 'mlw_advert_shows', 'true' ); diff --git a/php/classes/class-qsm-questions.php b/php/classes/class-qsm-questions.php index a0cabf383..52f6441e5 100644 --- a/php/classes/class-qsm-questions.php +++ b/php/classes/class-qsm-questions.php @@ -270,7 +270,6 @@ private static function create_save_question( $data, $answers, $settings, $is_cr 'order' => 1, 'category' => '', 'multicategories' => '', - 'linked_question' => '', ); $data = wp_parse_args( $data, $defaults ); @@ -298,14 +297,6 @@ private static function create_save_question( $data, $answers, $settings, $is_cr if ( $trim_question_description ) { $question_name = trim( preg_replace( '/\s+/', ' ', $question_name ) ); } - $linked_question = sanitize_text_field( $data['linked_question'] ); - if ( $is_creating && isset($data['is_linking']) ) { - if ( 1 <= $data['is_linking'] ) { - $linked_question = $data['is_linking']; - }elseif ( 0 == $data['is_linking'] ) { - $linked_question = ''; - } - } $values = array( 'quiz_id' => intval( $data['quiz_id'] ), @@ -318,11 +309,10 @@ private static function create_save_question( $data, $answers, $settings, $is_cr 'question_type_new' => sanitize_text_field( $data['type'] ), 'question_settings' => maybe_serialize( $settings ), 'category' => sanitize_text_field( $data['category'] ), - 'linked_question' => $linked_question, 'deleted' => 0, ); $values = apply_filters( 'qsm_save_question_data', $values ); - + $types = array( '%d', '%s', @@ -334,7 +324,6 @@ private static function create_save_question( $data, $answers, $settings, $is_cr '%s', '%s', '%s', - '%s', '%d', ); @@ -362,74 +351,44 @@ private static function create_save_question( $data, $answers, $settings, $is_cr throw new Exception( $msg ); } - $base_question_id = $question_id; - $quiz_questions_array = array(); - $quiz_questions_array[ intval( $data['quiz_id'] ) ] = $question_id; - $linked_questions_array[] = $question_id; - if ( isset($linked_question) && "" != $linked_question ) { - $expolded_question_array = explode(',', $linked_question); - $linked_questions_array = array_merge($expolded_question_array, $linked_questions_array); - // preparing array for quiz question id - $imploded_question_ids = implode( ',', array_unique($linked_questions_array) ); - if ( ! empty($linked_questions_array) ) { - $quiz_results = $wpdb->get_results( "SELECT `quiz_id`, `question_id` FROM `{$wpdb->prefix}mlw_questions` WHERE `question_id` IN (" . $imploded_question_ids . ")" ); - foreach ( $quiz_results as $key => $value ) { - $quiz_questions_array[ $value->quiz_id ] = $value->question_id; - } - } - $values['linked_question'] = $imploded_question_ids; - } + /** + * Process Question Categories + */ $question_terms_table = $wpdb->prefix . 'mlw_question_terms'; - foreach ( $quiz_questions_array as $quiz_id => $question_id_loop ) { - $values['quiz_id'] = intval( $quiz_id ); - $wpdb->update( - $wpdb->prefix . 'mlw_questions', - $values, - array( 'question_id' => intval($question_id_loop) ), - $types, - array( '%d' ) - ); - - /** - * Process Question Categories - */ - - $wpdb->delete( - $question_terms_table, - array( - 'question_id' => $question_id_loop, + $wpdb->delete( + $question_terms_table, + array( + 'question_id' => $question_id, + 'taxonomy' => 'qsm_category', + ) + ); + if ( ! empty( $data['multicategories'] ) ) { + foreach ( $data['multicategories'] as $term_id ) { + $term_rel_data = array( + 'question_id' => $question_id, + 'quiz_id' => intval( $data['quiz_id'] ), + 'term_id' => $term_id, 'taxonomy' => 'qsm_category', - ) - ); - if ( ! empty( $data['multicategories'] ) ) { - foreach ( $data['multicategories'] as $term_id ) { - $term_rel_data = array( - 'question_id' => $question_id_loop, - 'quiz_id' => intval( $quiz_id ), - 'term_id' => $term_id, - 'taxonomy' => 'qsm_category', - ); - // Check if the data already exists in the table - $data_exists = $wpdb->get_row($wpdb->prepare("SELECT * FROM $question_terms_table WHERE question_id = %s AND quiz_id = %s AND term_id = %s AND taxonomy = %s", $question_id_loop, intval( $quiz_id ), $term_id, 'qsm_category' )); - if ( ! $data_exists ) { - $wpdb->insert( $question_terms_table, $term_rel_data ); - } + ); + // Check if the data already exists in the table + $data_exists = $wpdb->get_row($wpdb->prepare("SELECT * FROM $question_terms_table WHERE question_id = %s AND quiz_id = %s AND term_id = %s AND taxonomy = %s", $question_id, intval( $data['quiz_id'] ), $term_id, 'qsm_category' )); + if ( ! $data_exists ) { + $wpdb->insert( $question_terms_table, $term_rel_data ); } } + } - /** - * Hook after saving question - */ - - if ( $is_creating && $base_question_id == $question_id_loop ) { - do_action( 'qsm_question_added', $question_id_loop, $values ); - } else { - do_action( 'qsm_question_updated', $question_id_loop, $values ); - } - do_action( 'qsm_saved_question', $question_id_loop, $values ); - + /** + * Hook after saving question + */ + if ( $is_creating ) { + do_action( 'qsm_question_added', $question_id, $values ); + } else { + do_action( 'qsm_question_updated', $question_id, $values ); } - return $base_question_id; + do_action( 'qsm_saved_question', $question_id, $values ); + + return $question_id; } /** diff --git a/php/rest-api.php b/php/rest-api.php index 4970dda8f..53f1bd935 100644 --- a/php/rest-api.php +++ b/php/rest-api.php @@ -271,7 +271,6 @@ function qsm_rest_get_bank_questions( WP_REST_Request $request ) { 'file_upload_type' => isset( $question['settings']['file_upload_type'] ) ? $question['settings']['file_upload_type'] : '', 'quiz_name' => isset( $quiz_name['quiz_name'] ) ? $quiz_name['quiz_name'] : '', 'question_title' => isset( $question['settings']['question_title'] ) ? $question['settings']['question_title'] : '', - 'linked_question' => array_filter( isset( $question['linked_question'] ) ? explode(',', $question['linked_question']) : array() ), ); $question_data = apply_filters( 'qsm_rest_api_filter_question_data', $question_data, $question, $request ); $question_array['questions'][] = $question_data; @@ -488,34 +487,11 @@ function qsm_rest_save_results( WP_REST_Request $request ) { function qsm_rest_get_question( WP_REST_Request $request ) { // Makes sure user is logged in. if ( is_user_logged_in() ) { - global $wpdb; $current_user = wp_get_current_user(); if ( 0 !== $current_user ) { $question = QSM_Questions::load_question( $request['id'] ); $categorysArray = QSM_Questions::get_question_categories( $question['question_id'] ); if ( ! empty( $question ) ) { - $is_linking = $request['is_linking']; - $comma_seprated_ids = ''; - if ( 1 <= $is_linking ) { - if ( isset( $question['linked_question'] ) && '' == $question['linked_question'] ) { - $comma_seprated_ids = $is_linking; - } else { - $linked_question = isset($question['linked_question']) ? $question['linked_question'] : ''; - $exploded_question_array = explode(',', $linked_question); - $expolded_question_array[] = $is_linking; - $comma_seprated_ids = implode( ',', array_unique($expolded_question_array) ); - } - } - - $quiz_name_by_question = array(); - if ( ! empty($comma_seprated_ids) ) { - $quiz_results = $wpdb->get_results( "SELECT `quiz_id`, `question_id` FROM `{$wpdb->prefix}mlw_questions` WHERE `question_id` IN (" .$comma_seprated_ids. ")" ); - foreach ( $quiz_results as $value ) { - $quiz_name_in_loop = $wpdb->get_row( $wpdb->prepare( "SELECT quiz_name FROM {$wpdb->prefix}mlw_quizzes WHERE quiz_id = %d", $value->quiz_id ), ARRAY_A ); - $quiz_name_in_loop = isset( $quiz_name_in_loop['quiz_name'] ) ? $quiz_name_in_loop['quiz_name'] : ''; - $quiz_name_by_question[] = $quiz_name_in_loop; - } - } $question['page'] = isset( $question['page'] ) ? $question['page'] : 0; $question = array( 'id' => $question['question_id'], @@ -532,8 +508,6 @@ function qsm_rest_get_question( WP_REST_Request $request ) { 'answers' => $question['answers'], 'page' => $question['page'], 'question_title' => isset( $question['settings']['question_title'] ) ? $question['settings']['question_title'] : '', - 'link_quizzes' => $quiz_name_by_question, - 'merged_question' => $comma_seprated_ids, ); } return $question; @@ -564,31 +538,12 @@ function qsm_rest_get_questions( WP_REST_Request $request ) { $questions = QSM_Questions::load_questions( 0 ); } global $wpdb; - $stored_quiz_names = $procesed_question_ids = $question_array = array(); + $question_array = array(); foreach ( $questions as $question ) { $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'] ); - $quiz_name = isset( $quiz_name['quiz_name'] ) ? $quiz_name['quiz_name'] : ''; - $quiz_name_by_question = array(); - $procesed_question_ids[] = $question['question_id']; - $stored_quiz_names[ $question['question_id'] ] = $quiz_name; - $linked_question_ids = array_filter( isset( $question['linked_question'] ) ? explode(',', $question['linked_question']) : array() ); - if ( ! empty($linked_question_ids) ) { - $quiz_results = $wpdb->get_results( "SELECT `quiz_id`, `question_id` FROM `{$wpdb->prefix}mlw_questions` WHERE `question_id` IN (" . implode( ',', $linked_question_ids ) . ")" ); - foreach ( $quiz_results as $value ) { - if ( ! in_array($value->question_id, $procesed_question_ids) ) { - $quiz_name_in_loop = $wpdb->get_row( $wpdb->prepare( "SELECT quiz_name FROM {$wpdb->prefix}mlw_quizzes WHERE quiz_id = %d", $value->quiz_id ), ARRAY_A ); - $quiz_name_in_loop = isset( $quiz_name_in_loop['quiz_name'] ) ? $quiz_name_in_loop['quiz_name'] : ''; - $quiz_name_by_question[] = $quiz_name_in_loop; - $procesed_question_ids[] = $value->question_id; - $stored_quiz_names[ $value->question_id ] = $quiz_name_in_loop; - } else { - $quiz_name_by_question[] = $stored_quiz_names[ $value->question_id ]; - } - } - } - $quiz_name_by_question = array_diff($quiz_name_by_question, [ $quiz_name ]); // remove current quiz id from the list + $question_data = array( 'id' => $question['question_id'], 'quizID' => $question['quiz_id'], @@ -611,13 +566,11 @@ function qsm_rest_get_questions( WP_REST_Request $request ) { 'limit_multiple_response' => isset( $question['settings']['limit_multiple_response'] ) ? $question['settings']['limit_multiple_response'] : 0, 'file_upload_limit' => isset( $question['settings']['file_upload_limit'] ) ? $question['settings']['file_upload_limit'] : 0, 'file_upload_type' => isset( $question['settings']['file_upload_type'] ) ? $question['settings']['file_upload_type'] : '', - 'quiz_name' => $quiz_name, + 'quiz_name' => isset( $quiz_name['quiz_name'] ) ? $quiz_name['quiz_name'] : '', 'question_title' => isset( $question['settings']['question_title'] ) ? $question['settings']['question_title'] : '', 'featureImageID' => isset( $question['settings']['featureImageID'] ) ? $question['settings']['featureImageID'] : '', 'featureImageSrc' => isset( $question['settings']['featureImageSrc'] ) ? $question['settings']['featureImageSrc'] : '', 'settings' => $question['settings'], - 'link_quizzes' => $quiz_name_by_question, - 'merged_question' => implode(",", $linked_question_ids), ); $question_data = apply_filters( 'qsm_rest_api_filter_question_data', $question_data, $question, $request ); $question_array[] = $question_data; @@ -655,8 +608,6 @@ function qsm_rest_create_question( WP_REST_Request $request ) { 'order' => 1, 'category' => $request['category'], 'multicategories' => $request['multicategories'], - 'linked_question' => $request['merged_question'], - 'is_linking' => $request['is_linking'], ); $settings = array( 'required' => $request['required'], @@ -720,7 +671,6 @@ function qsm_rest_save_question( WP_REST_Request $request ) { 'order' => 1, 'category' => $request['category'], 'multicategories' => $request['multicategories'], - 'linked_question' => $request['merged_question'], ); $settings = array(); $settings['answerEditor'] = $request['answerEditor'];