Quiz And Survey Master (Formerly Quiz Master Next) - Version 7.3.9

Version Description

(January 20, 2022) = * Hotfix: Issues with markup in email * Hotfix: Issues with quiz review for blank submissions * Hotfix: Issues with question/average points/score template variable * Hotfix: Issues with result items on admin dashboard

=

Download this release

Release Info

Developer expresstech
Plugin Icon 128x128 Quiz And Survey Master (Formerly Quiz Master Next)
Version 7.3.9
Comparing to
See all releases

Code changes from version 7.3.8 to 7.3.9

js/qsm-admin.js CHANGED
@@ -2215,6 +2215,11 @@ if (jQuery('body').hasClass('admin_page_mlw_quiz_options')){
2215
  },
2216
  question_type_change: function (previous_question_val, questionID) {
2217
  //you can override this object
 
 
 
 
 
2218
  }
2219
  };
2220
 
2215
  },
2216
  question_type_change: function (previous_question_val, questionID) {
2217
  //you can override this object
2218
+ var ans_type = $('#change-answer-editor').val();
2219
+ if (2 == questionID && 'text' !== ans_type){
2220
+ $('#change-answer-editor').val('text');
2221
+ $('.answers-single').remove();
2222
+ }
2223
  }
2224
  };
2225
 
mlw_quizmaster2.php CHANGED
@@ -2,14 +2,14 @@
2
  /**
3
  * Plugin Name: Quiz And Survey Master
4
  * Description: Easily and quickly add quizzes and surveys to your website.
5
- * Version: 7.3.8
6
  * Author: ExpressTech
7
  * Author URI: https://quizandsurveymaster.com/
8
  * Plugin URI: https://expresstech.io/
9
  * Text Domain: quiz-master-next
10
  *
11
  * @author QSM Team
12
- * @version 7.3.8
13
  * @package QSM
14
  */
15
 
@@ -44,7 +44,7 @@ class MLWQuizMasterNext {
44
  * @var string
45
  * @since 4.0.0
46
  */
47
- public $version = '7.3.8';
48
 
49
  /**
50
  * QSM Alert Manager Object
@@ -118,6 +118,19 @@ class MLWQuizMasterNext {
118
  */
119
  public $quiz = array();
120
 
 
 
 
 
 
 
 
 
 
 
 
 
 
121
  /**
122
  * Main Construct Function
123
  *
@@ -282,6 +295,7 @@ class MLWQuizMasterNext {
282
  wp_enqueue_style( 'qsm_common_style', QSM_PLUGIN_CSS_URL . '/common.css', array(), $this->version );
283
  wp_style_add_data( 'qsm_common_style', 'rtl', 'replace' );
284
  wp_enqueue_script( 'math_jax', QSM_PLUGIN_JS_URL . '/mathjax/tex-mml-chtml.js', false, '3.2.0', true );
 
285
  wp_enqueue_script( 'jquery-ui-slider' );
286
  wp_enqueue_script( 'jquery-ui-slider-rtl-js', QSM_PLUGIN_JS_URL . '/jquery.ui.slider-rtl.js', array( 'jquery-ui-core', 'jquery-ui-mouse', 'jquery-ui-slider' ), $this->version, true );
287
  wp_enqueue_style( 'jquery-ui-slider-rtl-css', QSM_PLUGIN_CSS_URL . '/jquery.ui.slider-rtl.css', array(), $this->version );
@@ -313,6 +327,7 @@ class MLWQuizMasterNext {
313
  case 'emails':
314
  case 'results-pages':
315
  wp_enqueue_script( 'math_jax', QSM_PLUGIN_JS_URL . '/mathjax/tex-mml-chtml.js', false, '3.2.0', true );
 
316
  wp_enqueue_editor();
317
  wp_enqueue_media();
318
  break;
@@ -332,11 +347,13 @@ class MLWQuizMasterNext {
332
  wp_enqueue_script( 'jquery-effects-blind' );
333
  wp_enqueue_script( 'jquery-effects-explode' );
334
  wp_enqueue_script( 'math_jax', QSM_PLUGIN_JS_URL . '/mathjax/tex-mml-chtml.js', false, '3.2.0', true );
 
335
  break;
336
  default:
337
  wp_enqueue_style( 'qsm_admin_question_css', QSM_PLUGIN_CSS_URL . '/qsm-admin-question.css', array(), $this->version );
338
  wp_style_add_data( 'qsm_admin_question_css', 'rtl', 'replace' );
339
  wp_enqueue_script( 'math_jax', QSM_PLUGIN_JS_URL . '/mathjax/tex-mml-chtml.js', false, '3.2.0', true );
 
340
  wp_enqueue_editor();
341
  wp_enqueue_media();
342
  break;
2
  /**
3
  * Plugin Name: Quiz And Survey Master
4
  * Description: Easily and quickly add quizzes and surveys to your website.
5
+ * Version: 7.3.9
6
  * Author: ExpressTech
7
  * Author URI: https://quizandsurveymaster.com/
8
  * Plugin URI: https://expresstech.io/
9
  * Text Domain: quiz-master-next
10
  *
11
  * @author QSM Team
12
+ * @version 7.3.9
13
  * @package QSM
14
  */
15
 
44
  * @var string
45
  * @since 4.0.0
46
  */
47
+ public $version = '7.3.9';
48
 
49
  /**
50
  * QSM Alert Manager Object
118
  */
119
  public $quiz = array();
120
 
121
+ /*
122
+ * Default MathJax inline scripts.
123
+ */
124
+ public static $default_MathJax_script = "MathJax = {
125
+ tex: {
126
+ inlineMath: [['$','$'],['\\\\(','\\\\)']],
127
+ processEscapes: true
128
+ },
129
+ options: {
130
+ ignoreHtmlClass: 'tex2jax_ignore|editor-rich-text'
131
+ }
132
+ };";
133
+
134
  /**
135
  * Main Construct Function
136
  *
295
  wp_enqueue_style( 'qsm_common_style', QSM_PLUGIN_CSS_URL . '/common.css', array(), $this->version );
296
  wp_style_add_data( 'qsm_common_style', 'rtl', 'replace' );
297
  wp_enqueue_script( 'math_jax', QSM_PLUGIN_JS_URL . '/mathjax/tex-mml-chtml.js', false, '3.2.0', true );
298
+ wp_add_inline_script( 'math_jax', self::$default_MathJax_script, 'before' );
299
  wp_enqueue_script( 'jquery-ui-slider' );
300
  wp_enqueue_script( 'jquery-ui-slider-rtl-js', QSM_PLUGIN_JS_URL . '/jquery.ui.slider-rtl.js', array( 'jquery-ui-core', 'jquery-ui-mouse', 'jquery-ui-slider' ), $this->version, true );
301
  wp_enqueue_style( 'jquery-ui-slider-rtl-css', QSM_PLUGIN_CSS_URL . '/jquery.ui.slider-rtl.css', array(), $this->version );
327
  case 'emails':
328
  case 'results-pages':
329
  wp_enqueue_script( 'math_jax', QSM_PLUGIN_JS_URL . '/mathjax/tex-mml-chtml.js', false, '3.2.0', true );
330
+ wp_add_inline_script( 'math_jax', self::$default_MathJax_script, 'before' );
331
  wp_enqueue_editor();
332
  wp_enqueue_media();
333
  break;
347
  wp_enqueue_script( 'jquery-effects-blind' );
348
  wp_enqueue_script( 'jquery-effects-explode' );
349
  wp_enqueue_script( 'math_jax', QSM_PLUGIN_JS_URL . '/mathjax/tex-mml-chtml.js', false, '3.2.0', true );
350
+ wp_add_inline_script( 'math_jax', self::$default_MathJax_script, 'before' );
351
  break;
352
  default:
353
  wp_enqueue_style( 'qsm_admin_question_css', QSM_PLUGIN_CSS_URL . '/qsm-admin-question.css', array(), $this->version );
354
  wp_style_add_data( 'qsm_admin_question_css', 'rtl', 'replace' );
355
  wp_enqueue_script( 'math_jax', QSM_PLUGIN_JS_URL . '/mathjax/tex-mml-chtml.js', false, '3.2.0', true );
356
+ wp_add_inline_script( 'math_jax', self::$default_MathJax_script, 'before' );
357
  wp_enqueue_editor();
358
  wp_enqueue_media();
359
  break;
php/admin/options-page-questions-tab.php CHANGED
@@ -299,7 +299,7 @@ function qsm_options_questions_tab_content() {
299
  }
300
  ?>
301
  </div>
302
- <div id="qsm_optoins_wrapper" class="qsm-row qsm_hide_for_other qsm_show_question_type_0 qsm_show_question_type_1 qsm_show_question_type_2 qsm_show_question_type_3 qsm_show_question_type_4 qsm_show_question_type_5 qsm_show_question_type_7 qsm_show_question_type_10 qsm_show_question_type_12 qsm_show_question_type_14 <?php echo esc_attr( $polar_class . $show_answer_option ); ?>">
303
  <label class="answer-header">
304
  <?php esc_html_e( 'Answers', 'quiz-master-next' ); ?>
305
  <a class="qsm-question-doc" rel="noopener"
@@ -317,6 +317,7 @@ function qsm_options_questions_tab_content() {
317
  class="dashicons dashicons-plus"></span>
318
  <?php esc_html_e( 'Add New Answer!', 'quiz-master-next' ); ?></a>
319
  </div>
 
320
  </div>
321
  <hr style="margin-bottom:25px;">
322
  <a href="#" class="qsm-show-correct-info-box button button-default"><span
@@ -437,17 +438,6 @@ function qsm_options_questions_tab_content() {
437
  'default' => 'random',
438
  'show' => '14' . $show_match_answer,
439
  ),
440
- 'text-answer-editor' => array(
441
- 'label' => __( 'Answers Type', 'quiz-master-next' ),
442
- 'type' => 'select',
443
- 'priority' => '4',
444
- 'options' => array(
445
- 'text' => __( 'Text Answers', 'quiz-master-next' ),
446
- ),
447
- 'default' => 'text',
448
- 'show' => '2' . $show_change_answer_editor,
449
- 'documentation_link' => 'https://quizandsurveymaster.com/docs/v7/questions-tab/#Answer-Type',
450
- ),
451
  );
452
  $simple_question_option = apply_filters( 'qsm_question_format_option', $simple_question_option );
453
  $keys = array_column( $simple_question_option, 'priority' );
299
  }
300
  ?>
301
  </div>
302
+ <div id="qsm_optoins_wrapper" class="qsm-row qsm_hide_for_other qsm_show_question_type_0 qsm_show_question_type_1 qsm_show_question_type_2 qsm_show_question_type_3 qsm_show_question_type_4 qsm_show_question_type_5 qsm_show_question_type_7 qsm_show_question_type_10 qsm_show_question_type_12 qsm_show_question_type_14 <?php echo apply_filters('qsm_polar_class',esc_attr( $polar_class . $show_answer_option )); ?>">
303
  <label class="answer-header">
304
  <?php esc_html_e( 'Answers', 'quiz-master-next' ); ?>
305
  <a class="qsm-question-doc" rel="noopener"
317
  class="dashicons dashicons-plus"></span>
318
  <?php esc_html_e( 'Add New Answer!', 'quiz-master-next' ); ?></a>
319
  </div>
320
+ <?php do_action('qsm_after_options'); ?>
321
  </div>
322
  <hr style="margin-bottom:25px;">
323
  <a href="#" class="qsm-show-correct-info-box button button-default"><span
438
  'default' => 'random',
439
  'show' => '14' . $show_match_answer,
440
  ),
 
 
 
 
 
 
 
 
 
 
 
441
  );
442
  $simple_question_option = apply_filters( 'qsm_question_format_option', $simple_question_option );
443
  $keys = array_column( $simple_question_option, 'priority' );
php/backward-compatibility/qsm-backward-compatibility-template-variables.php ADDED
@@ -0,0 +1,121 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ function qsm_bckcmp_tempvar_qa_text_qt_multi_choice_correct( $answers_from_db, $answers_from_response, $question_settings ) {
4
+ $question_with_answer_text = '';
5
+ $new_array_user_answer = isset($answers_from_response['user_compare_text']) ? explode('=====', $answers_from_response['user_compare_text']) : array();
6
+ foreach ( $answers_from_db as $single_answer ) {
7
+ $current_answer_text = trim(stripslashes(htmlspecialchars_decode($single_answer[0], ENT_QUOTES)));
8
+ $is_answer_correct = false;
9
+ if ( $new_array_user_answer ) {
10
+ foreach ( $new_array_user_answer as $new_array_value ) {
11
+ $new_array_value = trim(stripslashes(htmlspecialchars_decode($new_array_value, ENT_QUOTES)));
12
+ if ( $current_answer_text == $new_array_value ) {
13
+ $is_answer_correct = true;
14
+ break;
15
+ }
16
+ }
17
+ }
18
+ $image_class = '';
19
+ if ( isset($question_settings['answerEditor']) && 'image' == $question_settings['answerEditor'] ) {
20
+ $show_user_answer = '<img src="' . htmlspecialchars_decode($single_answer[0], ENT_QUOTES) . '"/>';
21
+ $image_class = 'qmn_image_option';
22
+ } else {
23
+ $show_user_answer = htmlspecialchars_decode($single_answer[0], ENT_QUOTES);
24
+ $image_class = '';
25
+ }
26
+ if ( isset($single_answer[2]) && 1 == $single_answer[2] && $is_answer_correct ) {
27
+ $question_with_answer_text .= '<span class="qsm-text-correct-option qsm-text-user-correct-answers_from_response ' . $image_class . '">' . $show_user_answer . '</span>';
28
+ } elseif ( isset($single_answer[2]) && 1 === $single_answer[2] ) {
29
+ $question_with_answer_text .= '<span class="qsm-text-correct-option ' . $image_class . '">' . $show_user_answer . '</span>';
30
+ } elseif ( $is_answer_correct && 1 !== $single_answer[2] ) {
31
+ $question_with_answer_text .= '<span class="qsm-text-wrong-option ' . $image_class . '">' . $show_user_answer . '</span>';
32
+ } else {
33
+ $question_with_answer_text .= '<span class="qsm-text-simple-option ' . $image_class . '">' . $show_user_answer . '</span>';
34
+ }
35
+ }
36
+
37
+ return $question_with_answer_text;
38
+ }
39
+
40
+ function qsm_bckcmp_tempvar_qa_text_qt_single_choice_correct( $answers_from_db, $answers_from_response, $question_settings ) {
41
+ $question_with_answer_text = '';
42
+ foreach ( $answers_from_db as $single_answer ) {
43
+ $single_answer_option = $single_answer[0];
44
+ if ( isset($question_settings['answerEditor']) && 'rich' == $question_settings['answerEditor'] ) {
45
+ $single_answer_option = htmlspecialchars_decode($single_answer[0], ENT_QUOTES);
46
+ $single_answer_option = htmlentities($single_answer_option);
47
+ if ( strpos($single_answer_option, '&lt;') !== false || strpos($single_answer_option, '&quot;') !== false ) {
48
+ $single_answer_option = htmlspecialchars($single_answer_option);
49
+ }
50
+ if ( strpos($answers_from_response[1], '&lt;') !== false || strpos($answers_from_response[1], '&quot;') !== false ) {
51
+ $answer_value = htmlentities($answers_from_response[1]);
52
+ } else {
53
+ $answer_value = htmlspecialchars_decode($answers_from_response[1], ENT_QUOTES);
54
+ $answer_value = htmlspecialchars_decode($answer_value, ENT_QUOTES);
55
+ $answer_value = htmlentities($answer_value);
56
+ $answer_value = htmlspecialchars($answer_value);
57
+ }
58
+ } else {
59
+ $answer_value = htmlspecialchars_decode($answers_from_response[1], ENT_QUOTES);
60
+ }
61
+ $image_class = '';
62
+ if ( isset($question_settings['answerEditor']) && 'image' == $question_settings['answerEditor'] ) {
63
+ $show_user_answer = '<img src="' . htmlspecialchars_decode($single_answer[0], ENT_QUOTES) . '"/>';
64
+ $image_class = 'qmn_image_option';
65
+ } else {
66
+ $show_user_answer = htmlspecialchars_decode($single_answer[0], ENT_QUOTES);
67
+ $image_class = '';
68
+ }
69
+ if ( isset($single_answer[2]) && 1 == $single_answer[2] && $answer_value == $single_answer_option ) {
70
+ $question_with_answer_text .= '<span class="qsm-text-correct-option qsm-text-user-correct-answer ' . $image_class . '">' . $show_user_answer . '</span>';
71
+ } elseif ( isset($single_answer[2]) && 1 == $single_answer[2] ) {
72
+ $question_with_answer_text .= '<span class="qsm-text-correct-option ' . $image_class . '">' . $show_user_answer . '</span>';
73
+ } elseif ( $answer_value == $single_answer_option && 1 !== $single_answer[2] ) {
74
+ $question_with_answer_text .= '<span class="qsm-text-wrong-option ' . $image_class . '">' . $show_user_answer . '</span>';
75
+ } else {
76
+ $question_with_answer_text .= '<span class="qsm-text-simple-option ' . $image_class . '">' . $show_user_answer . '</span>';
77
+ }
78
+ }
79
+ return $question_with_answer_text;
80
+ }
81
+
82
+ function qsm_bckcmp_tempvar_qa_text_qt_multi_choice_points( $answers_from_db, $answers_from_response, $question_settings ) {
83
+ $question_with_answer_text = '';
84
+ $user_selected_answer = htmlspecialchars_decode($answers_from_response[1], ENT_QUOTES);
85
+ foreach ( $answers_from_db as $single_answer ) {
86
+ $image_class = '';
87
+ if ( isset($question_settings['answerEditor']) && 'image' == $question_settings['answerEditor'] ) {
88
+ $show_user_answer = '<img src="' . htmlspecialchars_decode($single_answer[0], ENT_QUOTES) . '"/>';
89
+ $image_class = 'qmn_image_option';
90
+ } else {
91
+ $show_user_answer = htmlspecialchars_decode($single_answer[0], ENT_QUOTES);
92
+ $image_class = '';
93
+ }
94
+ if ( strpos($user_selected_answer, $single_answer[0]) !== false ) {
95
+ $question_with_answer_text .= '<span class="qsm-text-correct-option ' . $image_class . '">' . $show_user_answer . '</span>';
96
+ } else {
97
+ $question_with_answer_text .= '<span class="qsm-text-simple-option ' . $image_class . '">' . $show_user_answer . '</span>';
98
+ }
99
+ }
100
+ return $question_with_answer_text;
101
+ }
102
+
103
+ function qsm_bckcmp_tempvar_qa_text_qt_single_choice_points( $answers_from_db, $answers_from_response, $question_settings ) {
104
+ $question_with_answer_text = '';
105
+ foreach ( $answers_from_db as $single_answer ) {
106
+ $image_class = '';
107
+ if ( isset($question_settings['answerEditor']) && 'image' == $question_settings['answerEditor'] ) {
108
+ $show_user_answer = '<img src="' . htmlspecialchars_decode($single_answer[0], ENT_QUOTES) . '"/>';
109
+ $image_class = 'qmn_image_option';
110
+ } else {
111
+ $show_user_answer = htmlspecialchars_decode($single_answer[0], ENT_QUOTES);
112
+ $image_class = '';
113
+ }
114
+ if ( htmlspecialchars_decode($answers_from_response[1], ENT_QUOTES) == $single_answer[0] ) {
115
+ $question_with_answer_text .= '<span class="qsm-text-correct-option ' . $image_class . '">' . $show_user_answer . '</span>';
116
+ } else {
117
+ $question_with_answer_text .= '<span class="qsm-text-simple-option ' . $image_class . '">' . $show_user_answer . '</span>';
118
+ }
119
+ }
120
+ return $question_with_answer_text;
121
+ }
php/classes/class-qmn-plugin-helper.php CHANGED
@@ -839,10 +839,6 @@ class QMNPluginHelper {
839
  $simple_answer = "<span style='color:#808080;display:block;margin-bottom:5px;'>&#8226;&nbsp;";
840
  $html = str_replace( '<br/>', '<br>', $html );
841
  $html = str_replace( '<br />', '<br>', $html );
842
- $html = str_replace( '<span class="qmn_user_incorrect_answer">', "<span style='color:red'>&#x2715; ", $html );
843
- $html = str_replace( "<span class='qmn_user_incorrect_answer'>", "<span style='color:red'>&#x2715; ", $html );
844
- $html = str_replace( '<span class="qmn_user_correct_answer">', "<span style='color:green'>&#10003; ", $html );
845
- $html = str_replace( "<span class='qmn_user_correct_answer'>", "<span style='color:green'>&#10003; ", $html );
846
  $html = str_replace( '<span class="qsm-text-wrong-option qmn_image_option">', "$incorrect_answer ", $html );
847
  $html = str_replace( '<span class="qsm-text-correct-option qmn_image_option">', "$correct_answer ", $html );
848
  $html = str_replace( '<span class="qsm-text-correct-option qsm-text-user-correct-answer qmn_image_option">', "$correct_answer ", $html );
@@ -852,7 +848,7 @@ class QMNPluginHelper {
852
  $html = str_replace( '<span class="qsm-text-wrong-option ">', "$incorrect_answer ", $html );
853
  $html = str_replace( '<span class="qsm-text-correct-option ">', "$correct_answer ", $html );
854
  $html = str_replace( '<span class="qmn_user_incorrect_answer">', "$incorrect_answer ", $html );
855
- $html = str_replace( '<span class="qmn_user_incorrect_answer">', "$correct_answer ", $html );
856
  $html = str_replace( "class='qmn_question_answer", "style='margin-bottom:30px' class='", $html );
857
 
858
  return $html;
@@ -869,18 +865,18 @@ class QMNPluginHelper {
869
  if ( 'others' === mb_strtolower( $question_type ['category'] ) ) {
870
  $question_type_others[ $question_type ['category'] ] [ $question_type['slug'] ] = array(
871
  'slug' => $question_type['slug'],
872
- 'name' => $question_type['name'],
873
  );
874
  } else {
875
  $question_type_categorized[ $question_type ['category'] ] [ $question_type['slug'] ] = array(
876
  'slug' => $question_type['slug'],
877
- 'name' => $question_type['name'],
878
  );
879
- }
880
  } else {
881
  $question_type_uncategorized['uncategorized'][ $question_type['slug'] ] = array(
882
  'slug' => $question_type['slug'],
883
- 'name' => $question_type['name'],
884
  );
885
 
886
  }
839
  $simple_answer = "<span style='color:#808080;display:block;margin-bottom:5px;'>&#8226;&nbsp;";
840
  $html = str_replace( '<br/>', '<br>', $html );
841
  $html = str_replace( '<br />', '<br>', $html );
 
 
 
 
842
  $html = str_replace( '<span class="qsm-text-wrong-option qmn_image_option">', "$incorrect_answer ", $html );
843
  $html = str_replace( '<span class="qsm-text-correct-option qmn_image_option">', "$correct_answer ", $html );
844
  $html = str_replace( '<span class="qsm-text-correct-option qsm-text-user-correct-answer qmn_image_option">', "$correct_answer ", $html );
848
  $html = str_replace( '<span class="qsm-text-wrong-option ">', "$incorrect_answer ", $html );
849
  $html = str_replace( '<span class="qsm-text-correct-option ">', "$correct_answer ", $html );
850
  $html = str_replace( '<span class="qmn_user_incorrect_answer">', "$incorrect_answer ", $html );
851
+ $html = str_replace( '<span class="qmn_user_correct_answer qsm-text-correct-option qsm-text-user-correct-answer">', "$correct_answer ", $html );
852
  $html = str_replace( "class='qmn_question_answer", "style='margin-bottom:30px' class='", $html );
853
 
854
  return $html;
865
  if ( 'others' === mb_strtolower( $question_type ['category'] ) ) {
866
  $question_type_others[ $question_type ['category'] ] [ $question_type['slug'] ] = array(
867
  'slug' => $question_type['slug'],
868
+ 'name' => $question_type['name'],
869
  );
870
  } else {
871
  $question_type_categorized[ $question_type ['category'] ] [ $question_type['slug'] ] = array(
872
  'slug' => $question_type['slug'],
873
+ 'name' => $question_type['name'],
874
  );
875
+ }
876
  } else {
877
  $question_type_uncategorized['uncategorized'][ $question_type['slug'] ] = array(
878
  'slug' => $question_type['slug'],
879
+ 'name' => $question_type['name'],
880
  );
881
 
882
  }
php/classes/class-qmn-quiz-manager.php CHANGED
@@ -23,6 +23,18 @@ class QMNQuizManager {
23
  * @since 7.3.5
24
  */
