Skip to content

Commit

Permalink
Merge pull request #2600 from QuizandSurveyMaster/dev
Browse files Browse the repository at this point in the history
Realese 9.1.0
  • Loading branch information
etvarun authored Jul 11, 2024
2 parents a805baa + 5638ead commit 2fed7da
Show file tree
Hide file tree
Showing 8 changed files with 361 additions and 111 deletions.
223 changes: 221 additions & 2 deletions mlw_quizmaster2.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
/**
* Plugin Name: Quiz And Survey Master
* Description: Easily and quickly add quizzes and surveys to your website.
* Version: 9.0.5
* Version: 9.1.0
* Author: ExpressTech
* Author URI: https://quizandsurveymaster.com/
* Plugin URI: https://expresstech.io/
Expand Down Expand Up @@ -43,7 +43,7 @@ class MLWQuizMasterNext {
* @var string
* @since 4.0.0
*/
public $version = '9.0.5';
public $version = '9.1.0';

/**
* QSM Alert Manager Object
Expand Down Expand Up @@ -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 );
Expand Down Expand Up @@ -784,6 +787,222 @@ public function admin_failed_submission_page() {
$QmnFailedSubmissions->render_list_table();
}
}
/**
* Check database structure
*
* @since 9.1.0
* @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',
],
];
$response['message'] = "";
// 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) ) {
$response['message'] .= esc_html__("Incorrect database structure!", "quiz-master-next") . "<br/>";
foreach ( $errors as $error ) {
$response['status'] = "error";
$response['message'] .= esc_html($error) . "<br>";
}
update_option('qsm_check_database_structure', "error");
} else {
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;
}
}

/**
* Check if table and columns exist
*
* @since 9.1.0
* @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, true) ) {
$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
Expand Down
2 changes: 1 addition & 1 deletion php/admin/options-page-questions-tab.php
Original file line number Diff line number Diff line change
Expand Up @@ -433,7 +433,7 @@ class="save-page-button button button-primary"><?php esc_html_e( 'Save Questions
'1' => __( 'Yes', 'quiz-master-next' ),
),
'default' => '0',
'show' => '14' . $show_case_sensitive,
'show' => '3, 5, 14' . $show_case_sensitive,
),
'limit_text' => array(
'heading' => __( 'Limit Text', 'quiz-master-next' ),
Expand Down
11 changes: 7 additions & 4 deletions php/classes/class-qmn-quiz-manager.php
Original file line number Diff line number Diff line change
Expand Up @@ -1870,9 +1870,9 @@ public function qsm_get_quiz_to_reload() {
*
* @return boolean results added or not
*/
private function add_quiz_results( $data ) {
public function add_quiz_results( $data ) {
global $wpdb;
if ( empty( $wpdb ) || empty( $data['qmn_array_for_variables'] ) || empty( $data['results_array'] ) || empty( $data['unique_id'] ) || 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;
}

Expand All @@ -1883,6 +1883,9 @@ private function add_quiz_results( $data ) {
$wpdb->suppress_errors();

try {
if ( empty( $data['page_name'] ) ) {
$data['page_name'] = url_to_postid( $data['http_referer'] ) ? get_the_title( url_to_postid( $data['http_referer'] ) ) : '';
}
$res = $wpdb->insert(
$table_name,
array(
Expand All @@ -1902,11 +1905,11 @@ private function add_quiz_results( $data ) {
'time_taken' => $data['qmn_array_for_variables']['time_taken'],
'time_taken_real' => gmdate( 'Y-m-d H:i:s', strtotime( $data['qmn_array_for_variables']['time_taken'] ) ),
'quiz_results' => maybe_serialize( $data['results_array'] ),
'deleted' => 0,
'deleted' => ( isset( $data['deleted'] ) && 1 === intval( $data['deleted'] ) ) ? 1 : 0,
'unique_id' => $data['unique_id'],
'form_type' => $data['form_type'],
'page_url' => $data['http_referer'],
'page_name' => url_to_postid( $data['http_referer'] ) ? get_the_title( url_to_postid( $data['http_referer'] ) ) : '',
'page_name' => sanitize_text_field( $data['page_name'] ),
),
array(
'%d',
Expand Down
2 changes: 1 addition & 1 deletion php/classes/class-qsm-fields.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public static function generate_section( $fields, $section ) {
if ( ( isset( $_POST[ $field["id"] ] ) && 'multiple_fields' !== $field["type"] ) || 'selectinput' == $field["type"] ) {
switch ( $field["type"] ) {
case 'text':
$sanitized_value = sanitize_text_field( wp_unslash( $_POST[ $field["id"] ] ) );
$sanitized_value = esc_html( sanitize_text_field( wp_unslash( $_POST[ $field["id"] ] ) ) );
break;

case 'url':
Expand Down
4 changes: 2 additions & 2 deletions php/classes/class-qsm-questions.php
Original file line number Diff line number Diff line change
Expand Up @@ -487,7 +487,7 @@ public static function get_question_categories_from_term_ids( $term_ids ) {
$categories_names[ $tax->term_id ] = $tax->name;
$taxs[ $tax->parent ][] = $tax;
}
$categories_tree = self::create_terms_tree( $taxs, $taxs[0] );
$categories_tree = self::create_terms_tree( $taxs, isset( $taxs[0] ) ? $taxs[0] : reset( $taxs ) );
}
$categories = array(
'list' => $categories_names,
Expand Down Expand Up @@ -527,7 +527,7 @@ public static function get_question_categories( $question_id = 0 ) {
$categories_names[ $tax->term_id ] = $tax->name;
$taxs[ $tax->parent ][] = $tax;
}
$categories_tree = self::create_terms_tree( $taxs, $taxs[0] );
$categories_tree = self::create_terms_tree( $taxs, isset( $taxs[0] ) ? $taxs[0] : reset( $taxs ) );

}
}
Expand Down
8 changes: 7 additions & 1 deletion php/classes/question-types/class-question-review-text.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,14 @@ public function set_user_answer() {
}

public function set_answer_status() {
global $mlwQuizMasterNext;
$case_sensitive = $mlwQuizMasterNext->pluginHelper->get_question_setting( $this->question_id, 'case_sensitive' );
$user_answer_value = $this->user_answer['input'];
$answer_key = array_search( $this->prepare_for_string_matching( $user_answer_value ), array_map( array( $this, 'prepare_for_string_matching' ), $this->correct_answer ), true );
if ( 1 === intval($case_sensitive ) ) {
$answer_key = array_search( $user_answer_value, $this->correct_answer, true );
}else {
$answer_key = array_search( $this->prepare_for_string_matching( $user_answer_value ), array_map( array( $this, 'prepare_for_string_matching' ), $this->correct_answer ), true );
}
if ( false !== $answer_key ) {
$this->answer_status = 'correct';
$this->points += $this->answer_array[ $answer_key ][1];
Expand Down
20 changes: 10 additions & 10 deletions php/template-variables.php
Original file line number Diff line number Diff line change
Expand Up @@ -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'] ) ) {
Expand Down Expand Up @@ -510,27 +510,27 @@ 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 ) {
$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' ], true);
$hasOptions = ! empty(trim($options));

if (($isRadioOrSelect && $hasOptions) || !$isRadioOrSelect) {
if ( ($isRadioOrSelect && $hasOptions) || ! $isRadioOrSelect ) {
$return .= $results_contact['label'] . ': ' . $results_contact['value'] . '<br>';
}
}
}
$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) {
return $item['options'];
}
function qsm_get_options_of_contact_fields( $data, $label, $type ) {
foreach ( $data as $item ) {
if ( $item['label'] === $label && $item['type'] === $type ) {
return $item['options'];
}
}
return null; // Option not found
}
Expand Down
Loading

0 comments on commit 2fed7da

Please sign in to comment.