From af6429b9ce427a9ba50694dbce4a853d94babdb2 Mon Sep 17 00:00:00 2001 From: Mohammad Zubair Ali Date: Thu, 20 Jun 2024 12:52:28 +0530 Subject: [PATCH 1/4] fixed http_referer issue --- php/classes/class-qmn-quiz-manager.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/classes/class-qmn-quiz-manager.php b/php/classes/class-qmn-quiz-manager.php index 4b3303164..97817780d 100644 --- a/php/classes/class-qmn-quiz-manager.php +++ b/php/classes/class-qmn-quiz-manager.php @@ -1872,7 +1872,7 @@ public function qsm_get_quiz_to_reload() { */ private function add_quiz_results( $data ) { global $wpdb; - if ( empty( $wpdb ) || empty( $data['qmn_array_for_variables'] ) || empty( $data['results_array'] ) || empty( $data['unique_id'] ) || empty( $data['http_referer'] ) || ! isset( $data['form_type'] ) ) { + if ( empty( $wpdb ) || empty( $data['qmn_array_for_variables'] ) || empty( $data['results_array'] ) || empty( $data['unique_id'] ) || ! isset( $data['http_referer'] ) || ! isset( $data['form_type'] ) ) { return false; } From 54e06fd703e5f31d12f52db754d4cca371268152 Mon Sep 17 00:00:00 2001 From: Mohammad Zubair Ali Date: Thu, 27 Jun 2024 16:04:41 +0530 Subject: [PATCH 2/4] added function to check table structure --- mlw_quizmaster2.php | 103 +++++++++++++++++++++++++++++++++++++ php/template-variables.php | 4 +- 2 files changed, 105 insertions(+), 2 deletions(-) diff --git a/mlw_quizmaster2.php b/mlw_quizmaster2.php index 2b6a65ad5..616d2c4c6 100644 --- a/mlw_quizmaster2.php +++ b/mlw_quizmaster2.php @@ -784,6 +784,109 @@ public function admin_failed_submission_page() { $QmnFailedSubmissions->render_list_table(); } } + /** + * Check database structure + * + * @since 9.0.6 + * @return void + */ + public function qsm_check_database_structure() { + global $wpdb; + + // Define the table names + $quiz_table_name = $wpdb->prefix . 'mlw_quizzes'; + $question_table_name = $wpdb->prefix . 'mlw_questions'; + $results_table_name = $wpdb->prefix . 'mlw_results'; + $audit_table_name = $wpdb->prefix . 'mlw_qm_audit_trail'; + $themes_table_name = $wpdb->prefix . 'mlw_themes'; + $quiz_themes_settings_table_name = $wpdb->prefix . 'mlw_quiz_theme_settings'; + $question_terms_table_name = $wpdb->prefix . 'mlw_question_terms'; + + // List of tables and their columns + $tables = [ + $quiz_table_name => [ + 'quiz_id', 'quiz_name', 'message_before', 'message_after', 'message_comment', 'message_end_template', + 'user_email_template', 'admin_email_template', 'submit_button_text', 'name_field_text', 'business_field_text', + 'email_field_text', 'phone_field_text', 'comment_field_text', 'email_from_text', 'question_answer_template', + 'leaderboard_template', 'quiz_system', 'randomness_order', 'loggedin_user_contact', 'show_score', 'send_user_email', + 'send_admin_email', 'contact_info_location', 'user_name', 'user_comp', 'user_email', 'user_phone', 'admin_email', + 'comment_section', 'question_from_total', 'total_user_tries', 'total_user_tries_text', 'certificate_template', + 'social_media', 'social_media_text', 'pagination', 'pagination_text', 'timer_limit', 'quiz_stye', 'question_numbering', + 'quiz_settings', 'theme_selected', 'last_activity', 'require_log_in', 'require_log_in_text', 'limit_total_entries', + 'limit_total_entries_text', 'scheduled_timeframe', 'scheduled_timeframe_text', 'disable_answer_onselect', 'ajax_show_correct', + 'quiz_views', 'quiz_taken', 'deleted', 'quiz_author_id' + ], + $question_table_name => [ + 'question_id', 'quiz_id', 'question_name', 'answer_array', 'answer_one', 'answer_one_points', 'answer_two', + 'answer_two_points', 'answer_three', 'answer_three_points', 'answer_four', 'answer_four_points', 'answer_five', + 'answer_five_points', 'answer_six', 'answer_six_points', 'correct_answer', 'question_answer_info', 'comments', + 'hints', 'question_order', 'question_type', 'question_type_new', 'question_settings', 'category', 'deleted', + 'deleted_question_bank' + ], + $results_table_name => [ + 'result_id', 'quiz_id', 'quiz_name', 'quiz_system', 'point_score', 'correct_score', 'correct', 'total', 'name', + 'business', 'email', 'phone', 'user', 'user_ip', 'time_taken', 'time_taken_real', 'quiz_results', 'deleted', + 'unique_id', 'form_type', 'page_name', 'page_url' + ], + $audit_table_name => [ + 'trail_id', 'action_user', 'action', 'quiz_id', 'quiz_name', 'form_data', 'time' + ], + $themes_table_name => [ + 'id', 'theme', 'theme_name', 'default_settings', 'theme_active' + ], + $quiz_themes_settings_table_name => [ + 'id', 'theme_id', 'quiz_id', 'quiz_theme_settings', 'active_theme' + ], + $question_terms_table_name => [ + 'id', 'question_id', 'quiz_id', 'term_id', 'taxonomy' + ] + ]; + + // Check all tables + $errors = []; + foreach ($tables as $table_name => $columns) { + $error = $this->qsm_check_table_structure($table_name, $columns); + if ($error) { + $errors[] = $error; + } + } + + if (!empty($errors)) { + foreach ($errors as $error) { + echo esc_html($error) . "
"; + } + } else { + esc_html_e("All tables have the correct structure.", "quiz-master-next"); + update_option('qsm_check_database_structure', 1); + } + } + + /** + * Check if table and columns exist + * + * @since 9.0.6 + * @param string $table_name + * @param array $expected_columns + * @return string|null + */ + public function qsm_check_table_structure($table_name, $expected_columns) { + global $wpdb; + $columns = $wpdb->get_results("SHOW COLUMNS FROM $table_name"); + if (!$columns) { + return esc_html__("Table ", "quiz-master-next") . $table_name . esc_html__(" does not exist.", "quiz-master-next"); + } + $existing_columns = array_column($columns, 'Field'); + $missing_columns = []; + foreach ($expected_columns as $column) { + if (!in_array($column, $existing_columns)) { + $missing_columns[] = $column; + } + } + if (!empty($missing_columns)) { + return esc_html__("Table ", "quiz-master-next") . $table_name . esc_html__(" is missing columns: ", "quiz-master-next") . implode(', ', $missing_columns); + } + return null; + } /** * Failed Database queries diff --git a/php/template-variables.php b/php/template-variables.php index b1c22ce30..a4dc68f27 100644 --- a/php/template-variables.php +++ b/php/template-variables.php @@ -134,7 +134,7 @@ function qsm_variable_single_answer( $content, $mlw_quiz_array ) { $ser_answer = $wpdb->get_row( $wpdb->prepare( "SELECT question_settings FROM {$wpdb->prefix}mlw_questions WHERE question_id = %d", $question_id ), ARRAY_A ); $question_settings = qmn_sanitize_input_data( $ser_answer['question_settings'] ); $answerstr = ""; - if ( isset($answers['user_answer']) ) { + if ( isset($answers['user_answer']) && is_array($answers['user_answer']) ) { if ( 13 === intval( $answers['question_type'] ) ) { $answerstr .= $answers['points']; }elseif ( 12 === intval( $answers['question_type'] ) ) { @@ -510,7 +510,7 @@ function qsm_contact_field_variable( $content, $results_array ) { function qsm_all_contact_fields_variable( $content, $results ) { global $mlwQuizMasterNext; $contact_form = $mlwQuizMasterNext->pluginHelper->get_quiz_setting( 'contact_form' ); - + $return = ''; if ( isset( $results['contact'] ) && ( is_array( $results['contact'] ) || is_object( $results['contact'] ) ) ) { foreach ( $results['contact'] as $results_contact ) { From 48397644bc55929ed333d2831fc05a950ec674ef Mon Sep 17 00:00:00 2001 From: Mohammad Zubair Ali Date: Thu, 27 Jun 2024 16:13:32 +0530 Subject: [PATCH 3/4] fixed phpcs --- mlw_quizmaster2.php | 181 +++++++++++++++++++++++++++++-------- php/template-variables.php | 14 +-- 2 files changed, 150 insertions(+), 45 deletions(-) diff --git a/mlw_quizmaster2.php b/mlw_quizmaster2.php index 616d2c4c6..5108403eb 100644 --- a/mlw_quizmaster2.php +++ b/mlw_quizmaster2.php @@ -804,55 +804,160 @@ public function qsm_check_database_structure() { // List of tables and their columns $tables = [ - $quiz_table_name => [ - 'quiz_id', 'quiz_name', 'message_before', 'message_after', 'message_comment', 'message_end_template', - 'user_email_template', 'admin_email_template', 'submit_button_text', 'name_field_text', 'business_field_text', - 'email_field_text', 'phone_field_text', 'comment_field_text', 'email_from_text', 'question_answer_template', - 'leaderboard_template', 'quiz_system', 'randomness_order', 'loggedin_user_contact', 'show_score', 'send_user_email', - 'send_admin_email', 'contact_info_location', 'user_name', 'user_comp', 'user_email', 'user_phone', 'admin_email', - 'comment_section', 'question_from_total', 'total_user_tries', 'total_user_tries_text', 'certificate_template', - 'social_media', 'social_media_text', 'pagination', 'pagination_text', 'timer_limit', 'quiz_stye', 'question_numbering', - 'quiz_settings', 'theme_selected', 'last_activity', 'require_log_in', 'require_log_in_text', 'limit_total_entries', - 'limit_total_entries_text', 'scheduled_timeframe', 'scheduled_timeframe_text', 'disable_answer_onselect', 'ajax_show_correct', - 'quiz_views', 'quiz_taken', 'deleted', 'quiz_author_id' + $quiz_table_name => [ + 'quiz_id', + 'quiz_name', + 'message_before', + 'message_after', + 'message_comment', + 'message_end_template', + 'user_email_template', + 'admin_email_template', + 'submit_button_text', + 'name_field_text', + 'business_field_text', + 'email_field_text', + 'phone_field_text', + 'comment_field_text', + 'email_from_text', + 'question_answer_template', + 'leaderboard_template', + 'quiz_system', + 'randomness_order', + 'loggedin_user_contact', + 'show_score', + 'send_user_email', + 'send_admin_email', + 'contact_info_location', + 'user_name', + 'user_comp', + 'user_email', + 'user_phone', + 'admin_email', + 'comment_section', + 'question_from_total', + 'total_user_tries', + 'total_user_tries_text', + 'certificate_template', + 'social_media', + 'social_media_text', + 'pagination', + 'pagination_text', + 'timer_limit', + 'quiz_stye', + 'question_numbering', + 'quiz_settings', + 'theme_selected', + 'last_activity', + 'require_log_in', + 'require_log_in_text', + 'limit_total_entries', + 'limit_total_entries_text', + 'scheduled_timeframe', + 'scheduled_timeframe_text', + 'disable_answer_onselect', + 'ajax_show_correct', + 'quiz_views', + 'quiz_taken', + 'deleted', + 'quiz_author_id', ], - $question_table_name => [ - 'question_id', 'quiz_id', 'question_name', 'answer_array', 'answer_one', 'answer_one_points', 'answer_two', - 'answer_two_points', 'answer_three', 'answer_three_points', 'answer_four', 'answer_four_points', 'answer_five', - 'answer_five_points', 'answer_six', 'answer_six_points', 'correct_answer', 'question_answer_info', 'comments', - 'hints', 'question_order', 'question_type', 'question_type_new', 'question_settings', 'category', 'deleted', - 'deleted_question_bank' + $question_table_name => [ + 'question_id', + 'quiz_id', + 'question_name', + 'answer_array', + 'answer_one', + 'answer_one_points', + 'answer_two', + 'answer_two_points', + 'answer_three', + 'answer_three_points', + 'answer_four', + 'answer_four_points', + 'answer_five', + 'answer_five_points', + 'answer_six', + 'answer_six_points', + 'correct_answer', + 'question_answer_info', + 'comments', + 'hints', + 'question_order', + 'question_type', + 'question_type_new', + 'question_settings', + 'category', + 'deleted', + 'deleted_question_bank', ], - $results_table_name => [ - 'result_id', 'quiz_id', 'quiz_name', 'quiz_system', 'point_score', 'correct_score', 'correct', 'total', 'name', - 'business', 'email', 'phone', 'user', 'user_ip', 'time_taken', 'time_taken_real', 'quiz_results', 'deleted', - 'unique_id', 'form_type', 'page_name', 'page_url' + $results_table_name => [ + 'result_id', + 'quiz_id', + 'quiz_name', + 'quiz_system', + 'point_score', + 'correct_score', + 'correct', + 'total', + 'name', + 'business', + 'email', + 'phone', + 'user', + 'user_ip', + 'time_taken', + 'time_taken_real', + 'quiz_results', + 'deleted', + 'unique_id', + 'form_type', + 'page_name', + 'page_url', ], - $audit_table_name => [ - 'trail_id', 'action_user', 'action', 'quiz_id', 'quiz_name', 'form_data', 'time' + $audit_table_name => [ + 'trail_id', + 'action_user', + 'action', + 'quiz_id', + 'quiz_name', + 'form_data', + 'time', ], - $themes_table_name => [ - 'id', 'theme', 'theme_name', 'default_settings', 'theme_active' + $themes_table_name => [ + 'id', + 'theme', + 'theme_name', + 'default_settings', + 'theme_active', ], $quiz_themes_settings_table_name => [ - 'id', 'theme_id', 'quiz_id', 'quiz_theme_settings', 'active_theme' + 'id', + 'theme_id', + 'quiz_id', + 'quiz_theme_settings', + 'active_theme', + ], + $question_terms_table_name => [ + 'id', + 'question_id', + 'quiz_id', + 'term_id', + 'taxonomy', ], - $question_terms_table_name => [ - 'id', 'question_id', 'quiz_id', 'term_id', 'taxonomy' - ] ]; // Check all tables $errors = []; - foreach ($tables as $table_name => $columns) { + foreach ( $tables as $table_name => $columns ) { $error = $this->qsm_check_table_structure($table_name, $columns); - if ($error) { + if ( $error ) { $errors[] = $error; } } - if (!empty($errors)) { - foreach ($errors as $error) { + if ( ! empty($errors) ) { + foreach ( $errors as $error ) { echo esc_html($error) . "
"; } } else { @@ -869,20 +974,20 @@ public function qsm_check_database_structure() { * @param array $expected_columns * @return string|null */ - public function qsm_check_table_structure($table_name, $expected_columns) { + public function qsm_check_table_structure( $table_name, $expected_columns ) { global $wpdb; $columns = $wpdb->get_results("SHOW COLUMNS FROM $table_name"); - if (!$columns) { + if ( ! $columns ) { return esc_html__("Table ", "quiz-master-next") . $table_name . esc_html__(" does not exist.", "quiz-master-next"); } $existing_columns = array_column($columns, 'Field'); $missing_columns = []; - foreach ($expected_columns as $column) { - if (!in_array($column, $existing_columns)) { + foreach ( $expected_columns as $column ) { + if ( ! in_array($column, $existing_columns, true) ) { $missing_columns[] = $column; } } - if (!empty($missing_columns)) { + if ( ! empty($missing_columns) ) { return esc_html__("Table ", "quiz-master-next") . $table_name . esc_html__(" is missing columns: ", "quiz-master-next") . implode(', ', $missing_columns); } return null; diff --git a/php/template-variables.php b/php/template-variables.php index a4dc68f27..ae207d466 100644 --- a/php/template-variables.php +++ b/php/template-variables.php @@ -134,7 +134,7 @@ function qsm_variable_single_answer( $content, $mlw_quiz_array ) { $ser_answer = $wpdb->get_row( $wpdb->prepare( "SELECT question_settings FROM {$wpdb->prefix}mlw_questions WHERE question_id = %d", $question_id ), ARRAY_A ); $question_settings = qmn_sanitize_input_data( $ser_answer['question_settings'] ); $answerstr = ""; - if ( isset($answers['user_answer']) && is_array($answers['user_answer']) ) { + if ( isset( $answers['user_answer'] ) && is_array( $answers['user_answer'] ) ) { if ( 13 === intval( $answers['question_type'] ) ) { $answerstr .= $answers['points']; }elseif ( 12 === intval( $answers['question_type'] ) ) { @@ -515,10 +515,10 @@ function qsm_all_contact_fields_variable( $content, $results ) { if ( isset( $results['contact'] ) && ( is_array( $results['contact'] ) || is_object( $results['contact'] ) ) ) { foreach ( $results['contact'] as $results_contact ) { $options = qsm_get_options_of_contact_fields($contact_form, $results_contact['label'], $results_contact['type'] ); - $isRadioOrSelect = in_array($results_contact['type'], ['radio', 'select']); - $hasOptions = !empty(trim($options)); + $isRadioOrSelect = in_array($results_contact['type'], [ 'radio', 'select' ]); + $hasOptions = ! empty(trim($options)); - if (($isRadioOrSelect && $hasOptions) || !$isRadioOrSelect) { + if ( ($isRadioOrSelect && $hasOptions) || ! $isRadioOrSelect ) { $return .= $results_contact['label'] . ': ' . $results_contact['value'] . '
'; } } @@ -526,9 +526,9 @@ function qsm_all_contact_fields_variable( $content, $results ) { $content = str_replace( '%CONTACT_ALL%', $return, $content ); return $content; } -function qsm_get_options_of_contact_fields($data, $label, $type) { - foreach ($data as $item) { - if ($item['label'] === $label && $item['type'] === $type) { +function qsm_get_options_of_contact_fields( $data, $label, $type ) { + foreach ( $data as $item ) { + if ( $item['label'] === $label && $item['type'] === $type ) { return $item['options']; } } From 1a36589065ed99bfd7a10b80ebce5f99394da963 Mon Sep 17 00:00:00 2001 From: Mohammad Zubair Ali Date: Fri, 28 Jun 2024 14:25:02 +0530 Subject: [PATCH 4/4] show database table structure message --- mlw_quizmaster2.php | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/mlw_quizmaster2.php b/mlw_quizmaster2.php index 5108403eb..e05014e5a 100644 --- a/mlw_quizmaster2.php +++ b/mlw_quizmaster2.php @@ -348,6 +348,9 @@ private function add_hooks() { add_action( 'admin_menu', array( $this, 'setup_admin_menu' ) ); add_action( 'admin_head', array( $this, 'admin_head' ), 900 ); add_action( 'init', array( $this, 'register_quiz_post_types' ) ); + if ( empty( get_option('qsm_check_database_structure') ) || ! empty($_GET['qsm_check_database_structure']) ) { + add_action( 'admin_init', array( $this, 'qsm_check_database_structure' ) ); + } add_filter( 'parent_file', array( &$this, 'parent_file' ), 9999, 1 ); add_action( 'plugins_loaded', array( &$this, 'qsm_load_textdomain' ) ); add_action( 'admin_enqueue_scripts', array( $this, 'qsm_admin_scripts_style' ), 10 ); @@ -946,7 +949,7 @@ public function qsm_check_database_structure() { 'taxonomy', ], ]; - + $response['message'] = ""; // Check all tables $errors = []; foreach ( $tables as $table_name => $columns ) { @@ -955,15 +958,23 @@ public function qsm_check_database_structure() { $errors[] = $error; } } - if ( ! empty($errors) ) { + $response['message'] .= esc_html__("Incorrect database structure!", "quiz-master-next") . "
"; foreach ( $errors as $error ) { - echo esc_html($error) . "
"; + $response['status'] = "error"; + $response['message'] .= esc_html($error) . "
"; } + update_option('qsm_check_database_structure', "error"); } else { - esc_html_e("All tables have the correct structure.", "quiz-master-next"); - update_option('qsm_check_database_structure', 1); + update_option('qsm_check_database_structure', "success"); + $response['status'] = "success"; + $response['message'] = esc_html__("All tables have the correct structure.", "quiz-master-next"); } + if ( ! empty( $_GET['qsm_check_database_structure'] ) ) { + $this->alertManager->newAlert( $response['message'], $response['status'] ); + }else { + return $response; + } } /**