25
  public $common_css = QSM_PLUGIN_CSS_URL . '/common.css';
 
 
 
 
 
 
 
 
 
 
 
 
26
  public $mathjax_url = QSM_PLUGIN_JS_URL . '/mathjax/tex-mml-chtml.js';
27
  public $mathjax_version = '3.2.0';
28
 
@@ -316,6 +328,7 @@ class QMNQuizManager {
316
  wp_enqueue_script( 'qsm_quiz', QSM_PLUGIN_JS_URL . '/qsm-quiz.js', array( 'wp-util', 'underscore', 'jquery', 'jquery-ui-tooltip' ), $mlwQuizMasterNext->version, false );
317
  wp_enqueue_script( 'qsm_common', QSM_PLUGIN_JS_URL . '/qsm-common.js', array(), $mlwQuizMasterNext->version, true );
318
  wp_enqueue_script( 'math_jax', $this->mathjax_url, false, $this->mathjax_version, true );
 
319
  $result_unique_id = sanitize_text_field( wp_unslash( $_GET['result_id'] ) );
320
  $query = $wpdb->prepare( "SELECT result_id FROM {$wpdb->prefix}mlw_results WHERE unique_id = %s", $result_unique_id );
321
  $result = $wpdb->get_row( $query, ARRAY_A );
@@ -477,6 +490,7 @@ class QMNQuizManager {
477
  wp_enqueue_style( 'dashicons' );
478
  wp_enqueue_style( 'qsm_primary_css', plugins_url( '../../templates/qmn_primary.css', __FILE__ ), array(), $mlwQuizMasterNext->version );
479
  wp_enqueue_script( 'math_jax', $this->mathjax_url, false, $this->mathjax_version, true );
 
480
  $quiz_result = maybe_unserialize( $result_data['quiz_results'] );
481
  $response_data = array(
482
  'quiz_id' => $result_data['quiz_id'],
@@ -774,6 +788,7 @@ class QMNQuizManager {
774
  )
775
  );
776
  wp_enqueue_script( 'math_jax', $this->mathjax_url, array(), $this->mathjax_version, true );
 
777
  global $qmn_total_questions;
778
  $qmn_total_questions = 0;
779
  global $mlw_qmn_section_count;
@@ -1804,6 +1819,9 @@ class QMNQuizManager {
1804
  $question_text = $results_array['question_text'];
1805
  }
1806
 
 
 
 
1807
  // Save question data into new array in our array
1808
  $question_data[] = apply_filters(
1809
  'qmn_answer_array',
@@ -1812,8 +1830,8 @@ class QMNQuizManager {
1812
  htmlspecialchars( $user_answer, ENT_QUOTES ),
1813
  htmlspecialchars( $correct_answer, ENT_QUOTES ),
1814
  $comment,
1815
- 'user_answer' => $results_array['user_answer'],
1816
- 'correct_answer' => $results_array['correct_answer'],
1817
  'correct' => $correct_status,
1818
  'id' => $question['question_id'],
1819
  'points' => $answer_points,
@@ -1885,6 +1903,8 @@ class QMNQuizManager {
1885
  if ( isset( $results_array['question_text'] ) ) {
1886
  $question_text = $results_array['question_text'];
1887
  }
 
 
1888
 
1889
  // Save question data into new array in our array
1890
  $question_data[] = apply_filters(
@@ -1894,8 +1914,8 @@ class QMNQuizManager {
1894
  htmlspecialchars( $user_answer, ENT_QUOTES ),
1895
  htmlspecialchars( $correct_answer, ENT_QUOTES ),
1896
  $comment,
1897
- 'user_answer' => $results_array['user_answer'],
1898
- 'correct_answer' => $results_array['correct_answer'],
1899
  'correct' => $correct_status,
1900
  'id' => $question['question_id'],
1901
  'points' => $answer_points,
23
  * @since 7.3.5
24
  */
25
  public $common_css = QSM_PLUGIN_CSS_URL . '/common.css';
26
+ /*
27
+ * Default MathJax inline scripts.
28
+ */
29
+ public static $default_MathJax_script = "MathJax = {
30
+ tex: {
31
+ inlineMath: [['$','$'],['\\\\(','\\\\)']],
32
+ processEscapes: true
33
+ },
34
+ options: {
35
+ ignoreHtmlClass: 'tex2jax_ignore|editor-rich-text'
36
+ }
37
+ };";
38
  public $mathjax_url = QSM_PLUGIN_JS_URL . '/mathjax/tex-mml-chtml.js';
39
  public $mathjax_version = '3.2.0';
40
 
328
  wp_enqueue_script( 'qsm_quiz', QSM_PLUGIN_JS_URL . '/qsm-quiz.js', array( 'wp-util', 'underscore', 'jquery', 'jquery-ui-tooltip' ), $mlwQuizMasterNext->version, false );
329
  wp_enqueue_script( 'qsm_common', QSM_PLUGIN_JS_URL . '/qsm-common.js', array(), $mlwQuizMasterNext->version, true );
330
  wp_enqueue_script( 'math_jax', $this->mathjax_url, false, $this->mathjax_version, true );
331
+ wp_add_inline_script( 'math_jax', self::$default_MathJax_script, 'before' );
332
  $result_unique_id = sanitize_text_field( wp_unslash( $_GET['result_id'] ) );
333
  $query = $wpdb->prepare( "SELECT result_id FROM {$wpdb->prefix}mlw_results WHERE unique_id = %s", $result_unique_id );
334
  $result = $wpdb->get_row( $query, ARRAY_A );
490
  wp_enqueue_style( 'dashicons' );
491
  wp_enqueue_style( 'qsm_primary_css', plugins_url( '../../templates/qmn_primary.css', __FILE__ ), array(), $mlwQuizMasterNext->version );
492
  wp_enqueue_script( 'math_jax', $this->mathjax_url, false, $this->mathjax_version, true );
493
+ wp_add_inline_script( 'math_jax', self::$default_MathJax_script, 'before' );
494
  $quiz_result = maybe_unserialize( $result_data['quiz_results'] );
495
  $response_data = array(
496
  'quiz_id' => $result_data['quiz_id'],
788
  )
789
  );
790
  wp_enqueue_script( 'math_jax', $this->mathjax_url, array(), $this->mathjax_version, true );
791
+ wp_add_inline_script( 'math_jax', self::$default_MathJax_script, 'before' );
792
  global $qmn_total_questions;
793
  $qmn_total_questions = 0;
794
  global $mlw_qmn_section_count;
1819
  $question_text = $results_array['question_text'];
1820
  }
1821
 
1822
+ $user_answer_array = isset( $results_array['user_answer'] ) ? $results_array['user_answer'] : array() ;
1823
+ $correct_answer_array = isset( $results_array['correct_answer'] ) ? $results_array['correct_answer'] : array();
1824
+
1825
  // Save question data into new array in our array
1826
  $question_data[] = apply_filters(
1827
  'qmn_answer_array',
1830
  htmlspecialchars( $user_answer, ENT_QUOTES ),
1831
  htmlspecialchars( $correct_answer, ENT_QUOTES ),
1832
  $comment,
1833
+ 'user_answer' => $user_answer_array,
1834
+ 'correct_answer' => $correct_answer_array,
1835
  'correct' => $correct_status,
1836
  'id' => $question['question_id'],
1837
  'points' => $answer_points,
1903
  if ( isset( $results_array['question_text'] ) ) {
1904
  $question_text = $results_array['question_text'];
1905
  }
1906
+ $user_answer_array = is_array( $results_array['user_answer'] ) ? $results_array['user_answer'] : array() ;
1907
+ $correct_answer_array = is_array( $results_array['correct_answer'] ) ? $results_array['correct_answer'] : array();
1908
 
1909
  // Save question data into new array in our array
1910
  $question_data[] = apply_filters(
1914
  htmlspecialchars( $user_answer, ENT_QUOTES ),
1915
  htmlspecialchars( $correct_answer, ENT_QUOTES ),
1916
  $comment,
1917
+ 'user_answer' => $user_answer_array,
1918
+ 'correct_answer' => $correct_answer_array,
1919
  'correct' => $correct_status,
1920
  'id' => $question['question_id'],
1921
  'points' => $answer_points,
php/classes/question-types/class-question-review-choice.php CHANGED
@@ -11,16 +11,16 @@ class QSM_Question_Review_Choice extends QSM_Question_Review {
11
 
12
  public function set_user_answer() {
13
  if ( isset( $_POST[ 'question' . $this->question_id ] ) ) {
14
- $user_response = isset( $_POST[ 'question' . $this->question_id ] ) ? wp_unslash( $_POST[ 'question' . $this->question_id ] ) : ''; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
15
  if ( is_array( $user_response ) ) {
16
  foreach ( $user_response as $user_response_single ) {
17
  $user_answer_key = intval( $this->sanitize_answer_from_post( $user_response_single ) );
18
- $user_answer_value = $this->sanitize_answer_from_db( $this->answer_array[ $user_answer_key ][0], $this->input_field );
19
  $this->user_answer[ $user_answer_key ] = $user_answer_value;
20
  }
21
- } else {
22
  $user_answer_key = intval( $this->sanitize_answer_from_post( $user_response ) );
23
- $user_answer_value = $this->sanitize_answer_from_db( $this->answer_array[ $user_answer_key ][0], $this->input_field );
24
  $this->user_answer[ $user_answer_key ] = $user_answer_value;
25
  }
26
  }
@@ -30,7 +30,7 @@ class QSM_Question_Review_Choice extends QSM_Question_Review {
30
  foreach ( $this->user_answer as $user_answer_key => $user_answer_value ) {
31
  if ( in_array( $user_answer_key, array_keys( $this->correct_answer ), true ) ) {
32
  $this->answer_status = 'correct';
33
- $this->points += $this->answer_array[ $user_answer_key ][2];
34
  }
35
  }
36
  }
11
 
12
  public function set_user_answer() {
13
  if ( isset( $_POST[ 'question' . $this->question_id ] ) ) {
14
+ $user_response = wp_unslash( $_POST[ 'question' . $this->question_id ] ) ; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
15
  if ( is_array( $user_response ) ) {
16
  foreach ( $user_response as $user_response_single ) {
17
  $user_answer_key = intval( $this->sanitize_answer_from_post( $user_response_single ) );
18
+ $user_answer_value = $this->sanitize_answer_from_db( $this->answer_array[ $user_answer_key ][0] );
19
  $this->user_answer[ $user_answer_key ] = $user_answer_value;
20
  }
21
+ } elseif ( '' !== $user_response ) {
22
  $user_answer_key = intval( $this->sanitize_answer_from_post( $user_response ) );
23
+ $user_answer_value = $this->sanitize_answer_from_db( $this->answer_array[ $user_answer_key ][0] );
24
  $this->user_answer[ $user_answer_key ] = $user_answer_value;
25
  }
26
  }
30
  foreach ( $this->user_answer as $user_answer_key => $user_answer_value ) {
31
  if ( in_array( $user_answer_key, array_keys( $this->correct_answer ), true ) ) {
32
  $this->answer_status = 'correct';
33
+ $this->points += $this->answer_array[ $user_answer_key ][1];
34
  }
35
  }
36
  }
php/classes/question-types/class-question-review-fill-in-blanks.php CHANGED
@@ -20,7 +20,7 @@ class QSM_Question_Review_Fill_In_Blanks extends QSM_Question_Review {
20
  if ( isset( $_POST[ 'question' . $this->question_id ] ) ) {
21
  $user_response = wp_unslash( $_POST[ 'question' . $this->question_id ] ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
22
  foreach ( $user_response as $user_answer_key => $user_answer_value ) {
23
- $user_answer_value = $this->sanitize_answer_from_post( $user_answer_value, 'text' );
24
  $user_answer_value = $this->decode_response_from_text_field( $user_answer_value );
25
  $this->user_answer[ $user_answer_key ] = $user_answer_value;
26
  }
@@ -30,7 +30,7 @@ class QSM_Question_Review_Fill_In_Blanks extends QSM_Question_Review {
30
 
31
  public function set_correct_answer() {
32
  foreach ( $this->answer_array as $answer_key => $answer_value ) {
33
- $this->correct_answer[ $answer_key ] = $this->sanitize_answer_from_db( $answer_value[0], $this->input_field );
34
  }
35
  }
36
 
@@ -52,7 +52,7 @@ class QSM_Question_Review_Fill_In_Blanks extends QSM_Question_Review {
52
  $answer_key = array_search( $this->prepare_for_string_matching( $user_answer ), array_map( array( $this, 'prepare_for_string_matching' ), $this->correct_answer ), true );
53
  if ( false !== $answer_key ) {
54
  $this->answer_status = 'correct';
55
- $this->points += $this->answer_array[ $answer_key ][2];
56
  } else {
57
  $this->answer_status = 'incorrect';
58
  }
@@ -62,7 +62,7 @@ class QSM_Question_Review_Fill_In_Blanks extends QSM_Question_Review {
62
  $answer_key = array_search( $this->prepare_for_string_matching( $correct_answer ), array_map( array( $this, 'prepare_for_string_matching' ), $this->user_answer ), true );
63
  if ( false !== $answer_key ) {
64
  $this->answer_status = 'correct';
65
- $this->points += $this->answer_array[ $answer_key ][2];
66
  } else {
67
  $this->answer_status = 'incorrect';
68
  }
@@ -77,7 +77,7 @@ class QSM_Question_Review_Fill_In_Blanks extends QSM_Question_Review {
77
  foreach ( $this->user_answer as $user_answer_key => $user_answer ) {
78
  if ( $this->prepare_for_string_matching( $user_answer ) === $this->prepare_for_string_matching( $this->correct_answer[ $user_answer_key ] ) ) {
79
  $this->answer_status = 'correct';
80
- $this->points += $this->answer_array[ $user_answer_key ][2];
81
  } else {
82
  $this->answer_status = 'incorrect';
83
  }
@@ -86,7 +86,7 @@ class QSM_Question_Review_Fill_In_Blanks extends QSM_Question_Review {
86
  foreach ( $this->correct_answer as $correct_answer_key => $correct_answer ) {
87
  if ( $this->prepare_for_string_matching( $correct_answer ) === $this->prepare_for_string_matching( $this->user_answer[ $correct_answer_key ] ) ) {
88
  $this->answer_status = 'correct';
89
- $this->points += $this->answer_array[ $correct_answer_key ][2];
90
  } else {
91
  $this->answer_status = 'incorrect';
92
  }
20
  if ( isset( $_POST[ 'question' . $this->question_id ] ) ) {
21
  $user_response = wp_unslash( $_POST[ 'question' . $this->question_id ] ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
22
  foreach ( $user_response as $user_answer_key => $user_answer_value ) {
23
+ $user_answer_value = $this->sanitize_answer_from_post( $user_answer_value );
24
  $user_answer_value = $this->decode_response_from_text_field( $user_answer_value );
25
  $this->user_answer[ $user_answer_key ] = $user_answer_value;
26
  }
30
 
31
  public function set_correct_answer() {
32
  foreach ( $this->answer_array as $answer_key => $answer_value ) {
33
+ $this->correct_answer[ $answer_key ] = $this->sanitize_answer_from_db( $answer_value[0] );
34
  }
35
  }
36
 
52
  $answer_key = array_search( $this->prepare_for_string_matching( $user_answer ), array_map( array( $this, 'prepare_for_string_matching' ), $this->correct_answer ), true );
53
  if ( false !== $answer_key ) {
54
  $this->answer_status = 'correct';
55
+ $this->points += $this->answer_array[ $answer_key ][1];
56
  } else {
57
  $this->answer_status = 'incorrect';
58
  }
62
  $answer_key = array_search( $this->prepare_for_string_matching( $correct_answer ), array_map( array( $this, 'prepare_for_string_matching' ), $this->user_answer ), true );
63
  if ( false !== $answer_key ) {
64
  $this->answer_status = 'correct';
65
+ $this->points += $this->answer_array[ $answer_key ][1];
66
  } else {
67
  $this->answer_status = 'incorrect';
68
  }
77
  foreach ( $this->user_answer as $user_answer_key => $user_answer ) {
78
  if ( $this->prepare_for_string_matching( $user_answer ) === $this->prepare_for_string_matching( $this->correct_answer[ $user_answer_key ] ) ) {
79
  $this->answer_status = 'correct';
80
+ $this->points += $this->answer_array[ $user_answer_key ][1];
81
  } else {
82
  $this->answer_status = 'incorrect';
83
  }
86
  foreach ( $this->correct_answer as $correct_answer_key => $correct_answer ) {
87
  if ( $this->prepare_for_string_matching( $correct_answer ) === $this->prepare_for_string_matching( $this->user_answer[ $correct_answer_key ] ) ) {
88
  $this->answer_status = 'correct';
89
+ $this->points += $this->answer_array[ $correct_answer_key ][1];
90
  } else {
91
  $this->answer_status = 'incorrect';
92
  }
php/classes/question-types/class-question-review-text.php CHANGED
@@ -12,7 +12,7 @@ class QSM_Question_Review_Text extends QSM_Question_Review {
12
  public function set_user_answer() {
13
  if ( isset( $_POST[ 'question' . $this->question_id ] ) ) {
14
  $user_answer_key = 'input';
15
- $user_answer_value = $this->sanitize_answer_from_post( wp_unslash( $_POST[ 'question' . $this->question_id ], 'text_area' ) ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
16
  $user_answer_value = $this->decode_response_from_text_field( $user_answer_value );
17
  $this->user_answer[ $user_answer_key ] = $user_answer_value;
18
  }
@@ -23,7 +23,7 @@ class QSM_Question_Review_Text extends QSM_Question_Review {
23
  $answer_key = array_search( $this->prepare_for_string_matching( $user_answer_value ), array_map( array( $this, 'prepare_for_string_matching' ), $this->correct_answer ), true );
24
  if ( false !== $answer_key ) {
25
  $this->answer_status = 'correct';
26
- $this->points += $this->answer_array[ $answer_key ][2];
27
  }
28
  }
29
  }
12
  public function set_user_answer() {
13
  if ( isset( $_POST[ 'question' . $this->question_id ] ) ) {
14
  $user_answer_key = 'input';
15
+ $user_answer_value = $this->sanitize_answer_from_post( wp_unslash( $_POST[ 'question' . $this->question_id ] ) ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
16
  $user_answer_value = $this->decode_response_from_text_field( $user_answer_value );
17
  $this->user_answer[ $user_answer_key ] = $user_answer_value;
18
  }
23
  $answer_key = array_search( $this->prepare_for_string_matching( $user_answer_value ), array_map( array( $this, 'prepare_for_string_matching' ), $this->correct_answer ), true );
24
  if ( false !== $answer_key ) {
25
  $this->answer_status = 'correct';
26
+ $this->points += $this->answer_array[ $answer_key ][1];
27
  }
28
  }
29
  }
php/classes/question-types/class-question-review.php CHANGED
@@ -12,6 +12,8 @@ abstract class QSM_Question_Review {
12
  public $points = 0;
13
  public $question_description = '';
14
  public $input_field = '';
 
 
15
 
16
  function __construct( $question_id = 0, $question_description = '', $answer_array = array() ) {
17
  global $mlwQuizMasterNext;
@@ -20,21 +22,24 @@ abstract class QSM_Question_Review {
20
  $this->question_description = $question_description;
21
  $this->question_type = QSM_Questions::load_question_data( $this->question_id, 'question_type_new' );
22
  $this->input_field = $mlwQuizMasterNext->pluginHelper->question_types[ $this->question_type ]['input_field'];
 
 
 
23
  $this->set_user_answer();
24
  $this->set_correct_answer();
25
  $this->set_answer_status();
26
  }
27
 
28
- public function sanitize_answer_from_post( $data, $type = 'text' ) {
29
- if ( 'text_area' === $type ) {
30
  return sanitize_textarea_field( wp_unslash( $data ) );
31
  } else {
32
  return sanitize_text_field( wp_unslash( $data ) );
33
  }
34
  }
35
 
36
- public function sanitize_answer_from_db( $data, $type = 'text' ) {
37
- if ( 'text_area' === $type ) {
38
  return trim( stripslashes( htmlspecialchars_decode( sanitize_textarea_field( $data ), ENT_QUOTES ) ) );
39
  } else {
40
  return trim( stripslashes( htmlspecialchars_decode( sanitize_text_field( $data ), ENT_QUOTES ) ) );
@@ -42,20 +47,30 @@ abstract class QSM_Question_Review {
42
  }
43
 
44
  public function decode_response_from_text_field( $data ) {
45
- return trim( preg_replace( '/\s\s+/', ' ', str_replace( "\n", ' ', htmlspecialchars_decode( $data, ENT_QUOTES ) ) ) );
 
 
 
 
46
  }
47
 
48
 
49
  public function prepare_for_string_matching( $data ) {
50
- return mb_strtoupper( str_replace( ' ', '', preg_replace( '/\s\s+/', '', $data ) ) );
 
 
 
 
51
  }
52
 
53
  abstract public function set_user_answer();
54
 
55
  public function set_correct_answer() {
56
  foreach ( $this->answer_array as $answer_key => $answer_value ) {
57
- if ( 1 === intval( $answer_value[2] ) ) {
58
- $this->correct_answer[ $answer_key ] = $this->sanitize_answer_from_db( $answer_value[0], $this->input_field );
 
 
59
  }
60
  }
61
  }
12
  public $points = 0;
13
  public $question_description = '';
14
  public $input_field = '';
15
+ public $form_type = 0;
16
+ public $grading_system = 0;
17
 
18
  function __construct( $question_id = 0, $question_description = '', $answer_array = array() ) {
19
  global $mlwQuizMasterNext;
22
  $this->question_description = $question_description;
23
  $this->question_type = QSM_Questions::load_question_data( $this->question_id, 'question_type_new' );
24
  $this->input_field = $mlwQuizMasterNext->pluginHelper->question_types[ $this->question_type ]['input_field'];
25
+ $quiz_options = $mlwQuizMasterNext->quiz_settings->get_quiz_options();
26
+ $this->form_type = intval( $quiz_options->form_type );
27
+ $this->grading_system = intval( $quiz_options->system );
28
  $this->set_user_answer();
29
  $this->set_correct_answer();
30
  $this->set_answer_status();
31
  }
32
 
33
+ public function sanitize_answer_from_post( $data ) {
34
+ if ( 'text_area' === $this->input_field ) {
35
  return sanitize_textarea_field( wp_unslash( $data ) );
36
  } else {
37
  return sanitize_text_field( wp_unslash( $data ) );
38
  }
39
  }
40
 
41
+ public function sanitize_answer_from_db( $data ) {
42
+ if ( 'text_area' === $this->input_field ) {
43
  return trim( stripslashes( htmlspecialchars_decode( sanitize_textarea_field( $data ), ENT_QUOTES ) ) );
44
  } else {
45
  return trim( stripslashes( htmlspecialchars_decode( sanitize_text_field( $data ), ENT_QUOTES ) ) );
47
  }
48
 
49
  public function decode_response_from_text_field( $data ) {
50
+ if ( 'text_area' === $this->input_field ) {
51
+ return trim( preg_replace( '/\s\s+/', ' ', str_replace( "\n", ' ', htmlspecialchars_decode( $data, ENT_QUOTES ) ) ) );
52
+ } else {
53
+ return trim( htmlspecialchars_decode( $data, ENT_QUOTES ) );
54
+ }
55
  }
56
 
57
 
58
  public function prepare_for_string_matching( $data ) {
59
+ if ( 'text_area' === $this->input_field ) {
60
+ return mb_strtoupper( str_replace( ' ', '', preg_replace( '/\s\s+/', '', $data ) ) );
61
+ } else {
62
+ return mb_strtoupper( $data );
63
+ }
64
  }
65
 
66
  abstract public function set_user_answer();
67
 
68
  public function set_correct_answer() {
69
  foreach ( $this->answer_array as $answer_key => $answer_value ) {
70
+ if ( 1 === $this->grading_system ) {
71
+ $this->correct_answer[ $answer_key ] = $this->sanitize_answer_from_db( $answer_value[0] );
72
+ } elseif ( 1 === intval( $answer_value[2] ) ) {
73
+ $this->correct_answer[ $answer_key ] = $this->sanitize_answer_from_db( $answer_value[0] );
74
  }
75
  }
76
  }
php/question-types/qsm-question-type-polar.php CHANGED
@@ -41,6 +41,7 @@ function qmn_polar_display( $id, $question, $answers ) {
41
  } else {
42
  $mlw_require_class = '';
43
  }
 
44
  qsm_question_title_func( $question, '', $new_question_title, $id );
45
 
46
  ?>
41
  } else {
42
  $mlw_require_class = '';
43
  }
44
+ $new_question_title = $mlwQuizMasterNext->pluginHelper->get_question_setting( $id, 'question_title' );
45
  qsm_question_title_func( $question, '', $new_question_title, $id );
46
 
47
  ?>
php/template-variables.php CHANGED
@@ -11,29 +11,11 @@ if ( ! defined( 'ABSPATH' ) ) {
11
  exit;
12
  }
13
 
14
- /*
15
- Results Array For Reference:
16
-
17
- $mlw_qmn_result_array = array(
18
- 'quiz_id' => $mlw_quiz_id,
19
- 'quiz_name' => $mlw_quiz_options->quiz_name,
20
- 'quiz_system' => $mlw_quiz_options->system,
21
- 'total_points' => $mlw_points,
22
- 'total_score' => $mlw_total_score,
23
- 'total_correct' => $mlw_correct,
24
- 'total_questions' => $mlw_total_questions,
25
- 'user_name' => $mlw_user_name,
26
- 'user_business' => $mlw_user_comp,
27
- 'user_email' => $mlw_user_email,
28
- 'user_phone' => $mlw_user_phone,
29
- 'user_id' => get_current_user_id(),
30
- 'question_answers_display' => $mlw_question_answers,
31
- 'question_answers_array' => $mlw_qmn_answer_array,
32
- 'timer' => $mlw_qmn_timer,
33
- 'comments' => $mlw_qm_quiz_comments
34
- );
35
 
36
- */
37
  add_filter( 'mlw_qmn_template_variable_results_page', 'qsm_all_contact_fields_variable', 10, 2 );
38
  add_filter( 'mlw_qmn_template_variable_results_page', 'qsm_contact_field_variable', 10, 2 );
39
  add_filter( 'mlw_qmn_template_variable_results_page', 'qmn_variable_category_points', 10, 2 );
@@ -79,7 +61,7 @@ add_filter( 'mlw_qmn_template_variable_results_page', 'qsm_variable_minimum_poin
79
  * Changed the display structure to new structure.
80
  *
81
  * @since 6.4.11
82
- * @param str $content
83
  * @param array $mlw_quiz_array
84
  * Show particular question answer.
85
  */
@@ -162,8 +144,8 @@ function qsm_variable_total_attempted_questions( $content, $mlw_quiz_array ) {
162
  /**
163
  * Show poll result
164
  *
165
- * @param str $content
166
- * @param arr $mlw_quiz_array
167
  */
168
  function qsm_variable_poll_result( $content, $mlw_quiz_array ) {
169
  $quiz_id = is_object( $mlw_quiz_array ) ? $mlw_quiz_array->quiz_id : $mlw_quiz_array['quiz_id'];
@@ -211,8 +193,8 @@ function qsm_variable_poll_result( $content, $mlw_quiz_array ) {
211
  /**
212
  * Show Answer type evaluated
213
  *
214
- * @param str $answer
215
- * @param arr $question_settings
216
  */
217
  function qsm_answers_type_evaluated( $answer, $question_settings ) {
218
  if ( 'rich' === $question_settings['answerEditor'] ) {
@@ -294,6 +276,7 @@ function mlw_qmn_variable_point_score( $content, $mlw_quiz_array ) {
294
  $content = str_replace( '%POINT_SCORE%', ( isset( $mlw_quiz_array['total_points'] ) ? $mlw_quiz_array['total_points'] : '' ), $content );
295
  return $content;
296
  }
 
297
  function mlw_qmn_variable_average_point( $content, $mlw_quiz_array ) {
298
  $question_total = 0;
299
  if ( isset( $mlw_quiz_array['question_answers_array'] ) ) {
@@ -886,9 +869,9 @@ add_filter( 'wp_kses_allowed_html', 'qsm_custom_wpkses_post_tags', 10, 2 );
886
  *
887
  * @since 7.1.3
888
  *
889
- * @param arr $mlw_quiz_array
890
- * @param str $qmn_question_answer_template
891
- * @param str $answer
892
  * @param int $qsm_question_cnt
893
  * @param int $total_question_cnt
894
  * @return string
@@ -1100,35 +1083,10 @@ function qsm_questions_answers_shortcode_to_text( $mlw_quiz_array, $qmn_question
1100
  } else {
1101
  if ( 0 == $form_type && ( 0 == $quiz_system || 3 == $quiz_system ) ) {
1102
  if ( isset( $answer['question_type'] ) && ( 4 == $answer['question_type'] || 10 == $answer['question_type'] ) ) {
1103
- foreach ( $total_answers as $single_answer_key => $single_answer ) {
1104
- $current_answer_key = $single_answer_key;
1105
- $user_answer_keys = array_keys( $answer['user_answer'] );
1106
- $correct_answer_keys = array_keys( $answer['correct_answer'] );
1107
- $is_answer_correct = false;
1108
- $is_user_answer = false;
1109
- if ( in_array( $current_answer_key, $correct_answer_keys, true ) ) {
1110
- $is_answer_correct = true;
1111
- }
1112
- if ( in_array( $current_answer_key, $user_answer_keys, true) ) {
1113
- $is_user_answer = true;
1114
- }
1115
- $image_class = '';
1116
- if ( isset( $question_settings['answerEditor'] ) && 'image' === $question_settings['answerEditor'] ) {
1117
- $show_user_answer = '<img src="' . htmlspecialchars_decode( $single_answer[0], ENT_QUOTES ) . '"/>';
1118
- $image_class = 'qmn_image_option';
1119
- } else {
1120
- $show_user_answer = htmlspecialchars_decode( $single_answer[0], ENT_QUOTES );
1121
- $image_class = '';
1122
- }
1123
- if ( $is_user_answer && $is_answer_correct ) {
1124
- $question_with_answer_text .= '<span class="qsm-text-correct-option qsm-text-user-correct-answer ' . $image_class . '">' . $show_user_answer . '</span>';
1125
- } elseif ( ! $is_user_answer && $is_answer_correct ) {
1126
- $question_with_answer_text .= '<span class="qsm-text-correct-option ' . $image_class . '">' . $show_user_answer . '</span>';
1127
- } elseif ( $is_user_answer && ! $is_answer_correct ) {
1128
- $question_with_answer_text .= '<span class="qsm-text-wrong-option ' . $image_class . '">' . $show_user_answer . '</span>';
1129
- } else {
1130
- $question_with_answer_text .= '<span class="qsm-text-simple-option ' . $image_class . '">' . $show_user_answer . '</span>';
1131
- }
1132
  }
1133
  } else {
1134
  if ( 13 == $answer['question_type'] ) {
@@ -1137,55 +1095,19 @@ function qsm_questions_answers_shortcode_to_text( $mlw_quiz_array, $qmn_question
1137
  } elseif ( in_array( $answer['question_type'], $use_custom_default_template, true ) ) {
1138
  $question_with_answer_text .= apply_filters( 'qsm_result_page_custom_default_template', $total_answers, $questions, $answer );
1139
  } else {
1140
- foreach ( $total_answers as $single_answer_key => $single_answer ) {
1141
- $current_answer_key = $single_answer_key;
1142
- $user_answer_keys = array_keys( $answer['user_answer'] );
1143
- $correct_answer_keys = array_keys( $answer['correct_answer'] );
1144
- $is_answer_correct = false;
1145
- $is_user_answer = false;
1146
- if ( in_array( $current_answer_key, $correct_answer_keys, true ) ) {
1147
- $is_answer_correct = true;
1148
- }
1149
- if ( in_array( $current_answer_key, $user_answer_keys, true) ) {
1150
- $is_user_answer = true;
1151
- }
1152
- $image_class = '';
1153
- if ( isset( $question_settings['answerEditor'] ) && 'image' === $question_settings['answerEditor'] ) {
1154
- $show_user_answer = '<img src="' . htmlspecialchars_decode( $single_answer[0], ENT_QUOTES ) . '"/>';
1155
- $image_class = 'qmn_image_option';
1156
- } else {
1157
- $show_user_answer = htmlspecialchars_decode( $single_answer[0], ENT_QUOTES );
1158
- }
1159
- if ( $is_user_answer && $is_answer_correct ) {
1160
- $question_with_answer_text .= '<span class="qsm-text-correct-option qsm-text-user-correct-answer ' . $image_class . '">' . $show_user_answer . '</span>';
1161
- } elseif ( ! $is_user_answer && $is_answer_correct ) {
1162
- $question_with_answer_text .= '<span class="qsm-text-correct-option ' . $image_class . '">' . $show_user_answer . '</span>';
1163
- } elseif ( $is_user_answer && ! $is_answer_correct ) {
1164
- $question_with_answer_text .= '<span class="qsm-text-wrong-option ' . $image_class . '">' . $show_user_answer . '</span>';
1165
- } else {
1166
- $question_with_answer_text .= '<span class="qsm-text-simple-option ' . $image_class . '">' . $show_user_answer . '</span>';
1167
- }
1168
  }
1169
  }
1170
  }
1171
  } else {
1172
  if ( isset( $answer['question_type'] ) && ( 4 == $answer['question_type'] || 10 == $answer['question_type'] ) ) {
1173
- foreach ( $total_answers as $single_answer_key => $single_answer ) {
1174
- $image_class = '';
1175
- if ( isset( $question_settings['answerEditor'] ) && 'image' === $question_settings['answerEditor'] ) {
1176
- $show_user_answer = '<img src="' . htmlspecialchars_decode( $single_answer[0], ENT_QUOTES ) . '"/>';
1177
- $image_class = 'qmn_image_option';
1178
- } else {
1179
- $show_user_answer = htmlspecialchars_decode( $single_answer[0], ENT_QUOTES );
1180
- $image_class = '';
1181
- }
1182
- $current_answer_key = $single_answer_key;
1183
- $user_answer_keys = array_keys( $answer['user_answer'] );
1184
- if ( in_array( $current_answer_key, $user_answer_keys , true ) ) {
1185
- $question_with_answer_text .= '<span class="qsm-text-correct-option ' . $image_class . '">' . $show_user_answer . '</span>';
1186
- } else {
1187
- $question_with_answer_text .= '<span class="qsm-text-simple-option ' . $image_class . '">' . $show_user_answer . '</span>';
1188
- }
1189
  }
1190
  } else {
1191
  if ( 13 == $answer['question_type'] ) {
@@ -1196,22 +1118,10 @@ function qsm_questions_answers_shortcode_to_text( $mlw_quiz_array, $qmn_question
1196
  $question_type = $answer['question_type'];
1197
  $question_with_answer_text .= apply_filters( 'qsm_result_page_custom_default_template', $total_answers, $questions, $answer );
1198
  } else {
1199
- foreach ( $total_answers as $single_answer_key => $single_answer ) {
1200
- $image_class = '';
1201
- if ( isset( $question_settings['answerEditor'] ) && 'image' === $question_settings['answerEditor'] ) {
1202
- $show_user_answer = '<img src="' . htmlspecialchars_decode( $single_answer[0], ENT_QUOTES ) . '"/>';
1203
- $image_class = 'qmn_image_option';
1204
- } else {
1205
- $show_user_answer = htmlspecialchars_decode( $single_answer[0], ENT_QUOTES );
1206
- $image_class = '';
1207
- }
1208
- $current_answer_key = $single_answer_key;
1209
- $user_answer_keys = array_keys( $answer['user_answer'] );
1210
- if ( in_array( $current_answer_key, $user_answer_keys , true ) ) {
1211
- $question_with_answer_text .= '<span class="qsm-text-correct-option ' . $image_class . '">' . $show_user_answer . '</span>';
1212
- } else {
1213
- $question_with_answer_text .= '<span class="qsm-text-simple-option ' . $image_class . '">' . $show_user_answer . '</span>';
1214
- }
1215
  }
1216
  }
1217
  }
@@ -1246,7 +1156,8 @@ function qsm_questions_answers_shortcode_to_text( $mlw_quiz_array, $qmn_question
1246
  $mlw_question_answer_display = str_replace( '%USER_ANSWER%', $qsm_user_ans, $mlw_question_answer_display );
1247
  } else {
1248
  $user_answer_new = $answer[1];
1249
- if ( ( 0 == $answer['question_type'] || 1 == $answer['question_type'] || 2 == $answer['question_type'] ) && '' === $answer[1] ) {
 
1250
  $user_answer_new = __( 'No Answer Provided', 'quiz-master-next' );
1251
  }
1252
  if ( isset( $question_settings['answerEditor'] ) && 'image' === $question_settings['answerEditor'] && '' !== $user_answer_new ) {
11
  exit;
12
  }
13
 
14
+ //Template variable files
15
+ include 'template-variables/qsm-tempvar-question-answers.php';
16
+ //Template variable files for backward compatibility ( @since QSM 7.3.8 )
17
+ include 'backward-compatibility/qsm-backward-compatibility-template-variables.php';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
 
 
19
  add_filter( 'mlw_qmn_template_variable_results_page', 'qsm_all_contact_fields_variable', 10, 2 );
20
  add_filter( 'mlw_qmn_template_variable_results_page', 'qsm_contact_field_variable', 10, 2 );
21
  add_filter( 'mlw_qmn_template_variable_results_page', 'qmn_variable_category_points', 10, 2 );
61
  * Changed the display structure to new structure.
62
  *
63
  * @since 6.4.11
64
+ * @param string $content
65
  * @param array $mlw_quiz_array
66
  * Show particular question answer.
67
  */
144
  /**
145
  * Show poll result
146
  *
147
+ * @param string $content
148
+ * @param array $mlw_quiz_array
149
  */
150
  function qsm_variable_poll_result( $content, $mlw_quiz_array ) {
151
  $quiz_id = is_object( $mlw_quiz_array ) ? $mlw_quiz_array->quiz_id : $mlw_quiz_array['quiz_id'];
193
  /**
194
  * Show Answer type evaluated
195
  *
196
+ * @param string $answer
197
+ * @param array $question_settings
198
  */
199
  function qsm_answers_type_evaluated( $answer, $question_settings ) {
200
  if ( 'rich' === $question_settings['answerEditor'] ) {
276
  $content = str_replace( '%POINT_SCORE%', ( isset( $mlw_quiz_array['total_points'] ) ? $mlw_quiz_array['total_points'] : '' ), $content );
277
  return $content;
278
  }
279
+
280
  function mlw_qmn_variable_average_point( $content, $mlw_quiz_array ) {
281
  $question_total = 0;
282
  if ( isset( $mlw_quiz_array['question_answers_array'] ) ) {
869
  *
870
  * @since 7.1.3
871
  *
872
+ * @param array $mlw_quiz_array
873
+ * @param string $qmn_question_answer_template
874
+ * @param string $answer
875
  * @param int $qsm_question_cnt
876
  * @param int $total_question_cnt
877
  * @return string
1083
  } else {
1084
  if ( 0 == $form_type && ( 0 == $quiz_system || 3 == $quiz_system ) ) {
1085
  if ( isset( $answer['question_type'] ) && ( 4 == $answer['question_type'] || 10 == $answer['question_type'] ) ) {
1086
+ if ( isset( $answer['user_answer'] ) && isset( $answer['correct_answer'] ) ) {
1087
+ $question_with_answer_text .= qsm_tempvar_qa_text_qt_choice( $total_answers, $answer, $quiz_system, $question_settings );
1088
+ } else {
1089
+ $question_with_answer_text .= qsm_bckcmp_tempvar_qa_text_qt_multi_choice_correct( $total_answers, $answer, $question_settings );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1090
  }
1091
  } else {
1092
  if ( 13 == $answer['question_type'] ) {
1095
  } elseif ( in_array( $answer['question_type'], $use_custom_default_template, true ) ) {
1096
  $question_with_answer_text .= apply_filters( 'qsm_result_page_custom_default_template', $total_answers, $questions, $answer );
1097
  } else {
1098
+ if ( isset( $answer['user_answer'] ) && isset( $answer['correct_answer'] ) ) {
1099
+ $question_with_answer_text .= qsm_tempvar_qa_text_qt_choice( $total_answers, $answer, $quiz_system, $question_settings );
1100
+ } else {
1101
+ $question_with_answer_text .= qsm_bckcmp_tempvar_qa_text_qt_single_choice_correct( $total_answers, $answer, $question_settings );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1102
  }
1103
  }
1104
  }
1105
  } else {
1106
  if ( isset( $answer['question_type'] ) && ( 4 == $answer['question_type'] || 10 == $answer['question_type'] ) ) {
1107
+ if ( isset( $answer['user_answer'] ) && isset( $answer['correct_answer'] ) ) {
1108
+ $question_with_answer_text .= qsm_tempvar_qa_text_qt_choice( $total_answers, $answer, $quiz_system, $question_settings );
1109
+ } else {
1110
+ $question_with_answer_text .= qsm_bckcmp_tempvar_qa_text_qt_multi_choice_points( $total_answers, $answer, $question_settings );
 
 
 
 
 
 
 
 
 
 
 
 
1111
  }
1112
  } else {
1113
  if ( 13 == $answer['question_type'] ) {
1118
  $question_type = $answer['question_type'];
1119
  $question_with_answer_text .= apply_filters( 'qsm_result_page_custom_default_template', $total_answers, $questions, $answer );
1120
  } else {
1121
+ if ( isset( $answer['user_answer'] ) && isset( $answer['correct_answer'] ) ) {
1122
+ $question_with_answer_text .= qsm_tempvar_qa_text_qt_choice( $total_answers, $answer, $quiz_system, $question_settings );
1123
+ } else {
1124
+ $question_with_answer_text .= qsm_bckcmp_tempvar_qa_text_qt_single_choice_points( $total_answers, $answer, $question_settings );
 
 
 
 
 
 
 
 
 
 
 
 
1125
  }
1126
  }
1127
  }
1156
  $mlw_question_answer_display = str_replace( '%USER_ANSWER%', $qsm_user_ans, $mlw_question_answer_display );
1157
  } else {
1158
  $user_answer_new = $answer[1];
1159
+ $is_choice_question_type = 0 == $answer['question_type'] || 1 == $answer['question_type'] || 2 == $answer['question_type'] || 4 == $answer['question_type'] || 10 == $answer['question_type'] ;
1160
+ if ( $is_choice_question_type && '' === $answer[1] ) {
1161
  $user_answer_new = __( 'No Answer Provided', 'quiz-master-next' );
1162
  }
1163
  if ( isset( $question_settings['answerEditor'] ) && 'image' === $question_settings['answerEditor'] && '' !== $user_answer_new ) {
php/template-variables/qsm-tempvar-question-answers.php ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ function qsm_tempvar_qa_text_qt_choice( $answers_from_db, $answers_from_response, $grading_system, $question_settings ) {
4
+ $question_with_answer_text = '';
5
+ foreach ( $answers_from_db as $single_answer_key => $single_answer ) {
6
+ $current_answer_key = $single_answer_key;
7
+ $user_answer_array = isset( $answers_from_response['user_answer'] ) && is_array( $answers_from_response['user_answer'] ) ? $answers_from_response['user_answer'] : array();
8
+ $correct_answer_array = isset( $answers_from_response['correct_answer'] ) && is_array( $answers_from_response['correct_answer'] ) ? $answers_from_response['correct_answer'] : array();
9
+ $user_answer_keys = ! empty( $user_answer_array ) ? array_keys( $user_answer_array ) : array() ;
10
+ $correct_answer_keys = ! empty( $correct_answer_array ) ? array_keys( $correct_answer_array ) : array();
11
+ $is_answer_correct = false;
12
+ $is_user_answer = false;
13
+ if ( in_array( $current_answer_key, $correct_answer_keys, true ) ) {
14
+ $is_answer_correct = true;
15
+ }
16
+ if ( in_array( $current_answer_key, $user_answer_keys, true) ) {
17
+ $is_user_answer = true;
18
+ }
19
+ $image_class = '';
20
+ if ( isset( $question_settings['answerEditor'] ) && 'image' === $question_settings['answerEditor'] ) {
21
+ $show_user_answer = '<img src="' . htmlspecialchars_decode( $single_answer[0], ENT_QUOTES ) . '"/>';
22
+ $image_class = 'qmn_image_option';
23
+ } else {
24
+ $show_user_answer = htmlspecialchars_decode( $single_answer[0], ENT_QUOTES );
25
+ $image_class = '';
26
+ }
27
+ if ( 0 === intval( $grading_system ) || 3 === intval( $grading_system ) ) {
28
+ if ( $is_user_answer && $is_answer_correct ) {
29
+ $question_with_answer_text .= '<span class="qsm-text-correct-option qsm-text-user-correct-answer ' . $image_class . '">' . $show_user_answer . '</span>';
30
+ } elseif ( ! $is_user_answer && $is_answer_correct ) {
31
+ $question_with_answer_text .= '<span class="qsm-text-correct-option ' . $image_class . '">' . $show_user_answer . '</span>';
32
+ } elseif ( $is_user_answer && ! $is_answer_correct ) {
33
+ $question_with_answer_text .= '<span class="qsm-text-wrong-option ' . $image_class . '">' . $show_user_answer . '</span>';
34
+ } else {
35
+ $question_with_answer_text .= '<span class="qsm-text-simple-option ' . $image_class . '">' . $show_user_answer . '</span>';
36
+ }
37
+ } else {
38
+ if ( $is_user_answer ) {
39
+ $question_with_answer_text .= '<span class="qsm-text-correct-option ' . $image_class . '">' . $show_user_answer . '</span>';
40
+ } else {
41
+ $question_with_answer_text .= '<span class="qsm-text-simple-option ' . $image_class . '">' . $show_user_answer . '</span>';
42
+ }
43
+ }
44
+ }
45
+ return $question_with_answer_text;
46
+ }
readme.txt CHANGED
@@ -4,7 +4,7 @@ Tags: quiz, survey, lead, test, score, exam, questionnaire, question,wordpress q
4
  Requires at least: 4.9
5
  Tested up to: 5.8
6
  Requires PHP: 5.4
7
- Stable tag: 7.3.8
8
  License: GPLv2
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
@@ -100,10 +100,19 @@ Quiz And Survey Master is fully functional and is packed with tons of features t
100
  * Join our [official FB group](https://www.facebook.com/groups/516958552587745).
101
  * Quiz And Survey Master on [GitHub](https://github.com/QuizandSurveyMaster/quiz_master_next/)!
102
 
103
- = More free plugins for your WordPress Site =
 
 
 
 
 
 
104
 
105
- * 🎨 [Responsive Menu](https://wordpress.org/plugins/responsive-menu/) Highly customisable Responsive Menu Plugin for WordPress. No coding experience or knowledge is needed with an easy to use interface you can get it looking exactly as you want with minimal fuss.
106
- * 🔒 [Hide My WP](https://wordpress.org/plugins/hide-wp-login/) Makes it impossible for a hacker or an attacker to know the location of login url.
 
 
 
107
 
108
  == Installation ==
109
 
@@ -150,6 +159,13 @@ This is usually a theme conflict. You can [checkout out our common conflict solu
150
  17. QSM Pool Theme
151
  18. Database
152
 
 
 
 
 
 
 
 
153
  == Changelog ==
154
  = 7.3.8 (January 18, 2022) =
155
  * Bug: Fixed issues while taking quiz with logic questions.
4
  Requires at least: 4.9
5
  Tested up to: 5.8
6
  Requires PHP: 5.4
7
+ Stable tag: 7.3.9
8
  License: GPLv2
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
100
  * Join our [official FB group](https://www.facebook.com/groups/516958552587745).
101
  * Quiz And Survey Master on [GitHub](https://github.com/QuizandSurveyMaster/quiz_master_next/)!
102
 
103
+ 🌐Our Plugins
104
+
105
+ If you like this plugin, consider exploring our other plugins:
106
+
107
+ ☰ [Responsive Menu](https://wordpress.org/plugins/responsive-menu/) - Best WordPress Menu Builder Plugin to create awesome and interactive mobile & desktop menus for WordPress websites.
108
+
109
+ 📙 [Projectopia](https://wordpress.org/plugins/projectopia-core/) - Project Management & Invoicing plugin for WordPress. Generate invoices, send quotes, generate leads, manage clients, provide support - all inside your WordPress website.
110
 
111
+ 📅 [Booking Ultra](https://wordpress.org/plugins/booking-ultra-pro/) - Appointment Booking plugin for WordPress - Show a quick form to accept bookings for your services with pre-set booking slots. Ideal for salons, medical professionals, lawyers, consultants, etc.
112
+
113
+ ⚡ [InstaWP](https://instawp.io/) - Launch a quick WordPress site with this sandbox service. Create New WordPress instance within a second.
114
+
115
+ 🔒 [Hide My WP](https://hidemywp.net/) - Hide your WordPress from bots, attackers & spammers. Hides all the known URLs, paths, plugins, themes which can reveal that you are using WP, also comes with an in-built firewall & trust network.
116
 
117
  == Installation ==
118
 
159
  17. QSM Pool Theme
160
  18. Database
161
 
162
+ == Changelog ==
163
+ = 7.3.9 (January 20, 2022) =
164
+ * Hotfix: Issues with markup in email
165
+ * Hotfix: Issues with quiz review for blank submissions
166
+ * Hotfix: Issues with question/average points/score template variable
167
+ * Hotfix: Issues with result items on admin dashboard
168
+
169
  == Changelog ==
170
  = 7.3.8 (January 18, 2022) =
171
  * Bug: Fixed issues while taking quiz with logic questions.