Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Realese 9.1.0 #2600

Merged
merged 21 commits into from
Jul 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
af6429b
fixed http_referer issue
zubairraeen Jun 20, 2024
6682940
Fixed category's parent issue
iam-pranav Jun 26, 2024
59c0079
Merge pull request #2593 from QuizandSurveyMaster/CU-86cvt9mpw-undefi…
randhirexpresstech Jun 26, 2024
40d3579
added case sensitive option to text question types
iam-pranav Jun 27, 2024
ba3b951
Merge branch 'dev' into CU-86cv2unwj-manage-case-sensitive-inputs
iam-pranav Jun 27, 2024
69d576e
Merge pull request #2594 from QuizandSurveyMaster/CU-86cv2unwj-manage…
zubairraeen Jun 27, 2024
54e06fd
added function to check table structure
zubairraeen Jun 27, 2024
4839764
fixed phpcs
zubairraeen Jun 27, 2024
1a36589
show database table structure message
zubairraeen Jun 28, 2024
89c4ad0
Merge pull request #2595 from QuizandSurveyMaster/dev-zubair
zubairraeen Jun 28, 2024
e5a1b04
adjust add result function for import feature
randhirexpresstech Jul 1, 2024
13caee8
Merge pull request #2596 from QuizandSurveyMaster/86cvpd1da-fix-email…
randhirexpresstech Jul 1, 2024
32fe308
added case sensitive option to text question types
iam-pranav Jun 27, 2024
1c0d180
Fixed category's parent issue
iam-pranav Jun 26, 2024
95f69e1
adjust add result function for import feature
randhirexpresstech Jul 1, 2024
d66fd53
Fixed vulnerability in text tab
iam-pranav Jul 10, 2024
5b2f3ec
Merge branch 'dev' into CU-86cvuadta-vulnerability-report
iam-pranav Jul 10, 2024
7b238b6
Merge pull request #2598 from QuizandSurveyMaster/CU-86cvuadta-vulner…
zubairraeen Jul 10, 2024
ae65951
Update changelog 9.1.0
zubairraeen Jul 11, 2024
c5e1a32
merge with dev
zubairraeen Jul 11, 2024
5638ead
Merge pull request #2599 from QuizandSurveyMaster/dev-zubair
zubairraeen Jul 11, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading