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

Version Description

(August 13, 2021) = * Bug: Fixed the error on updating database. * Bug: Fixed the issue of everything displayed in the same line in the results page. * Bug: Fixed the issue of fill in the blank question type not showing user answer and correct answer in the results page and email. * Feature: Added global default settings for quiz options. * Enhancement: Added option to deny quiz submission after end date/time * Enhancement: Made order of random questions same on the results page and the quiz frontend.

Download this release

Release Info

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

Code changes from version 7.3.0 to 7.3.1

css/common.css CHANGED
@@ -166,9 +166,38 @@ footer.qsm-popup__footer button.qsm-popup-secondary-button:hover{
166
  cursor: pointer;
167
  }
168
 
 
169
  /**
170
  * Design for new template variable QUESTION_WITH_ANSWER
171
  */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
172
  .mlw_qmn_question .qsm-text-wrong-option{
173
  display: block;
174
  color: #dc3232;
166
  cursor: pointer;
167
  }
168
 
169
+
170
  /**
171
  * Design for new template variable QUESTION_WITH_ANSWER
172
  */
173
+
174
+ .mlw_qmn_question .qmn_user_incorrect_answer{
175
+ color: #dc3232;
176
+ margin-bottom: 5px;
177
+ padding-left: 10px;
178
+ }
179
+ .mlw_qmn_question span.qmn_user_incorrect_answer::before {
180
+ position: relative;
181
+ top: 3px;
182
+ content: "\f335";
183
+ font-family: dashicons;
184
+
185
+ left: -10px;
186
+ }
187
+
188
+ .mlw_qmn_question .qmn_user_correct_answer{
189
+ color: green;
190
+ margin-bottom: 5px;
191
+ padding-left: 10px;
192
+ }
193
+ .mlw_qmn_question .qmn_user_correct_answer:before{
194
+ content: "\f159";
195
+ font-family: dashicons;
196
+ position: relative;
197
+ top: 3px;
198
+ left: -10px;
199
+ }
200
+
201
  .mlw_qmn_question .qsm-text-wrong-option{
202
  display: block;
203
  color: #dc3232;
js/admin.js CHANGED
@@ -373,5 +373,29 @@ var QSMAdmin;
373
  button.nextAll('.qsm_featured_image_preview').attr('src', attachment.url);
374
  }).open();
375
  });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
376
  });
377
  }(jQuery));
373
  button.nextAll('.qsm_featured_image_preview').attr('src', attachment.url);
374
  }).open();
375
  });
376
+
377
+ $(document).on('change', '.global_form_type_settiong select[name="qsm-quiz-settings[form_type]"]', function () {
378
+ var value = $(this).val();
379
+ if (value == '0' ) {
380
+ $('.global_setting_system').parents('tr').show();
381
+ $('.global_setting_score_roundoff').parents('tr').show();
382
+ }else {
383
+ $('.global_setting_system').parents('tr').hide();
384
+ $('.global_setting_score_roundoff').parents('tr').hide();
385
+
386
+ }
387
+ });
388
+ $(document).on('change', '.global_setting_system input[name="qsm-quiz-settings[system]"]', function () {
389
+ var value = $('input[name="qsm-quiz-settings[system]"]:checked').val();
390
+ var value1 = $('.global_form_type_settiong select[name="qsm-quiz-settings[form_type]"]').val();
391
+ if (value != '1' && value1 == '0' ) {
392
+ $('.global_setting_score_roundoff').parents('tr').show();
393
+ }else {
394
+ $('.global_setting_score_roundoff').parents('tr').hide();
395
+ }
396
+ });
397
+ $('.global_form_type_settiong select[name="qsm-quiz-settings[form_type]"]').trigger('change');
398
+ $('.global_setting_system input[name="qsm-quiz-settings[system]"]').trigger('change');
399
+
400
  });
401
  }(jQuery));
js/qsm-quiz.js CHANGED
@@ -61,8 +61,7 @@ var QSMPageTimer;
61
  var $quizForm = QSM.getQuizForm(quizID);
62
 
63
  // Creates timer status key.
64
- qmn_quiz_data[quizID].timerStatus = false;
65
-
66
 
67
  // If we are using the newer pagination system...
68
  if (0 < $quizForm.children('.qsm-page').length) {
@@ -173,8 +172,13 @@ var QSMPageTimer;
173
  }
174
  var secondsRemaining = qmn_quiz_data[quizID].timerRemaning;
175
  var display = QSM.secondsToTimer(secondsRemaining);
176
-
177
- // Sets our local storage values for the timer being started and current timer value.
 
 
 
 
 
178
  localStorage.setItem('mlw_time_quiz' + quizID, secondsRemaining);
179
  localStorage.setItem('mlw_started_quiz' + quizID, "yes");
180
 
@@ -832,11 +836,11 @@ function getFormData($form) {
832
  }
833
 
834
  function qmnFormSubmit(quiz_form_id) {
 
835
  var quiz_id = +jQuery('#' + quiz_form_id).find('.qmn_quiz_id').val();
836
  var $container = jQuery('#' + quiz_form_id).closest('.qmn_quiz_container');
837
  var result = qmnValidation('#' + quiz_form_id + ' *', quiz_form_id);
838
 
839
-
840
  if (!result) { return result; }
841
 
842
  /**
@@ -860,8 +864,10 @@ function qmnFormSubmit(quiz_form_id) {
860
  fd.append(input.name, input.value);
861
  });
862
  fd.append("action", 'qmn_process_quiz');
 
 
863
 
864
-
865
  qsmEndTimeTakenTimer();
866
  if (qmn_quiz_data[quizID].hasOwnProperty('advanced_timer')) {
867
  QSMPageTimer.endPageTimer(quiz_id);
@@ -880,11 +886,19 @@ function qmnFormSubmit(quiz_form_id) {
880
  processData: false,
881
  type: 'POST',
882
  success: function (response) {
883
- qmnDisplayResults(JSON.parse(response), quiz_form_id, $container);
884
- jQuery(document).trigger('qsm_after_quiz_submit_load_chart');
 
 
 
 
 
 
 
 
885
  }
886
  });
887
- jQuery(document).trigger('qsm_after_quiz_submit', [quiz_form_id]);
888
  return false;
889
  }
890
 
61
  var $quizForm = QSM.getQuizForm(quizID);
62
 
63
  // Creates timer status key.
64
+ qmn_quiz_data[quizID].timerStatus = false;
 
65
 
66
  // If we are using the newer pagination system...
67
  if (0 < $quizForm.children('.qsm-page').length) {
172
  }
173
  var secondsRemaining = qmn_quiz_data[quizID].timerRemaning;
174
  var display = QSM.secondsToTimer(secondsRemaining);
175
+ var systemTime=new Date().getTime()/1000;
176
+ systemTime=Math.round(systemTime);
177
+ if('1'===qmn_quiz_data[quizID].not_allow_after_expired_time && systemTime > qmn_quiz_data[quizID].scheduled_time_end ){
178
+ MicroModal.show('modal-4');
179
+ return false;
180
+ }
181
+ // Sets our local storage values for the timer being started and current timer value.
182
  localStorage.setItem('mlw_time_quiz' + quizID, secondsRemaining);
183
  localStorage.setItem('mlw_started_quiz' + quizID, "yes");
184
 
836
  }
837
 
838
  function qmnFormSubmit(quiz_form_id) {
839
+
840
  var quiz_id = +jQuery('#' + quiz_form_id).find('.qmn_quiz_id').val();
841
  var $container = jQuery('#' + quiz_form_id).closest('.qmn_quiz_container');
842
  var result = qmnValidation('#' + quiz_form_id + ' *', quiz_form_id);
843
 
 
844
  if (!result) { return result; }
845
 
846
  /**
864
  fd.append(input.name, input.value);
865
  });
866
  fd.append("action", 'qmn_process_quiz');
867
+ fd.append("currentuserTime", Math.round(new Date().getTime()/1000));
868
+ fd.append("currentuserTimeZone",Intl.DateTimeFormat().resolvedOptions().timeZone);
869
 
870
+
871
  qsmEndTimeTakenTimer();
872
  if (qmn_quiz_data[quizID].hasOwnProperty('advanced_timer')) {
873
  QSMPageTimer.endPageTimer(quiz_id);
886
  processData: false,
887
  type: 'POST',
888
  success: function (response) {
889
+ response=JSON.parse(response);
890
+ if(response.quizExpired){
891
+ MicroModal.show('modal-4');
892
+ return false;
893
+ }else{
894
+ qmnDisplayResults(response, quiz_form_id, $container);
895
+ jQuery(document).trigger('qsm_after_quiz_submit_load_chart');
896
+ jQuery(document).trigger('qsm_after_quiz_submit', [quiz_form_id]);
897
+ }
898
+
899
  }
900
  });
901
+
902
  return false;
903
  }
904
 
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.0
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.0
13
  * @package QSM
14
  */
15
 
@@ -41,7 +41,7 @@ class MLWQuizMasterNext {
41
  * @var string
42
  * @since 4.0.0
43
  */
44
- public $version = '7.3.0';
45
 
46
  /**
47
  * QSM Alert Manager Object
2
  /**
3
  * Plugin Name: Quiz And Survey Master
4
  * Description: Easily and quickly add quizzes and surveys to your website.
5
+ * Version: 7.3.1
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.1
13
  * @package QSM
14
  */
15
 
41
  * @var string
42
  * @since 4.0.0
43
  */
44
+ public $version = '7.3.1';
45
 
46
  /**
47
  * QSM Alert Manager Object
php/admin/settings-page.php CHANGED
@@ -22,6 +22,7 @@ class QMNGlobalSettingsPage {
22
  */
23
  function __construct() {
24
  $this->add_hooks();
 
25
  }
26
 
27
  /**
@@ -34,6 +35,7 @@ class QMNGlobalSettingsPage {
34
  */
35
  private function add_hooks() {
36
  add_action( 'admin_init', array( $this, 'init' ) );
 
37
  }
38
 
39
  /**
@@ -49,18 +51,67 @@ class QMNGlobalSettingsPage {
49
  add_settings_field( 'ip-collection', __( 'Disable collecting and storing IP addresses?', 'quiz-master-next' ), array( $this, 'ip_collection_field' ), 'qmn_global_settings', 'qmn-global-section' );
50
  add_settings_field( 'cpt-search', __( 'Disable Quiz Posts From Being Searched?', 'quiz-master-next' ), array( $this, 'cpt_search_field' ), 'qmn_global_settings', 'qmn-global-section' );
51
  add_settings_field( 'cpt-archive', __( 'Disable Quiz Archive?', 'quiz-master-next' ), array( $this, 'cpt_archive_field' ), 'qmn_global_settings', 'qmn-global-section' );
52
- add_settings_field( 'detele-qsm-data', __( 'Delete all the data related to QSM on deletion?', 'quiz-master-next' ), array( $this, 'qsm_delete_data' ), 'qmn_global_settings', 'qmn-global-section' );
53
- add_settings_field( 'background-quiz-email-process', __( 'Process emails in background?', 'quiz-master-next' ), array( $this, 'qsm_background_quiz_email_process' ), 'qmn_global_settings', 'qmn-global-section' );
54
  add_settings_field( 'cpt-slug', __( 'Quiz Url Slug', 'quiz-master-next' ), array( $this, 'cpt_slug_field' ), 'qmn_global_settings', 'qmn-global-section' );
55
  add_settings_field( 'plural-name', __( 'Post Type Plural Name (Shown in various places such as on archive pages)', 'quiz-master-next' ), array( $this, 'plural_name_field' ), 'qmn_global_settings', 'qmn-global-section' );
56
  add_settings_field( 'facebook-app-id', __( 'Facebook App Id', 'quiz-master-next' ), array( $this, 'facebook_app_id' ), 'qmn_global_settings', 'qmn-global-section' );
57
  add_settings_field( 'from-name', __( 'From Name (The name emails come from)', 'quiz-master-next' ), array( $this, 'from_name' ), 'qmn_global_settings', 'qmn-global-section' );
58
  add_settings_field( 'from-email', __( 'From Email (The email address that emails come from)', 'quiz-master-next' ), array( $this, 'from_email' ), 'qmn_global_settings', 'qmn-global-section' );
59
- add_settings_field( 'items-per-page-question-bank', __( 'Items per page in question bank pagination', 'quiz-master-next' ), array( $this, 'items_per_page_question_bank' ), 'qmn_global_settings', 'qmn-global-section' );
60
- add_settings_field( 'new-template-result-detail', __( 'New Template For Admin Results Details', 'quiz-master-next' ), array( $this, 'new_template_results_details' ), 'qmn_global_settings', 'qmn-global-section' );
61
  add_settings_field( 'results-details', __( 'Template For Admin Results Details', 'quiz-master-next' ), array( $this, 'results_details_template' ), 'qmn_global_settings', 'qmn-global-section' );
62
  }
63
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
64
  /**
65
  * Generates Section Text
66
  *
@@ -371,12 +422,27 @@ class QMNGlobalSettingsPage {
371
  wp_enqueue_style( 'qsm_admin_style', plugins_url( '../../css/qsm-admin.css', __FILE__ ), array(), $mlwQuizMasterNext->version );
372
  wp_style_add_data( 'qsm_admin_style', 'rtl', 'replace' );
373
  wp_enqueue_script( 'qsm_admin_js', plugins_url( '../../js/admin.js', __FILE__ ), array( 'jquery' ), $mlwQuizMasterNext->version );
 
 
 
 
 
 
 
 
374
  ?>
375
  <div class="wrap">
376
  <h2><?php _e( 'Global Settings', 'quiz-master-next' ); ?></h2>
 
 
 
 
 
377
  <form action="options.php" method="POST" class="qsm_global_settings">
378
- <?php settings_fields( 'qmn-settings-group' ); ?>
379
- <?php do_settings_sections( 'qmn_global_settings' ); ?>
 
 
380
  <?php submit_button(); ?>
381
  </form>
382
  </div>
@@ -405,6 +471,641 @@ class QMNGlobalSettingsPage {
405
  echo __( 'Old Template', 'quiz-master-next' );
406
  echo '</label>';
407
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
408
  }
409
 
410
  $qmnGlobalSettingsPage = new QMNGlobalSettingsPage();
22
  */
23
  function __construct() {
24
  $this->add_hooks();
25
+ global $globalQuizsetting;
26
  }
27
 
28
  /**
35
  */
36
  private function add_hooks() {
37
  add_action( 'admin_init', array( $this, 'init' ) );
38
+ add_action( 'admin_init', array( $this, 'quiz_default_global_option_init' ) );
39
  }
40
 
41
  /**
51
  add_settings_field( 'ip-collection', __( 'Disable collecting and storing IP addresses?', 'quiz-master-next' ), array( $this, 'ip_collection_field' ), 'qmn_global_settings', 'qmn-global-section' );
52
  add_settings_field( 'cpt-search', __( 'Disable Quiz Posts From Being Searched?', 'quiz-master-next' ), array( $this, 'cpt_search_field' ), 'qmn_global_settings', 'qmn-global-section' );
53
  add_settings_field( 'cpt-archive', __( 'Disable Quiz Archive?', 'quiz-master-next' ), array( $this, 'cpt_archive_field' ), 'qmn_global_settings', 'qmn-global-section' );
54
+ add_settings_field( 'detele-qsm-data', __( 'Delete all the data related to QSM on deletion?', 'quiz-master-next' ), array( $this, 'qsm_delete_data' ), 'qmn_global_settings', 'qmn-global-section' );
55
+ add_settings_field( 'background-quiz-email-process', __( 'Process emails in background?', 'quiz-master-next' ), array( $this, 'qsm_background_quiz_email_process' ), 'qmn_global_settings', 'qmn-global-section' );
56
  add_settings_field( 'cpt-slug', __( 'Quiz Url Slug', 'quiz-master-next' ), array( $this, 'cpt_slug_field' ), 'qmn_global_settings', 'qmn-global-section' );
57
  add_settings_field( 'plural-name', __( 'Post Type Plural Name (Shown in various places such as on archive pages)', 'quiz-master-next' ), array( $this, 'plural_name_field' ), 'qmn_global_settings', 'qmn-global-section' );
58
  add_settings_field( 'facebook-app-id', __( 'Facebook App Id', 'quiz-master-next' ), array( $this, 'facebook_app_id' ), 'qmn_global_settings', 'qmn-global-section' );
59
  add_settings_field( 'from-name', __( 'From Name (The name emails come from)', 'quiz-master-next' ), array( $this, 'from_name' ), 'qmn_global_settings', 'qmn-global-section' );
60
  add_settings_field( 'from-email', __( 'From Email (The email address that emails come from)', 'quiz-master-next' ), array( $this, 'from_email' ), 'qmn_global_settings', 'qmn-global-section' );
61
+ add_settings_field( 'items-per-page-question-bank', __( 'Items per page in question bank pagination', 'quiz-master-next' ), array( $this, 'items_per_page_question_bank' ), 'qmn_global_settings', 'qmn-global-section' );
62
+ add_settings_field( 'new-template-result-detail', __( 'New Template For Admin Results Details', 'quiz-master-next' ), array( $this, 'new_template_results_details' ), 'qmn_global_settings', 'qmn-global-section' );
63
  add_settings_field( 'results-details', __( 'Template For Admin Results Details', 'quiz-master-next' ), array( $this, 'results_details_template' ), 'qmn_global_settings', 'qmn-global-section' );
64
  }
65
 
66
+ /**
67
+ * Prepares Settings Fields of global quiz default option
68
+ *
69
+ * @since 4.1.0
70
+ * @return void
71
+ */
72
+ public function quiz_default_global_option_init() {
73
+ register_setting( 'qsm-quiz-settings-group', 'qsm-quiz-settings' );
74
+ add_settings_section( 'qmn-global-section', __( 'Quiz Settings', 'quiz-master-next' ), array( $this, 'global_section' ), 'qsm_default_global_option' );
75
+ add_settings_field( 'quiz-type', __( 'Quiz Type', 'quiz-master-next' ), array( $this, 'qsm_global_quiz_type' ), 'qsm_default_global_option', 'qmn-global-section' );
76
+ add_settings_field( 'grading-system', __( 'Grading System', 'quiz-master-next' ), array( $this, 'qsm_global_grading_system' ), 'qsm_default_global_option', 'qmn-global-section' );
77
+ add_settings_field( 'allow-score-round-off', __( 'Allow Score Round-off', 'quiz-master-next' ), array( $this, 'qsm_global_score_roundoff' ), 'qsm_default_global_option', 'qmn-global-section' );
78
+ add_settings_field( 'show-progress-bar', __( 'Show progress bar', 'quiz-master-next' ), array( $this, 'qsm_global_show_progress_bar' ), 'qsm_default_global_option', 'qmn-global-section' );
79
+ add_settings_field( 'require-user-login', __( 'Require User Login', 'quiz-master-next' ), array( $this, 'qsm_global_require_user_login' ), 'qsm_default_global_option', 'qmn-global-section' );
80
+ add_settings_field( 'questions-per-page', __( 'Questions Per Page', 'quiz-master-next' ), array( $this, 'qsm_global_questions_per_page' ), 'qsm_default_global_option', 'qmn-global-section' );
81
+ add_settings_field( 'time-limit-in-minutes', __( 'Time Limit (in minutes)', 'quiz-master-next' ), array( $this, 'qsm_global_time_limit_in_minutes' ), 'qsm_default_global_option', 'qmn-global-section' );
82
+ add_settings_field( 'force-submit-after-timer-expiry', __( 'Force submit after timer expiry', 'quiz-master-next' ), array( $this, 'qsm_global_force_submit_after_timer_expiry' ), 'qsm_default_global_option', 'qmn-global-section' );
83
+ add_settings_field( 'skip-validations-when-time-expire', __( 'Skip validations when time expire', 'quiz-master-next' ), array( $this, 'qsm_global_skip_validations_when_time_expire' ), 'qsm_default_global_option', 'qmn-global-section' );
84
+ add_settings_field( 'limit-attempts', __( 'Limit Attempts', 'quiz-master-next' ), array( $this, 'qsm_global_limit_attempts' ), 'qsm_default_global_option', 'qmn-global-section' );
85
+ add_settings_field( 'limit-entries', __( 'Limit Entries', 'quiz-master-next' ), array( $this, 'qsm_global_limit_entries' ), 'qsm_default_global_option', 'qmn-global-section' );
86
+ add_settings_field( 'limit-number-of-questions', __( 'Limit number of Questions', 'quiz-master-next' ), array( $this, 'qsm_global_limit_number_of_questions' ), 'qsm_default_global_option', 'qmn-global-section' );
87
+ add_settings_field( 'limit-number-of-questions-per-category', __( 'Limit number of Questions Per Category', 'quiz-master-next' ), array( $this, 'qsm_global_limit_number_of_questions_per_category' ), 'qsm_default_global_option', 'qmn-global-section' );
88
+ add_settings_field( 'quiz-dates', __( 'Quiz Dates', 'quiz-master-next' ), array( $this, 'qsm_global_quiz_dates' ), 'qsm_default_global_option', 'qmn-global-section' );
89
+ add_settings_field( 'can-submit-after-end-date', __( 'Do not allow quiz submission after the end date/time', 'quiz-master-next' ), array( $this, 'qsm_global_Do_not_allow_quiz_submission_after_the_end_datetime' ), 'qsm_default_global_option', 'qmn-global-section' );
90
+ add_settings_field( 'random-questions', __( 'Random Questions', 'quiz-master-next' ), array( $this, 'qsm_global_random_questions' ), 'qsm_default_global_option', 'qmn-global-section' );
91
+ add_settings_field( 'contact-form-position', __( 'Contact form position', 'quiz-master-next' ), array( $this, 'qsm_global_contact_form_position' ), 'qsm_default_global_option', 'qmn-global-section' );
92
+ add_settings_field( 'show-contact-form-to-logged-in-users', __( 'Show contact form to logged in users', 'quiz-master-next' ), array( $this, 'qsm_global_show_contact_form_to_logged_in_users' ), 'qsm_default_global_option', 'qmn-global-section' );
93
+ add_settings_field( 'enable-comments', __( 'Enable comments', 'quiz-master-next' ), array( $this, 'qsm_global_enable_comments' ), 'qsm_default_global_option', 'qmn-global-section' );
94
+ add_settings_field( 'show-question-numbers', __( 'Show question numbers', 'quiz-master-next' ), array( $this, 'qsm_global_show_question_numbers' ), 'qsm_default_global_option', 'qmn-global-section' );
95
+ add_settings_field( 'save-responses', __( 'Save Responses', 'quiz-master-next' ), array( $this, 'qsm_global_save_responses' ), 'qsm_default_global_option', 'qmn-global-section' );
96
+ add_settings_field( 'disable-change-of-answers', __( 'Disable change of answers', 'quiz-master-next' ), array( $this, 'qsm_global_disable_change_of_answers' ), 'qsm_default_global_option', 'qmn-global-section' );
97
+ add_settings_field( 'add-class-for-correct-incorrect-answers', __( 'Add class for correct/incorrect answers', 'quiz-master-next' ), array( $this, 'qsm_global_add_class_for_correct_incorrect_answers' ), 'qsm_default_global_option', 'qmn-global-section' );
98
+ add_settings_field( 'disable-auto-fill-for-contact-input', __( 'Disable auto fill for contact input', 'quiz-master-next' ), array( $this, 'qsm_global_disable_auto_fill_for_contact_input' ), 'qsm_default_global_option', 'qmn-global-section' );
99
+ add_settings_field( 'disable-auto-fill-for-quiz-input', __( 'Disable auto fill for Quiz input', 'quiz-master-next' ), array( $this, 'qsm_global_disable_auto_fill_for_quiz_input' ), 'qsm_default_global_option', 'qmn-global-section' );
100
+ add_settings_field( 'display-category-name-on-front-end', __( 'Display category name on front end', 'quiz-master-next' ), array( $this, 'qsm_global_display_category_name_on_front_end' ), 'qsm_default_global_option', 'qmn-global-section' );
101
+ add_settings_field( 'show-results-inline', __( 'Show results inline', 'quiz-master-next' ), array( $this, 'qsm_global_show_results_inline' ), 'qsm_default_global_option', 'qmn-global-section' );
102
+ add_settings_field( 'end-quiz-if-there-is-wrong-answer', __( 'End quiz if there is wrong answer', 'quiz-master-next' ), array( $this, 'qsm_global_end_quiz_if_there_is_wrong_answer' ), 'qsm_default_global_option', 'qmn-global-section' );
103
+ add_settings_field( 'show-correct-answer-inline', __( 'Show correct answer inline', 'quiz-master-next' ), array( $this, 'qsm_global_show_correct_answer_inline' ), 'qsm_default_global_option', 'qmn-global-section' );
104
+ add_settings_field( 'retake-quiz', __( 'Retake Quiz', 'quiz-master-next' ), array( $this, 'qsm_global_retake_quiz' ), 'qsm_default_global_option', 'qmn-global-section' );
105
+ add_settings_field( 'show-current-page-number', __( 'Show current page number', 'quiz-master-next' ), array( $this, 'qsm_global_show_current_page_number' ), 'qsm_default_global_option', 'qmn-global-section' );
106
+ add_settings_field( 'deselect-answer', __( 'Deselect Answer', 'quiz-master-next' ), array( $this, 'qsm_global_deselect_answer' ), 'qsm_default_global_option', 'qmn-global-section' );
107
+ add_settings_field( 'disable-description-on-quiz-result-page', __( 'Disable description on quiz result page?', 'quiz-master-next' ), array( $this, 'qsm_global_disable_description_on_quiz_result_page' ), 'qsm_default_global_option', 'qmn-global-section' );
108
+ add_settings_field( 'disable-scroll-on-next-and-previous-button-click', __( 'Disable scroll on next and previous button click?', 'quiz-master-next' ), array( $this, 'qsm_global_disable_scroll_on_next_and_previous_button_click' ), 'qsm_default_global_option', 'qmn-global-section' );
109
+ add_settings_field( 'quiz-animation', __( 'Quiz Animation', 'quiz-master-next' ), array( $this, 'qsm_global_quiz_animation' ), 'qsm_default_global_option', 'qmn-global-section' );
110
+ add_settings_field( 'logo-url', __( 'Logo URL', 'quiz-master-next' ), array( $this, 'qsm_global_logo_url' ), 'qsm_default_global_option', 'qmn-global-section' );
111
+ global $globalQuizsetting;
112
+ $globalQuizsetting=get_option( 'qsm-quiz-settings' );
113
+
114
+ }
115
  /**
116
  * Generates Section Text
117
  *
422
  wp_enqueue_style( 'qsm_admin_style', plugins_url( '../../css/qsm-admin.css', __FILE__ ), array(), $mlwQuizMasterNext->version );
423
  wp_style_add_data( 'qsm_admin_style', 'rtl', 'replace' );
424
  wp_enqueue_script( 'qsm_admin_js', plugins_url( '../../js/admin.js', __FILE__ ), array( 'jquery' ), $mlwQuizMasterNext->version );
425
+ $active_tab = "qmn_global_settings";
426
+ if(isset($_GET["tab"])){
427
+ if($_GET["tab"] == "qmn_global_settings"){
428
+ $active_tab = "qmn_global_settings";
429
+ }else{
430
+ $active_tab = "quiz-default-qptions";
431
+ }
432
+ }
433
  ?>
434
  <div class="wrap">
435
  <h2><?php _e( 'Global Settings', 'quiz-master-next' ); ?></h2>
436
+ <h2 class="nav-tab-wrapper">
437
+ <!-- when tab buttons are clicked we jump back to the same page but with a new parameter that represents the clicked tab. accordingly we make it active -->
438
+ <a href="?page=qmn_global_settings&tab=qmn_global_settings" class="nav-tab <?php if($active_tab == 'qmn_global_settings'){echo 'nav-tab-active';} ?> "><?php _e('Main Settings', 'quiz-master-next'); ?></a>
439
+ <a href="?page=qmn_global_settings&tab=quiz-default-qptions" class="nav-tab <?php if($active_tab == 'quiz-default-qptions'){echo 'nav-tab-active';} ?>"><?php _e('Quiz Default Options', 'quiz-master-next'); ?></a>
440
+ </h2>
441
  <form action="options.php" method="POST" class="qsm_global_settings">
442
+
443
+
444
+ <?php if($active_tab == 'qmn_global_settings'){ settings_fields( 'qmn-settings-group' ); do_settings_sections( 'qmn_global_settings' ); }?>
445
+ <?php if($active_tab == 'quiz-default-qptions'){ settings_fields( 'qsm-quiz-settings-group' ); do_settings_sections( 'qsm_default_global_option' ); }?>
446
  <?php submit_button(); ?>
447
  </form>
448
  </div>
471
  echo __( 'Old Template', 'quiz-master-next' );
472
  echo '</label>';
473
  }
474
+
475
+ /**
476
+ * Generates Quiz Global Field For Quiz Type
477
+ *
478
+ * @since 4.1.0
479
+ * @return void
480
+ */
481
+ public function qsm_global_quiz_type() {
482
+ global $globalQuizsetting;
483
+ $qsm_form_type =(isset($globalQuizsetting['form_type']) && '' !== $globalQuizsetting['form_type'] ? $globalQuizsetting['form_type'] :"");
484
+ echo '<div class="global_form_type_settiong"><select name ="qsm-quiz-settings[form_type]">
485
+ <option value="0" '.($qsm_form_type=='0' ? "Selected" :"").'>Quiz</option>
486
+ <option value="1" '.($qsm_form_type=='1' ? "Selected" :"").' >Survey</option>
487
+ <option value="2" '.($qsm_form_type=='2' ? "Selected" :"").'>Simple Form</option>
488
+ </select></div>';
489
+ }
490
+
491
+ /**
492
+ * Generates Quiz Global Field For grading system
493
+ *
494
+ * @since 4.1.0
495
+ * @return void
496
+ */
497
+ public function qsm_global_grading_system() {
498
+ global $globalQuizsetting;
499
+ $qsm_system =(isset($globalQuizsetting['system']) && '' !== $globalQuizsetting['system'] ? $globalQuizsetting['system'] :"");
500
+ echo '<fieldset class="buttonset buttonset-hide global_setting_system" >
501
+ <input type="radio" id="system-0" name="qsm-quiz-settings[system]" value="0" '. checked( $qsm_system, '0', false ) .'>
502
+ <label for="system-0">Correct/Incorrect</label><br>
503
+ <input type="radio" id="system-1" name="qsm-quiz-settings[system]" value="1" '. checked( $qsm_system, '1', false ) .'>
504
+ <label for="system-1">Points</label><br>
505
+ <input type="radio" id="system-3" name="qsm-quiz-settings[system]" value="3" '. checked( $qsm_system, '3', false ) .'>
506
+ <label for="system-3">Both</label><br>
507
+ </fieldset>
508
+ <span class="qsm-opt-desc">Select the system for grading the quiz.</span>';
509
+ }
510
+
511
+ /**
512
+ * Generates Quiz Global Field For Allow Score Round-off
513
+ *
514
+ * @since 4.1.0
515
+ * @return void
516
+ */
517
+ public function qsm_global_score_roundoff() {
518
+ global $globalQuizsetting;
519
+ $qsm_score_roundoff =(isset($globalQuizsetting['score_roundoff']) && '' !== $globalQuizsetting['score_roundoff'] ? $globalQuizsetting['score_roundoff'] :"");
520
+ echo '<fieldset class="buttonset buttonset-hide global_setting_score_roundoff" >
521
+ <input type="checkbox" id="score_roundoff-1" name="qsm-quiz-settings[score_roundoff]" value="1" '. checked( $qsm_score_roundoff, '1', false ) .'>
522
+ </fieldset>';
523
+ }
524
+
525
+ /**
526
+ * Generates Quiz Global Field For Show progress bar
527
+ *
528
+ * @since 4.1.0
529
+ * @return void
530
+ */
531
+ public function qsm_global_show_progress_bar() {
532
+ global $globalQuizsetting;
533
+ $qsm_progress_bar =(isset($globalQuizsetting['progress_bar']) && '' !== $globalQuizsetting['progress_bar'] ? $globalQuizsetting['progress_bar'] :"0");
534
+ echo '<fieldset class="buttonset buttonset-hide qsm_tab_content" >
535
+ <input type="radio" id="progress_bar-1" name="qsm-quiz-settings[progress_bar]" value="1" '. checked( $qsm_progress_bar, '1', false ) .' >
536
+ <label for="progress_bar-1">Yes</label><br>
537
+ <input type="radio" id="progress_bar-0" name="qsm-quiz-settings[progress_bar]" value="0" '. checked( $qsm_progress_bar, '0', false ) .'>
538
+ <label for="progress_bar-0">No</label><br>
539
+ </fieldset>';
540
+ }
541
+
542
+ /**
543
+ * Generates Quiz Global Field For Require User Login
544
+ *
545
+ * @since 4.1.0
546
+ * @return void
547
+ */
548
+ public function qsm_global_require_user_login() {
549
+ global $globalQuizsetting;
550
+
551
+ $qsm_require_log_in =(isset($globalQuizsetting['require_log_in']) && '' !== $globalQuizsetting['require_log_in'] ? $globalQuizsetting['require_log_in'] :"0");
552
+ echo '<fieldset class="buttonset buttonset-hide" >
553
+ <input type="radio" id="require_log_in-1" name="qsm-quiz-settings[require_log_in]" value="1" '. checked( $qsm_require_log_in, '1', false ) .'>
554
+ <label for="require_log_in-1">Yes</label><br>
555
+ <input type="radio" id="require_log_in-0" name="qsm-quiz-settings[require_log_in]" value="0" '. checked( $qsm_require_log_in, '0', false ) .'>
556
+ <label for="require_log_in-0">No</label><br>
557
+ </fieldset>
558
+ <span class="qsm-opt-desc">Enabling this allows only logged in users to take the quiz</span>';
559
+ }
560
+
561
+ /**
562
+ * Generates Quiz Global Field For Questions Per Page
563
+ *
564
+ * @since 4.1.0
565
+ * @return void
566
+ */
567
+ public function qsm_global_questions_per_page() {
568
+ global $globalQuizsetting;
569
+ $qsm_pagination =(isset($globalQuizsetting['pagination']) && '' !== $globalQuizsetting['pagination'] ? $globalQuizsetting['pagination'] :"0");
570
+ echo '<input type="number" step="1" min="0" id="pagination" name="qsm-quiz-settings[pagination]" value="'.$qsm_pagination.'">
571
+ <span class="qsm-opt-desc">Override the default pagination created on questions tab</span>';
572
+ }
573
+
574
+ /**
575
+ * Generates Quiz Global Field For Time Limit (in minutes)
576
+ *
577
+ * @since 4.1.0
578
+ * @return void
579
+ */
580
+ public function qsm_global_time_limit_in_minutes() {
581
+ global $globalQuizsetting;
582
+ $qsm_timer_limit =(isset($globalQuizsetting['timer_limit']) && '' !== $globalQuizsetting['timer_limit'] ? $globalQuizsetting['timer_limit'] :"0");
583
+ echo '<input type="number" step="1" min="0" id="timer_limit" name="qsm-quiz-settings[timer_limit]" value="'.$qsm_timer_limit.'">
584
+ <span class="qsm-opt-desc">Leave 0 for no time limit</span>';
585
+ }
586
+
587
+ /**
588
+ * Generates Quiz Global Field For Force submit after timer expiry
589
+ *
590
+ * @since 4.1.0
591
+ * @return void
592
+ */
593
+ public function qsm_global_force_submit_after_timer_expiry() {
594
+ global $globalQuizsetting;
595
+ $qsm_enable_result_after_timer_end =(isset($globalQuizsetting['enable_result_after_timer_end']) && '' !== $globalQuizsetting['enable_result_after_timer_end'] ? $globalQuizsetting['enable_result_after_timer_end'] :"0");
596
+ echo '<fieldset class="buttonset buttonset-hide" >
597
+ <input type="radio" id="enable_result_after_timer_end-1" name="qsm-quiz-settings[enable_result_after_timer_end]" value="1" '. checked( $qsm_enable_result_after_timer_end, '1', false ) .'>
598
+ <label for="enable_result_after_timer_end-1">Yes</label><br>
599
+ <input type="radio" id="enable_result_after_timer_end-0" name="qsm-quiz-settings[enable_result_after_timer_end]" value="0" '. checked( $qsm_enable_result_after_timer_end, '0', false ) .'>
600
+ <label for="enable_result_after_timer_end-0">No</label><br>
601
+ </fieldset>';
602
+ }
603
+ /**
604
+ * Generates Quiz Global Field For Skip validations when time expire
605
+ *
606
+ * @since 4.1.0
607
+ * @return void
608
+ */
609
+ public function qsm_global_skip_validations_when_time_expire() {
610
+ global $globalQuizsetting;
611
+ $qsm_skip_validation_time_expire =(isset($globalQuizsetting['skip_validation_time_expire']) && '' !== $globalQuizsetting['skip_validation_time_expire'] ? $globalQuizsetting['skip_validation_time_expire'] :"0");
612
+ echo '<fieldset class="buttonset buttonset-hide" >
613
+ <input type="radio" id="skip_validation_time_expire-1" name="qsm-quiz-settings[skip_validation_time_expire]" value="1" '. checked( $qsm_skip_validation_time_expire, '1', false ) .'>
614
+ <label for="skip_validation_time_expire-1">Yes</label><br>
615
+ <input type="radio" id="skip_validation_time_expire-0" name="qsm-quiz-settings[skip_validation_time_expire]" value="0" '. checked( $qsm_skip_validation_time_expire, '0', false ) .'>
616
+ <label for="skip_validation_time_expire-0">No</label><br>
617
+ </fieldset>';
618
+ }
619
+
620
+ /**
621
+ * Generates Quiz Global Field For Limit Attempts
622
+ *
623
+ * @since 4.1.0
624
+ * @return void
625
+ */
626
+ public function qsm_global_limit_attempts() {
627
+ global $globalQuizsetting;
628
+ $qsm_total_user_tries =(isset($globalQuizsetting['total_user_tries']) && '' !== $globalQuizsetting['total_user_tries'] ? $globalQuizsetting['total_user_tries'] :"0");
629
+ echo '<input type="number" step="1" min="0" id="total_user_tries" name="qsm-quiz-settings[total_user_tries]" value="'.$qsm_total_user_tries.'">
630
+ <span class="qsm-opt-desc">Leave 0 for unlimited attempts</span>';
631
+ }
632
+
633
+
634
+ /**
635
+ * Generates Quiz Global Field For Limit Entries
636
+ *
637
+ * @since 4.1.0
638
+ * @return void
639
+ */
640
+ public function qsm_global_limit_entries() {
641
+ global $globalQuizsetting;
642
+ $qsm_limit_total_entries =(isset($globalQuizsetting['limit_total_entries']) && '' !== $globalQuizsetting['limit_total_entries'] ? $globalQuizsetting['limit_total_entries'] :"0");
643
+ echo '<input type="number" step="1" min="0" id="limit_total_entries" name="qsm-quiz-settings[limit_total_entries]" value="'.$qsm_limit_total_entries.'">
644
+ <span class="qsm-opt-desc">Leave 0 for unlimited entries</span>';
645
+
646
+ }
647
+
648
+ /**
649
+ * Generates Quiz Global Field For Limit number of Questions
650
+ *
651
+ * @since 4.1.0
652
+ * @return void
653
+ */
654
+ public function qsm_global_limit_number_of_questions() {
655
+ global $globalQuizsetting;
656
+ $qsm_question_from_total =(isset($globalQuizsetting['question_from_total']) && '' !== $globalQuizsetting['question_from_total'] ? $globalQuizsetting['question_from_total'] :"0");
657
+ echo '<input type="number" step="1" min="0" id="question_from_total" name="qsm-quiz-settings[question_from_total]" value="'.$qsm_question_from_total.'">
658
+ <span class="qsm-opt-desc">Leave 0 to load all questions</span>';
659
+ }
660
+
661
+
662
+
663
+ /**
664
+ * Generates Quiz Global Field For Limit number of Questions Per Category
665
+ *
666
+ * @since 4.1.0
667
+ * @return void
668
+ */
669
+ public function qsm_global_limit_number_of_questions_per_category() {
670
+ global $globalQuizsetting;
671
+ $qsm_question_per_category =(isset($globalQuizsetting['question_per_category']) && '' !== $globalQuizsetting['question_per_category'] ? $globalQuizsetting['question_per_category'] :"0");
672
+ echo '<input type="number" step="1" min="0" id="question_per_category" name="qsm-quiz-settings[question_per_category]" value="'.$qsm_question_per_category.'">
673
+ <span class="qsm-opt-desc">Leave 0 to load all questions. You also need to set Limit Number of questions, as well as select Question Categories</span>';
674
+ }
675
+
676
+
677
+ /**
678
+ * Generates Quiz Global Field For Contact form position
679
+ *
680
+ * @since 4.1.0
681
+ * @return void
682
+ */
683
+ public function qsm_global_contact_form_position() {
684
+ global $globalQuizsetting;
685
+ $qsm_contact_info_location =(isset($globalQuizsetting['contact_info_location']) && '' !== $globalQuizsetting['contact_info_location'] ? $globalQuizsetting['contact_info_location'] :"0");
686
+ echo '<fieldset class="buttonset buttonset-hide" >
687
+ <input type="radio" id="contact_info_location-0" name="qsm-quiz-settings[contact_info_location]" value="0" '. checked( $qsm_contact_info_location, '0', false ) .'>
688
+ <label for="contact_info_location-0">Show before quiz begins</label><br>
689
+ <input type="radio" id="contact_info_location-1" name="qsm-quiz-settings[contact_info_location]" value="1" '. checked( $qsm_contact_info_location, '1', false ) .'>
690
+ <label for="contact_info_location-1">Show after the quiz ends</label><br>
691
+ </fieldset>
692
+ <span class="qsm-opt-desc">Select when to display the contact form</span>';
693
+ }
694
+
695
+ /**
696
+ * Generates Quiz Global Field For Show contact form to logged in users
697
+ *
698
+ * @since 4.1.0
699
+ * @return void
700
+ */
701
+ public function qsm_global_show_contact_form_to_logged_in_users() {
702
+ global $globalQuizsetting;
703
+ $qsm_loggedin_user_contact =(isset($globalQuizsetting['loggedin_user_contact']) && '' !== $globalQuizsetting['loggedin_user_contact'] ? $globalQuizsetting['loggedin_user_contact'] :"0");
704
+ echo '<fieldset class="buttonset buttonset-hide" >
705
+ <input type="radio" id="loggedin_user_contact-0" name="qsm-quiz-settings[loggedin_user_contact]" value="0" '. checked( $qsm_loggedin_user_contact, '0', false ) .'>
706
+ <label for="loggedin_user_contact-0">Yes</label><br>
707
+ <input type="radio" id="loggedin_user_contact-1" name="qsm-quiz-settings[loggedin_user_contact]" value="1" '. checked( $qsm_loggedin_user_contact, '1', false ) .'>
708
+ <label for="loggedin_user_contact-1">No</label><br>
709
+ </fieldset>
710
+ <span class="qsm-opt-desc">Logged in users can edit their contact information</span>';
711
+ }
712
+
713
+ /**
714
+ * Generates Quiz Global Field For Enable comments
715
+ *
716
+ * @since 4.1.0
717
+ * @return void
718
+ */
719
+ public function qsm_global_enable_comments() {
720
+ global $globalQuizsetting;
721
+ $qsm_comment_section =(isset($globalQuizsetting['comment_section']) && '' !== $globalQuizsetting['comment_section'] ? $globalQuizsetting['comment_section'] :"0");
722
+ echo '<fieldset class="buttonset buttonset-hide" >
723
+ <input type="radio" id="comment_section-0" name="qsm-quiz-settings[comment_section]" value="0" '. checked( $qsm_comment_section, '0', false ) .'>
724
+ <label for="comment_section-0">Yes</label><br>
725
+ <input type="radio" id="comment_section-1" name="qsm-quiz-settings[comment_section]" value="1" '. checked( $qsm_comment_section, '1', false ) .'>
726
+ <label for="comment_section-1">No</label><br>
727
+ </fieldset>
728
+ <span class="qsm-opt-desc">Allow users to enter their comments after the quiz</span>';
729
+ }
730
+
731
+ /**
732
+ * Generates Quiz Global Field For Show question numbers
733
+ *
734
+ * @since 4.1.0
735
+ * @return void
736
+ */
737
+ public function qsm_global_show_question_numbers() {
738
+ global $globalQuizsetting;
739
+ $qsm_question_numbering =(isset($globalQuizsetting['question_numbering']) && '' !== $globalQuizsetting['question_numbering'] ? $globalQuizsetting['question_numbering'] :"0");
740
+ echo '<fieldset class="buttonset buttonset-hide" >
741
+ <input type="radio" id="question_numbering-1" name="qsm-quiz-settings[question_numbering]" value="1" '. checked( $qsm_question_numbering, '1', false ) .'>
742
+ <label for="question_numbering-1">Yes</label><br>
743
+ <input type="radio" id="question_numbering-0" name="qsm-quiz-settings[question_numbering]" value="0" '. checked( $qsm_question_numbering, '0', false ) .'>
744
+ <label for="question_numbering-0">No</label><br>
745
+ </fieldset>';
746
+ }
747
+
748
+ /**
749
+ * Generates Quiz Global Field For Save Responses
750
+ *
751
+ * @since 4.1.0
752
+ * @return void
753
+ */
754
+ public function qsm_global_save_responses() {
755
+ global $globalQuizsetting;
756
+ $qsm_store_responses =(isset($globalQuizsetting['store_responses']) && '' !== $globalQuizsetting['store_responses'] ? $globalQuizsetting['store_responses'] :"0");
757
+ echo '<fieldset class="buttonset buttonset-hide" >
758
+ <input type="radio" id="store_responses-1" name="qsm-quiz-settings[store_responses]" value="1" '. checked( $qsm_store_responses, '1', false ) .'>
759
+ <label for="store_responses-1">Yes</label><br>
760
+ <input type="radio" id="store_responses-0" name="qsm-quiz-settings[store_responses]" value="0" '. checked( $qsm_store_responses, '0', false ) .'>
761
+ <label for="store_responses-0">No</label><br>
762
+ </fieldset>
763
+ <span class="qsm-opt-desc">The results will be permanently stored in a database</span>';
764
+ }
765
+
766
+ /**
767
+ * Generates Quiz Global Field For Disable change of answers
768
+ *
769
+ * @since 4.1.0
770
+ * @return void
771
+ */
772
+ public function qsm_global_disable_change_of_answers() {
773
+ global $globalQuizsetting;
774
+ $qsm_disable_answer_onselect =(isset($globalQuizsetting['disable_answer_onselect']) && '' !== $globalQuizsetting['disable_answer_onselect'] ? $globalQuizsetting['disable_answer_onselect'] :"0");
775
+ echo '<fieldset class="buttonset buttonset-hide" >
776
+ <input type="radio" id="disable_answer_onselect-1" name="qsm-quiz-settings[disable_answer_onselect]" value="1" '. checked( $qsm_disable_answer_onselect, '1', false ) .'>
777
+ <label for="disable_answer_onselect-1">Yes</label><br>
778
+ <input type="radio" id="disable_answer_onselect-0" name="qsm-quiz-settings[disable_answer_onselect]" value="0" '. checked( $qsm_disable_answer_onselect, '0', false ) .'>
779
+ <label for="disable_answer_onselect-0">No</label><br>
780
+ </fieldset>
781
+ <span class="qsm-opt-desc">Works with multiple choice questions only</span>';
782
+ }
783
+
784
+ /**
785
+ * Generates Quiz Global Field For Add class for correct/incorrect answers
786
+ *
787
+ * @since 4.1.0
788
+ * @return void
789
+ */
790
+ public function qsm_global_add_class_for_correct_incorrect_answers() {
791
+ global $globalQuizsetting;
792
+ $qsm_ajax_show_correct =(isset($globalQuizsetting['ajax_show_correct']) && '' !== $globalQuizsetting['ajax_show_correct'] ? $globalQuizsetting['ajax_show_correct'] :"0");
793
+ echo '<fieldset class="buttonset buttonset-hide" >
794
+ <input type="radio" id="ajax_show_correct-1" name="qsm-quiz-settings[ajax_show_correct]" value="1" '. checked( $qsm_ajax_show_correct, '1', false ) .'>
795
+ <label for="ajax_show_correct-1">Yes</label><br>
796
+ <input type="radio" id="ajax_show_correct-0" name="qsm-quiz-settings[ajax_show_correct]"value="0" '. checked( $qsm_ajax_show_correct, '0', false ) .'>
797
+ <label for="ajax_show_correct-0">No</label><br>
798
+ </fieldset>
799
+ <span class="qsm-opt-desc">Works with multiple choice questions only</span>';
800
+ }
801
+
802
+ /**
803
+ * Generates Quiz Global Field For Disable auto fill for contact input
804
+ *
805
+ * @since 4.1.0
806
+ * @return void
807
+ */
808
+ public function qsm_global_disable_auto_fill_for_contact_input() {
809
+ global $globalQuizsetting;
810
+ $qsm_contact_disable_autofill =(isset($globalQuizsetting['contact_disable_autofill']) && '' !== $globalQuizsetting['contact_disable_autofill'] ? $globalQuizsetting['contact_disable_autofill'] :"0");
811
+ echo '<fieldset class="buttonset buttonset-hide" >
812
+ <input type="radio" id="contact_disable_autofill-1" name="qsm-quiz-settings[contact_disable_autofill]" value="1" '. checked( $qsm_contact_disable_autofill, '1', false ) .'>
813
+ <label for="contact_disable_autofill-1">Yes</label><br>
814
+ <input type="radio" id="contact_disable_autofill-0" name="qsm-quiz-settings[contact_disable_autofill]" value="0" '. checked( $qsm_contact_disable_autofill, '0', false ) .'>
815
+ <label for="contact_disable_autofill-0">No</label><br>
816
+ </fieldset>';
817
+ }
818
+
819
+ /**
820
+ * Generates Quiz Global Field For Disable auto fill for Quiz input
821
+ *
822
+ * @since 4.1.0
823
+ * @return void
824
+ */
825
+ public function qsm_global_disable_auto_fill_for_quiz_input() {
826
+ global $globalQuizsetting;
827
+ $qsm_form_disable_autofill =(isset($globalQuizsetting['form_disable_autofill']) && '' !== $globalQuizsetting['form_disable_autofill'] ? $globalQuizsetting['form_disable_autofill'] :"0");
828
+ echo '<fieldset class="buttonset buttonset-hide" >
829
+ <input type="radio" id="form_disable_autofill-1" name="qsm-quiz-settings[form_disable_autofill]" value="1" '. checked( $qsm_form_disable_autofill, '1', false ) .'>
830
+ <label for="form_disable_autofill-1">Yes</label><br>
831
+ <input type="radio" id="form_disable_autofill-0" name="qsm-quiz-settings[form_disable_autofill]" value="0" '. checked( $qsm_form_disable_autofill, '0', false ) .'>
832
+ <label for="form_disable_autofill-0">No</label><br>
833
+ </fieldset>';
834
+ }
835
+
836
+ /**
837
+ * Generates Quiz Global Field For Display category name on front end
838
+ *
839
+ * @since 4.1.0
840
+ * @return void
841
+ */
842
+ public function qsm_global_display_category_name_on_front_end() {
843
+ global $globalQuizsetting;
844
+ $qsm_show_category_on_front =(isset($globalQuizsetting['show_category_on_front']) && '' !== $globalQuizsetting['show_category_on_front'] ? $globalQuizsetting['show_category_on_front'] :"0");
845
+ echo '<fieldset class="buttonset buttonset-hide" >
846
+ <input type="radio" id="show_category_on_front-1" name="qsm-quiz-settings[show_category_on_front]" value="1" '. checked( $qsm_show_category_on_front, '1', false ) .' >
847
+ <label for="show_category_on_front-1">Yes</label><br>
848
+ <input type="radio" id="show_category_on_front-0" name="qsm-quiz-settings[show_category_on_front]" value="0" '. checked( $qsm_show_category_on_front, '0', false ) .'>
849
+ <label for="show_category_on_front-0">No</label><br>
850
+ </fieldset>';
851
+ }
852
+
853
+ /**
854
+ * Generates Quiz Global Field For Show results inline
855
+ *
856
+ * @since 4.1.0
857
+ * @return void
858
+ */
859
+ public function qsm_global_show_results_inline() {
860
+ global $globalQuizsetting;
861
+ $qsm_enable_quick_result_mc =(isset($globalQuizsetting['enable_quick_result_mc']) && '' !== $globalQuizsetting['enable_quick_result_mc'] ? $globalQuizsetting['enable_quick_result_mc'] :"0");
862
+ echo '<fieldset class="buttonset buttonset-hide" >
863
+ <input type="radio" id="enable_quick_result_mc-1" name="qsm-quiz-settings[enable_quick_result_mc]" value="1" '. checked( $qsm_enable_quick_result_mc, '1', false ) .'>
864
+ <label for="enable_quick_result_mc-1">Yes</label><br>
865
+ <input type="radio" id="enable_quick_result_mc-0" name="qsm-quiz-settings[enable_quick_result_mc]" value="0" '. checked( $qsm_enable_quick_result_mc, '0', false ) .'>
866
+ <label for="enable_quick_result_mc-0">No</label><br>
867
+ </fieldset>
868
+ <span class="qsm-opt-desc">Instantly displays the result for each question</span>';
869
+ }
870
+
871
+ /**
872
+ * Generates Quiz Global Field For End quiz if there is wrong answer
873
+ *
874
+ * @since 4.1.0
875
+ * @return void
876
+ */
877
+ public function qsm_global_end_quiz_if_there_is_wrong_answer() {
878
+ global $globalQuizsetting;
879
+ $qsm_end_quiz_if_wrong =(isset($globalQuizsetting['end_quiz_if_wrong']) && '' !== $globalQuizsetting['end_quiz_if_wrong'] ? $globalQuizsetting['end_quiz_if_wrong'] :"0");
880
+ echo '<fieldset class="buttonset buttonset-hide" >
881
+ <input type="radio" id="end_quiz_if_wrong-1" name="qsm-quiz-settings[end_quiz_if_wrong]" value="1" '. checked( $qsm_end_quiz_if_wrong, '1', false ) .' >
882
+ <label for="end_quiz_if_wrong-1">Yes</label><br>
883
+ <input type="radio" id="end_quiz_if_wrong-0" name="qsm-quiz-settings[end_quiz_if_wrong]" value="0" '. checked( $qsm_end_quiz_if_wrong, '0', false ) .'>
884
+ <label for="end_quiz_if_wrong-0">No</label><br>
885
+ </fieldset>
886
+ <span class="qsm-opt-desc">This option works with vertical Multiple Choice , horizontal Multiple Choice , drop down , multiple response and horizontal multiple response question types</span>';
887
+ }
888
+
889
+ /**
890
+ * Generates Quiz Global Field For Show correct answer inline
891
+ *
892
+ * @since 4.1.0
893
+ * @return void
894
+ */
895
+ public function qsm_global_show_correct_answer_inline() {
896
+ global $globalQuizsetting;
897
+ $qsm_enable_quick_correct_answer_info =(isset($globalQuizsetting['enable_quick_correct_answer_info']) && '' !== $globalQuizsetting['enable_quick_correct_answer_info'] ? $globalQuizsetting['enable_quick_correct_answer_info'] :"0");
898
+ echo '<fieldset class="buttonset buttonset-hide" >
899
+ <input type="radio" id="enable_quick_correct_answer_info-1" name="qsm-quiz-settings[enable_quick_correct_answer_info]" value="1" '. checked( $qsm_enable_quick_correct_answer_info, '1', false ) .'>
900
+ <label for="enable_quick_correct_answer_info-1">Yes When answer is correct</label><br>
901
+ <input type="radio" id="enable_quick_correct_answer_info-2" name="qsm-quiz-settings[enable_quick_correct_answer_info]" value="2" '. checked( $qsm_enable_quick_correct_answer_info, '2', false ) .'>
902
+ <label for="enable_quick_correct_answer_info-2">Yes Independent of correct/incorrect</label><br>
903
+ <input type="radio" id="enable_quick_correct_answer_info-0" name="qsm-quiz-settings[enable_quick_correct_answer_info]" value="0" '. checked( $qsm_enable_quick_correct_answer_info, '0', false ) .'>
904
+ <label for="enable_quick_correct_answer_info-0">No</label><br>
905
+ </fieldset>
906
+ <span class="qsm-opt-desc">Show correct user info when inline result is enabled.</span>';
907
+ }
908
+
909
+ /**
910
+ * Generates Quiz Global Field For Retake Quiz
911
+ *
912
+ * @since 4.1.0
913
+ * @return void
914
+ */
915
+ public function qsm_global_retake_quiz() {
916
+ global $globalQuizsetting;
917
+ $qsm_enable_retake_quiz_button =(isset($globalQuizsetting['enable_retake_quiz_button']) && '' !== $globalQuizsetting['enable_retake_quiz_button'] ? $globalQuizsetting['enable_retake_quiz_button'] :"0");
918
+ echo '<fieldset class="buttonset buttonset-hide" >
919
+ <input type="radio" id="enable_retake_quiz_button-1" name="qsm-quiz-settings[enable_retake_quiz_button]" value="1" '. checked( $qsm_enable_retake_quiz_button, '1', false ) .'>
920
+ <label for="enable_retake_quiz_button-1">Yes</label><br>
921
+ <input type="radio" id="enable_retake_quiz_button-0" name="qsm-quiz-settings[enable_retake_quiz_button]" value="0" '. checked( $qsm_enable_retake_quiz_button, '0', false ) .'>
922
+ <label for="enable_retake_quiz_button-0">No</label><br>
923
+ </fieldset>
924
+ <span class="qsm-opt-desc">Show a button on result page to retake the quiz</span>';
925
+ }
926
+
927
+
928
+ /**
929
+ * Generates Quiz Global Field For Show current page number
930
+ *
931
+ * @since 4.1.0
932
+ * @return void
933
+ */
934
+ public function qsm_global_show_current_page_number() {
935
+ global $globalQuizsetting;
936
+ $qsm_enable_pagination_quiz =(isset($globalQuizsetting['enable_pagination_quiz']) && '' !== $globalQuizsetting['enable_pagination_quiz'] ? $globalQuizsetting['enable_pagination_quiz'] :"0");
937
+ echo '<fieldset class="buttonset buttonset-hide" >
938
+ <input type="radio" id="enable_pagination_quiz-1" name="qsm-quiz-settings[enable_pagination_quiz]" value="1" '. checked( $qsm_enable_pagination_quiz, '1', false ) .'>
939
+ <label for="enable_pagination_quiz-1">Yes</label><br>
940
+ <input type="radio" id="enable_pagination_quiz-0" name="qsm-quiz-settings[enable_pagination_quiz]" value="0" '. checked( $qsm_enable_pagination_quiz, '0', false ) .'>
941
+ <label for="enable_pagination_quiz-0">No</label><br>
942
+ </fieldset>';
943
+ }
944
+
945
+ /**
946
+ * Generates Quiz Global Field For Deselect Answer
947
+ *
948
+ * @since 4.1.0
949
+ * @return void
950
+ */
951
+ public function qsm_global_deselect_answer() {
952
+ global $globalQuizsetting;
953
+ $qsm_enable_deselect_option =(isset($globalQuizsetting['enable_deselect_option']) && '' !== $globalQuizsetting['enable_deselect_option'] ? $globalQuizsetting['enable_deselect_option'] :"0");
954
+ echo '<fieldset class="buttonset buttonset-hide" >
955
+ <input type="radio" id="enable_deselect_option-1" name="qsm-quiz-settings[enable_deselect_option]" value="1" '. checked( $qsm_enable_deselect_option, '1', false ) .'>
956
+ <label for="enable_deselect_option-1">Yes</label><br>
957
+ <input type="radio" id="enable_deselect_option-0" name="qsm-quiz-settings[enable_deselect_option]" value="0" '. checked( $qsm_enable_deselect_option, '0', false ) .'>
958
+ <label for="enable_deselect_option-0">No</label><br>
959
+ </fieldset>
960
+ <span class="qsm-opt-desc">Users are able deselect an answer and leave it blank. Works with Multiple Choice and Horizintal Multiple Choice questions only</span>';
961
+ }
962
+ /**
963
+ * Generates Quiz Global Field For Disable description on quiz result page?
964
+ *
965
+ * @since 4.1.0
966
+ * @return void
967
+ */
968
+ public function qsm_global_disable_description_on_quiz_result_page() {
969
+ global $globalQuizsetting;
970
+ $qsm_disable_description_on_result =(isset($globalQuizsetting['disable_description_on_result']) && '' !== $globalQuizsetting['disable_description_on_result'] ? $globalQuizsetting['disable_description_on_result'] :"0");
971
+ echo '<fieldset class="buttonset buttonset-hide" >
972
+ <input type="radio" id="disable_description_on_result-1" name="qsm-quiz-settings[disable_description_on_result]" value="1" '. checked( $qsm_disable_description_on_result, '1', false ) .' >
973
+ <label for="disable_description_on_result-1">Yes</label><br>
974
+ <input type="radio" id="disable_description_on_result-0" name="qsm-quiz-settings[disable_description_on_result]" value="0" '. checked( $qsm_disable_description_on_result, '0', false ) .'>
975
+ <label for="disable_description_on_result-0">No</label><br>
976
+ </fieldset>';
977
+ }
978
+ /**
979
+ * Generates Quiz Global Field For Disable scroll on next and previous button click?
980
+ *
981
+ * @since 4.1.0
982
+ * @return void
983
+ */
984
+ public function qsm_global_disable_scroll_on_next_and_previous_button_click() {
985
+ global $globalQuizsetting;
986
+ $qsm_disable_scroll_next_previous_click =(isset($globalQuizsetting['disable_scroll_next_previous_click']) && '' !== $globalQuizsetting['disable_scroll_next_previous_click'] ? $globalQuizsetting['disable_scroll_next_previous_click'] :"0");
987
+ echo '<fieldset class="buttonset buttonset-hide" >
988
+ <input type="radio" id="disable_scroll_next_previous_click-1" name="qsm-quiz-settings[disable_scroll_next_previous_click]" value="1" '. checked( $qsm_disable_scroll_next_previous_click, '1', false ) .'>
989
+ <label for="disable_scroll_next_previous_click-1">Yes</label><br>
990
+ <input type="radio" id="disable_scroll_next_previous_click-0" name="qsm-quiz-settings[disable_scroll_next_previous_click]" value="0" '. checked( $qsm_disable_scroll_next_previous_click, '0', false ) .'>
991
+ <label for="disable_scroll_next_previous_click-0">No</label><br>
992
+ </fieldset>';
993
+ }
994
+
995
+ /**
996
+ * Generates Quiz Global Field For Quiz Animation
997
+ *
998
+ * @since 4.1.0
999
+ * @return void
1000
+ */
1001
+ public function qsm_global_quiz_animation() {
1002
+ global $globalQuizsetting;
1003
+ global $mlwQuizMasterNext;
1004
+ $qsm_quiz_animation =(isset($globalQuizsetting['quiz_animation']) && '' !== $globalQuizsetting['quiz_animation'] ? $globalQuizsetting['quiz_animation'] :"");
1005
+ $options = $mlwQuizMasterNext->pluginHelper->quiz_animation_effect();
1006
+
1007
+ $string= '<select name="qsm-quiz-settings[quiz_animation]">';
1008
+ foreach($options as $value){
1009
+ $string.='<option value="'.$value['value'].'" '.(isset($qsm_quiz_animation) && $qsm_quiz_animation ==$value['value'] ? "Selected": "").' >'.$value['label'].'</option>';
1010
+ }
1011
+ $string.='</select>';
1012
+ echo $string;
1013
+ }
1014
+
1015
+ /**
1016
+ * Generates Quiz Global Field For Logo URL
1017
+ *
1018
+ * @since 4.1.0
1019
+ * @return void
1020
+ */
1021
+ public function qsm_global_logo_url() {
1022
+ global $globalQuizsetting;
1023
+ $qsm_result_page_fb_image =(isset($globalQuizsetting['result_page_fb_image']) && '' !== $globalQuizsetting['result_page_fb_image'] ? $globalQuizsetting['result_page_fb_image'] : QSM_PLUGIN_URL . 'assets/icon-200x200.png');
1024
+ echo '<input type="text" id="result_page_fb_image" name="qsm-quiz-settings[result_page_fb_image]" value="'.$qsm_result_page_fb_image.'">
1025
+ <span class="qsm-opt-desc">If left blank, this will default to QSM logo</span>';
1026
+ }
1027
+
1028
+ /**
1029
+ * Generates Quiz Global Field For Random Questions
1030
+ *
1031
+ * @since 4.1.0
1032
+ * @return void
1033
+ */
1034
+ public function qsm_global_random_questions() {
1035
+ global $globalQuizsetting;
1036
+ $qsm_randomness_order =(isset($globalQuizsetting['randomness_order']) && '' !== $globalQuizsetting['randomness_order'] ? $globalQuizsetting['randomness_order'] :"");
1037
+ $options = array(
1038
+ array(
1039
+ 'label' => __( 'Random Questions', 'quiz-master-next' ),
1040
+ 'value' => 1,
1041
+ ),
1042
+ array(
1043
+ 'label' => __( 'Random Questions And Answers', 'quiz-master-next' ),
1044
+ 'value' => 2,
1045
+ ),
1046
+ array(
1047
+ 'label' => __( 'Random Answers', 'quiz-master-next' ),
1048
+ 'value' => 3,
1049
+ ),
1050
+ array(
1051
+ 'label' => __( 'Disabled', 'quiz-master-next' ),
1052
+ 'value' => 0,
1053
+ ),
1054
+ );
1055
+ $string= '<select name="qsm-quiz-settings[randomness_order]">';
1056
+ foreach($options as $value){
1057
+ $string.='<option value="'.$value['value'].'" '.(isset($qsm_randomness_order) && $qsm_randomness_order ==$value['value'] ? "Selected": "").' >'.$value['label'].'</option>';
1058
+ }
1059
+ $string.='</select>';
1060
+ echo $string;
1061
+ }
1062
+ /**
1063
+ * Generates Quiz Global Field For Quiz Dates
1064
+ *
1065
+ * @since 4.1.0
1066
+ * @return void
1067
+ */
1068
+ public function qsm_global_quiz_dates() {
1069
+ wp_enqueue_script( 'qmn_datetime_js', plugins_url( '../../js/jquery.datetimepicker.full.min.js', __FILE__ ) );
1070
+ wp_enqueue_style( 'qsm_datetime_style', plugins_url( '../../css/jquery.datetimepicker.css', __FILE__ ) );
1071
+ global $globalQuizsetting;
1072
+ $qsm_scheduled_time_start =(isset($globalQuizsetting['scheduled_time_start']) && '' !== $globalQuizsetting['scheduled_time_start'] ? $globalQuizsetting['scheduled_time_start'] :"");
1073
+ $qsm_scheduled_time_end =(isset($globalQuizsetting['scheduled_time_end']) && '' !== $globalQuizsetting['scheduled_time_end'] ? $globalQuizsetting['scheduled_time_end'] :"");
1074
+ echo '<div>
1075
+ <span class="qsm-ph_text">Start Date</span>
1076
+ <input autocomplete="off" type="text" id="scheduled_time_start" name="qsm-quiz-settings[scheduled_time_start]" value="'.$qsm_scheduled_time_start.'">
1077
+ <span class="qsm-opt-desc">If set, Quiz will be accessible only after this date</span>
1078
+ </div>';
1079
+ echo '<div>
1080
+ <span class="qsm-ph_text">End Date</span>
1081
+ <input autocomplete="off" type="text" id="scheduled_time_end" name="qsm-quiz-settings[scheduled_time_end]" value="'.$qsm_scheduled_time_end.'">
1082
+ <span class="qsm-opt-desc"> If set, Quiz will not be accessible after this date</span>
1083
+ </div>';
1084
+ echo '<script>
1085
+ jQuery(function() {
1086
+ jQuery("#scheduled_time_start,#scheduled_time_end").datetimepicker({
1087
+ format: "m/d/Y H:i",
1088
+ step: 1
1089
+ });
1090
+ });
1091
+ </script>';
1092
+ }
1093
+ /**
1094
+ * Generates Quiz Global Field For Do not allow quiz submission after the end date/time
1095
+ *
1096
+ * @since 4.1.0
1097
+ * @return void
1098
+ */
1099
+ public function qsm_global_Do_not_allow_quiz_submission_after_the_end_datetime() {
1100
+ global $globalQuizsetting;
1101
+ $qsm_not_allow_after_expired_time =(isset($globalQuizsetting['not_allow_after_expired_time']) && '' !== $globalQuizsetting['not_allow_after_expired_time'] ? $globalQuizsetting['not_allow_after_expired_time'] :"");
1102
+ echo '<fieldset class="buttonset buttonset-hide" >
1103
+ <input type="checkbox" id="not_allow_after_expired_time-1" name="qsm-quiz-settings[not_allow_after_expired_time]" value="1" '. checked( $qsm_not_allow_after_expired_time, '1', false ) .'>
1104
+ <br>
1105
+ </fieldset>';
1106
+ }
1107
+
1108
+
1109
  }
1110
 
1111
  $qmnGlobalSettingsPage = new QMNGlobalSettingsPage();
php/classes/class-qmn-plugin-helper.php CHANGED
@@ -406,6 +406,7 @@ class QMNPluginHelper
406
  }
407
  if (2 == $quiz_options->randomness_order || 3 == $quiz_options->randomness_order) {
408
  shuffle($answers);
 
409
  }
410
  foreach ($this->question_types as $type) {
411
  if ($type["slug"] == strtolower(str_replace(" ", "-", $slug))) {
@@ -659,4 +660,62 @@ class QMNPluginHelper
659
  {
660
  return apply_filters('qmn_quiz_setting_tabs' , $this->settings_tabs);
661
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
662
  }
406
  }
407
  if (2 == $quiz_options->randomness_order || 3 == $quiz_options->randomness_order) {
408
  shuffle($answers);
409
+ update_post_meta($question_id,'qsm_random_quetion_answer',$answers);
410
  }
411
  foreach ($this->question_types as $type) {
412
  if ($type["slug"] == strtolower(str_replace(" ", "-", $slug))) {
660
  {
661
  return apply_filters('qmn_quiz_setting_tabs' , $this->settings_tabs);
662
  }
663
+
664
+ /**
665
+ * global animatiocv array return
666
+ *
667
+ * @since 4.7.1
668
+ */
669
+ public function quiz_animation_effect( ) {
670
+
671
+
672
+ return array(
673
+ array(
674
+ 'label' => __( 'bounce', 'quiz-master-next' ),
675
+ 'value' => 'bounce',
676
+ ),
677
+ array(
678
+ 'label' => __( 'flash', 'quiz-master-next' ),
679
+ 'value' => 'flash',
680
+ ),
681
+ array(
682
+ 'label' => __( 'pulse', 'quiz-master-next' ),
683
+ 'value' => 'pulse',
684
+ ),
685
+ array(
686
+ 'label' => __( 'rubberBand', 'quiz-master-next' ),
687
+ 'value' => 'rubberBand',
688
+ ),
689
+ array(
690
+ 'label' => __( 'shake', 'quiz-master-next' ),
691
+ 'value' => 'shake',
692
+ ),
693
+ array(
694
+ 'label' => __( 'swing', 'quiz-master-next' ),
695
+ 'value' => 'swing',
696
+ ),
697
+ array(
698
+ 'label' => __( 'tada', 'quiz-master-next' ),
699
+ 'value' => 'tada',
700
+ ),
701
+ array(
702
+ 'label' => __( 'wobble', 'quiz-master-next' ),
703
+ 'value' => 'wobble',
704
+ ),
705
+ array(
706
+ 'label' => __( 'jello', 'quiz-master-next' ),
707
+ 'value' => 'jello',
708
+ ),
709
+ array(
710
+ 'label' => __( 'heartBeat', 'quiz-master-next' ),
711
+ 'value' => 'heartBeat',
712
+ ),
713
+ array(
714
+ 'label' => __( 'No animation', 'quiz-master-next' ),
715
+ 'value' => '',
716
+ ),
717
+ );
718
+
719
+ }
720
+
721
  }
php/classes/class-qmn-quiz-manager.php CHANGED
@@ -357,6 +357,8 @@ class QMNQuizManager {
357
  'enable_quick_correct_answer_info' => isset( $qmn_quiz_options->enable_quick_correct_answer_info ) ? $qmn_quiz_options->enable_quick_correct_answer_info : 0,
358
  'quick_result_correct_answer_text' => $qmn_quiz_options->quick_result_correct_answer_text,
359
  'quick_result_wrong_answer_text' => $qmn_quiz_options->quick_result_wrong_answer_text,
 
 
360
  );
361
 
362
  $return_display = apply_filters( 'qmn_begin_shortcode', $return_display, $qmn_quiz_options, $qmn_array_for_variables );
@@ -617,6 +619,8 @@ $range = range(0, $quiz_options->question_from_total);
617
  $questions = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}mlw_questions WHERE quiz_id=%d AND deleted=0 %1s %2s %3s", $quiz_id, $question_sql, $order_by_sql, $limit_sql ) );
618
  }
619
  $questions = apply_filters( 'qsm_load_questions_filter', $questions, $quiz_id, $quiz_options );
 
 
620
  // Returns an array of all the loaded questions.
621
  return $questions;
622
 
@@ -661,7 +665,8 @@ $range = range(0, $quiz_options->question_from_total);
661
  if ( ! $is_ajax ) {
662
  global $qmn_json_data;
663
  $qmn_json_data['question_list'] = $question_list;
664
- }
 
665
  return $mlw_qmn_answer_arrays;
666
  }
667
 
@@ -871,8 +876,14 @@ $range = range(0, $quiz_options->question_from_total);
871
  foreach ( $pages[0] as $question_id ) {
872
  $question_list .= $question_id . 'Q';
873
  $question = $questions[ $question_id ];
 
 
 
 
 
 
874
  ?>
875
- <div class='quiz_section qsm-question-wrapper question-section-id-<?php echo esc_attr( $question_id ); ?>'
876
  data-qid="<?php echo esc_attr($question_id); ?>">
877
  <?php
878
  echo $mlwQuizMasterNext->pluginHelper->display_question( $question['question_type_new'], $question_id, $options );
@@ -936,8 +947,14 @@ $range = range(0, $quiz_options->question_from_total);
936
  foreach ( $page as $question_id ) {
937
  $question_list .= $question_id . 'Q';
938
  $question = $questions[ $question_id ];
 
 
 
 
 
 
939
  ?>
940
- <div class='quiz_section qsm-question-wrapper question-section-id-<?php echo esc_attr( $question_id ); ?>'
941
  data-qid='<?php echo esc_attr($question_id); ?>'>
942
  <?php
943
  echo $mlwQuizMasterNext->pluginHelper->display_question( $question['question_type_new'], $question_id, $options );
@@ -1253,7 +1270,16 @@ $range = range(0, $quiz_options->question_from_total);
1253
  $qmn_allowed_visit = true;
1254
  $quiz = intval( $_POST['qmn_quiz_id'] );
1255
  $mlwQuizMasterNext->pluginHelper->prepare_quiz( $quiz );
1256
- $options = $mlwQuizMasterNext->quiz_settings->get_quiz_options();
 
 
 
 
 
 
 
 
 
1257
  $data = array(
1258
  'quiz_id' => $options->quiz_id,
1259
  'quiz_name' => $options->quiz_name,
@@ -1370,8 +1396,7 @@ $range = range(0, $quiz_options->question_from_total);
1370
  $qmn_array_for_variables = array_merge( $qmn_array_for_variables, $this->check_answers( $qmn_quiz_options, $qmn_array_for_variables ) );
1371
  $result_display = apply_filters( 'qmn_after_check_answers', $result_display, $qmn_quiz_options, $qmn_array_for_variables );
1372
  $qmn_array_for_variables['comments'] = $this->check_comment_section( $qmn_quiz_options, $qmn_array_for_variables );
1373
- $result_display = apply_filters( 'qmn_after_check_comments', $result_display, $qmn_quiz_options, $qmn_array_for_variables );
1374
-
1375
  $unique_id = md5( date( 'Y-m-d H:i:s' ) );
1376
  $results_id = 0;
1377
  // If the store responses in database option is set to Yes.
@@ -1536,7 +1561,8 @@ $range = range(0, $quiz_options->question_from_total);
1536
 
1537
  // Prepares data to be sent back to front-end.
1538
  $return_array = array(
1539
- 'display' => htmlspecialchars_decode( $result_display ),
 
1540
  'redirect' => apply_filters( 'mlw_qmn_template_variable_results_page', $results_pages['redirect'], $qmn_array_for_variables ),
1541
  );
1542
 
@@ -1814,7 +1840,21 @@ $range = range(0, $quiz_options->question_from_total);
1814
  } else {
1815
  $total_score = 0;
1816
  }
 
 
 
 
 
 
 
 
 
 
 
 
1817
 
 
 
1818
  // Return array to be merged with main user response array
1819
  return apply_filters('qsm_check_answers_results' , array(
1820
  'total_points' => $points_earned,
357
  'enable_quick_correct_answer_info' => isset( $qmn_quiz_options->enable_quick_correct_answer_info ) ? $qmn_quiz_options->enable_quick_correct_answer_info : 0,
358
  'quick_result_correct_answer_text' => $qmn_quiz_options->quick_result_correct_answer_text,
359
  'quick_result_wrong_answer_text' => $qmn_quiz_options->quick_result_wrong_answer_text,
360
+ 'not_allow_after_expired_time' => $qmn_quiz_options->not_allow_after_expired_time,
361
+ 'scheduled_time_end' => strtotime($qmn_quiz_options->scheduled_time_end),
362
  );
363
 
364
  $return_display = apply_filters( 'qmn_begin_shortcode', $return_display, $qmn_quiz_options, $qmn_array_for_variables );
619
  $questions = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}mlw_questions WHERE quiz_id=%d AND deleted=0 %1s %2s %3s", $quiz_id, $question_sql, $order_by_sql, $limit_sql ) );
620
  }
621
  $questions = apply_filters( 'qsm_load_questions_filter', $questions, $quiz_id, $quiz_options );
622
+ $qsm_random_que_ids = array_column($questions,'question_id');
623
+ update_option('qsm_random_que_ids',$qsm_random_que_ids);
624
  // Returns an array of all the loaded questions.
625
  return $questions;
626
 
665
  if ( ! $is_ajax ) {
666
  global $qmn_json_data;
667
  $qmn_json_data['question_list'] = $question_list;
668
+ }
669
+
670
  return $mlw_qmn_answer_arrays;
671
  }
672
 
876
  foreach ( $pages[0] as $question_id ) {
877
  $question_list .= $question_id . 'Q';
878
  $question = $questions[ $question_id ];
879
+ $categor_class = '';
880
+ if ( ! empty( $question['multicategories'] ) ) {
881
+ foreach ( $question['multicategories'] as $cat ) {
882
+ $categor_class .= ' category-section-id-c' . esc_attr( $cat );
883
+ }
884
+ }
885
  ?>
886
+ <div class='quiz_section qsm-question-wrapper question-section-id-<?php echo esc_attr( $question_id ); ?> <?php echo esc_attr($categor_class);?>'
887
  data-qid="<?php echo esc_attr($question_id); ?>">
888
  <?php
889
  echo $mlwQuizMasterNext->pluginHelper->display_question( $question['question_type_new'], $question_id, $options );
947
  foreach ( $page as $question_id ) {
948
  $question_list .= $question_id . 'Q';
949
  $question = $questions[ $question_id ];
950
+ $categor_class = '';
951
+ if ( ! empty( $question['multicategories'] ) ) {
952
+ foreach ( $question['multicategories'] as $cat ) {
953
+ $categor_class .= ' category-section-id-c' . esc_attr( $cat );
954
+ }
955
+ }
956
  ?>
957
+ <div class='quiz_section qsm-question-wrapper question-section-id-<?php echo esc_attr( $question_id ); ?> <?php echo esc_attr($categor_class);?>'
958
  data-qid='<?php echo esc_attr($question_id); ?>'>
959
  <?php
960
  echo $mlwQuizMasterNext->pluginHelper->display_question( $question['question_type_new'], $question_id, $options );
1270
  $qmn_allowed_visit = true;
1271
  $quiz = intval( $_POST['qmn_quiz_id'] );
1272
  $mlwQuizMasterNext->pluginHelper->prepare_quiz( $quiz );
1273
+ $options = $mlwQuizMasterNext->quiz_settings->get_quiz_options();
1274
+ $qsm_option = isset( $options->quiz_settings ) ? @unserialize( $options->quiz_settings ) : array();
1275
+ $qsm_option = array_map("unserialize", $qsm_option);
1276
+ $dateStr = $qsm_option['quiz_options']['scheduled_time_end'];
1277
+ $timezone = $_POST['currentuserTimeZone'];
1278
+ $dtUtcDate = strtotime($dateStr. ' '. $timezone);
1279
+ if('1'=== $qsm_option['quiz_options']['not_allow_after_expired_time'] && $_POST['currentuserTime'] > $dtUtcDate){
1280
+ echo json_encode( array('quizExpired'=>true) );
1281
+ die();
1282
+ }
1283
  $data = array(
1284
  'quiz_id' => $options->quiz_id,
1285
  'quiz_name' => $options->quiz_name,
1396
  $qmn_array_for_variables = array_merge( $qmn_array_for_variables, $this->check_answers( $qmn_quiz_options, $qmn_array_for_variables ) );
1397
  $result_display = apply_filters( 'qmn_after_check_answers', $result_display, $qmn_quiz_options, $qmn_array_for_variables );
1398
  $qmn_array_for_variables['comments'] = $this->check_comment_section( $qmn_quiz_options, $qmn_array_for_variables );
1399
+ $result_display = apply_filters( 'qmn_after_check_comments', $result_display, $qmn_quiz_options, $qmn_array_for_variables );
 
1400
  $unique_id = md5( date( 'Y-m-d H:i:s' ) );
1401
  $results_id = 0;
1402
  // If the store responses in database option is set to Yes.
1561
 
1562
  // Prepares data to be sent back to front-end.
1563
  $return_array = array(
1564
+ 'quizExpired'=>false,
1565
+ 'display' => htmlspecialchars_decode( $result_display ),
1566
  'redirect' => apply_filters( 'mlw_qmn_template_variable_results_page', $results_pages['redirect'], $qmn_array_for_variables ),
1567
  );
1568
 
1840
  } else {
1841
  $total_score = 0;
1842
  }
1843
+ $qsm_random_que_ids = get_option('qsm_random_que_ids');
1844
+ if(!empty($qsm_random_que_ids))
1845
+ {
1846
+
1847
+ $new_question_data = array();
1848
+ foreach($qsm_random_que_ids as $que_id)
1849
+ {
1850
+ $key = array_search($que_id,array_column($question_data,'id'));
1851
+ array_push($new_question_data,$question_data[$key]);
1852
+ }
1853
+ $question_data = $new_question_data;
1854
+ }
1855
 
1856
+ // We no need longer this option
1857
+ delete_option('qsm_random_que_ids');
1858
  // Return array to be merged with main user response array
1859
  return apply_filters('qsm_check_answers_results' , array(
1860
  'total_points' => $points_earned,
php/classes/class-qsm-fields.php CHANGED
@@ -106,7 +106,11 @@ class QSM_Fields {
106
  }
107
  ?>
108
  </table>
 
 
 
109
  <button class="button-primary"><?php _e('Save Changes', 'quiz-master-next'); ?></button>
 
110
  </form>
111
  <?php
112
  }
@@ -525,7 +529,7 @@ jQuery(function() {
525
  public static function generate_checkbox_field( $field, $value ) {
526
  $show_option = isset( $field['show_option'] ) ? $field['show_option'] : '';
527
  global $mlwQuizMasterNext;
528
- $score_roundoff = $mlwQuizMasterNext->pluginHelper->get_section_setting('quiz_options', 'score_roundoff');
529
  ?>
530
  <tr valign="top"
531
  <?php if( $show_option ){ echo "class='". $show_option ." hidden qsm_hidden_tr qsm_hidden_tr_gradingsystem'"; } ?>>
106
  }
107
  ?>
108
  </table>
109
+ <?php if(isset($_GET['tab']) && 'options'==$_GET['tab'] && $_GET['page']=='mlw_quiz_options'){?>
110
+ <button class="button" name="global_setting" type="submit"><?php _e('Set Global Defaults', 'quiz-master-next'); ?></button>
111
+ <?php } ?>
112
  <button class="button-primary"><?php _e('Save Changes', 'quiz-master-next'); ?></button>
113
+
114
  </form>
115
  <?php
116
  }
529
  public static function generate_checkbox_field( $field, $value ) {
530
  $show_option = isset( $field['show_option'] ) ? $field['show_option'] : '';
531
  global $mlwQuizMasterNext;
532
+ $score_roundoff = $mlwQuizMasterNext->pluginHelper->get_section_setting('quiz_options',$field["id"] );
533
  ?>
534
  <tr valign="top"
535
  <?php if( $show_option ){ echo "class='". $show_option ." hidden qsm_hidden_tr qsm_hidden_tr_gradingsystem'"; } ?>>
php/classes/class-qsm-install.php CHANGED
@@ -27,7 +27,6 @@ class QSM_Install {
27
  * @since 4.7.1
28
  */
29
  public function add_hooks() {
30
- add_action( 'admin_init', array( $this, 'update' ) );
31
  add_action( 'admin_init', array( $this, 'update' ) );
32
  add_filter( 'plugin_action_links_' . QSM_PLUGIN_BASENAME, array( $this, 'plugin_action_links' ) );
33
  add_filter( 'plugin_row_meta', array( $this, 'plugin_row_meta' ), 10, 2 );
@@ -279,6 +278,19 @@ class QSM_Install {
279
  'ph_text' => __( 'End Date', 'quiz-master-next' ),
280
  );
281
  $mlwQuizMasterNext->pluginHelper->register_quiz_setting( $field_array, 'quiz_options' );
 
 
 
 
 
 
 
 
 
 
 
 
 
282
 
283
  // Registers randomness_order setting
284
  $field_array = array(
@@ -682,52 +694,7 @@ class QSM_Install {
682
  'id' => 'quiz_animation',
683
  'label' => __( 'Quiz Animation', 'quiz-master-next' ),
684
  'type' => 'select',
685
- 'options' => array(
686
- array(
687
- 'label' => __( 'bounce', 'quiz-master-next' ),
688
- 'value' => 'bounce',
689
- ),
690
- array(
691
- 'label' => __( 'flash', 'quiz-master-next' ),
692
- 'value' => 'flash',
693
- ),
694
- array(
695
- 'label' => __( 'pulse', 'quiz-master-next' ),
696
- 'value' => 'pulse',
697
- ),
698
- array(
699
- 'label' => __( 'rubberBand', 'quiz-master-next' ),
700
- 'value' => 'rubberBand',
701
- ),
702
- array(
703
- 'label' => __( 'shake', 'quiz-master-next' ),
704
- 'value' => 'shake',
705
- ),
706
- array(
707
- 'label' => __( 'swing', 'quiz-master-next' ),
708
- 'value' => 'swing',
709
- ),
710
- array(
711
- 'label' => __( 'tada', 'quiz-master-next' ),
712
- 'value' => 'tada',
713
- ),
714
- array(
715
- 'label' => __( 'wobble', 'quiz-master-next' ),
716
- 'value' => 'wobble',
717
- ),
718
- array(
719
- 'label' => __( 'jello', 'quiz-master-next' ),
720
- 'value' => 'jello',
721
- ),
722
- array(
723
- 'label' => __( 'heartBeat', 'quiz-master-next' ),
724
- 'value' => 'heartBeat',
725
- ),
726
- array(
727
- 'label' => __( 'No animation', 'quiz-master-next' ),
728
- 'value' => '',
729
- ),
730
- ),
731
  'default' => '',
732
  );
733
  $mlwQuizMasterNext->pluginHelper->register_quiz_setting( $field_array, 'quiz_options' );
@@ -1890,7 +1857,6 @@ class QSM_Install {
1890
 
1891
  }
1892
 
1893
-
1894
  }
1895
 
1896
  $qsm_install = new QSM_Install();
27
  * @since 4.7.1
28
  */
29
  public function add_hooks() {
 
30
  add_action( 'admin_init', array( $this, 'update' ) );
31
  add_filter( 'plugin_action_links_' . QSM_PLUGIN_BASENAME, array( $this, 'plugin_action_links' ) );
32
  add_filter( 'plugin_row_meta', array( $this, 'plugin_row_meta' ), 10, 2 );
278
  'ph_text' => __( 'End Date', 'quiz-master-next' ),
279
  );
280
  $mlwQuizMasterNext->pluginHelper->register_quiz_setting( $field_array, 'quiz_options' );
281
+ $field_array = array(
282
+ 'id' => 'not_allow_after_expired_time',
283
+ 'label' => __( 'Do not allow quiz submission after the end date/time', 'quiz-master-next' ),
284
+ 'type' => 'checkbox',
285
+ 'options' => array(
286
+ array(
287
+ 'value' => 1,
288
+ ),
289
+ ),
290
+ 'default' => 0,
291
+ 'ph_text' => __( '', 'quiz-master-next' ),
292
+ );
293
+ $mlwQuizMasterNext->pluginHelper->register_quiz_setting( $field_array, 'quiz_options' );
294
 
295
  // Registers randomness_order setting
296
  $field_array = array(
694
  'id' => 'quiz_animation',
695
  'label' => __( 'Quiz Animation', 'quiz-master-next' ),
696
  'type' => 'select',
697
+ 'options' => $mlwQuizMasterNext->pluginHelper->quiz_animation_effect(),
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
698
  'default' => '',
699
  );
700
  $mlwQuizMasterNext->pluginHelper->register_quiz_setting( $field_array, 'quiz_options' );
1857
 
1858
  }
1859
 
 
1860
  }
1861
 
1862
  $qsm_install = new QSM_Install();
php/classes/class-qsm-migrate.php CHANGED
@@ -32,33 +32,41 @@ class QSM_Migrate {
32
  $values_array = array();
33
  $result = false;
34
  $category_data = $wpdb->get_results( "SELECT question_id, quiz_id, category FROM {$wpdb->prefix}mlw_questions WHERE category <> '' ORDER BY category" );
35
- foreach ( $category_data as $data ) {
36
- if ( $new_category != $data->category ) {
37
- $term_data = get_term_by( 'name', $data->category, 'qsm_category' );
38
- if ( $term_data ) {
39
- $term_id = $term_data->term_id;
40
- } else {
41
- $term_array = wp_insert_term( $data->category, 'qsm_category' );
42
- $term_id = $term_array['term_id'];
 
 
43
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
44
  }
45
- $values_array[] = "($data->question_id, $data->quiz_id, $term_id, 'qsm_category')";
46
- }
47
- $values = join( ',', $values_array );
48
- $insert_query = stripslashes( $wpdb->prepare( "INSERT INTO {$wpdb->prefix}mlw_question_terms (question_id, quiz_id, term_id, taxonomy) VALUES %1s", $values ) );
49
- $result = $wpdb->query( $insert_query );
50
- if ( $result > 0 ) {
51
- update_option( 'qsm_multiple_category_enabled', date( time() ) );
52
- $response = array(
53
- 'status' => true,
54
- 'count' => $result,
55
- );
56
- $update = "UPDATE {$wpdb->prefix}mlw_questions SET category = '' ";
57
- $updated = $wpdb->query( $update );
58
  } else {
59
- $response = array(
60
- 'status' => false,
 
61
  );
 
62
  }
63
  echo json_encode( $response );
64
  break;
32
  $values_array = array();
33
  $result = false;
34
  $category_data = $wpdb->get_results( "SELECT question_id, quiz_id, category FROM {$wpdb->prefix}mlw_questions WHERE category <> '' ORDER BY category" );
35
+ if ( ! empty( $category_data ) ) {
36
+ foreach ( $category_data as $data ) {
37
+ if ( $new_category != $data->category ) {
38
+ $term_data = get_term_by( 'name', $data->category, 'qsm_category' );
39
+ if ( $term_data ) {
40
+ $term_id = $term_data->term_id;
41
+ } else {
42
+ $term_array = wp_insert_term( $data->category, 'qsm_category' );
43
+ $term_id = $term_array['term_id'];
44
+ }
45
  }
46
+ $values_array[] = "($data->question_id, $data->quiz_id, $term_id, 'qsm_category')";
47
+ }
48
+ $values = join( ',', $values_array );
49
+ $insert_query = stripslashes( $wpdb->prepare( "INSERT INTO {$wpdb->prefix}mlw_question_terms (question_id, quiz_id, term_id, taxonomy) VALUES %1s", $values ) );
50
+ $result = $wpdb->query( $insert_query );
51
+ if ( $result > 0 ) {
52
+ update_option( 'qsm_multiple_category_enabled', date( time() ) );
53
+ $response = array(
54
+ 'status' => true,
55
+ 'count' => $result,
56
+ );
57
+ $update = "UPDATE {$wpdb->prefix}mlw_questions SET category = '' ";
58
+ $updated = $wpdb->query( $update );
59
+ } else {
60
+ $response = array(
61
+ 'status' => false,
62
+ );
63
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
64
  } else {
65
+ $response = array(
66
+ 'status' => true,
67
+ 'count' => 0,
68
  );
69
+ update_option( 'qsm_multiple_category_enabled', date( time() ) );
70
  }
71
  echo json_encode( $response );
72
  break;
php/classes/class-qsm-questions.php CHANGED
@@ -358,4 +358,56 @@ class QSM_Questions {
358
 
359
  return $question_id;
360
  }
361
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
358
 
359
  return $question_id;
360
  }
361
+
362
+ /**
363
+ * Get categories for a quiz
364
+ *
365
+ * @since 7.2.1
366
+ * @param int $quiz_id The ID of the quiz.
367
+ * @return array The array of categories.
368
+ */
369
+ public static function get_quiz_categories( $quiz_id = 0 ) {
370
+ global $wpdb;
371
+ $categories = array();
372
+ if ( 0 !== $quiz_id ) {
373
+ $question_terms = $wpdb->get_results( "SELECT `term_id` FROM `{$wpdb->prefix}mlw_question_terms` WHERE `quiz_id`='{$quiz_id}' AND `taxonomy`='qsm_category'", ARRAY_A );
374
+ if ( ! empty( $question_terms ) ) {
375
+ $term_ids = array_unique( array_column( $question_terms, 'term_id' ) );
376
+ if ( ! empty( $term_ids ) ) {
377
+ $categories_names = array();
378
+ $categories_tree = array();
379
+ $terms = get_terms( array( 'taxonomy' => 'qsm_category', 'include' => array_unique( $term_ids ), 'hide_empty' => false, 'orderby' => '', 'order' => '' ) );
380
+ if ( ! empty( $terms ) ) {
381
+ foreach ( $terms as $tax ) {
382
+ $categories_names[$tax->term_id] = $tax->name;
383
+ $taxs[$tax->parent][] = $tax;
384
+ }
385
+ $categories_tree = self::create_terms_tree( $taxs, $taxs[0] );
386
+ }
387
+ $categories = array(
388
+ 'list' => $categories_names,
389
+ 'tree' => $categories_tree,
390
+ );
391
+ }
392
+ }
393
+ }
394
+ return $categories;
395
+ }
396
+
397
+ /**
398
+ * Create tree structure of terms.
399
+ *
400
+ * @since 7.2.1
401
+ */
402
+ public static function create_terms_tree( &$list, $parent ) {
403
+ $taxTree = array();
404
+ foreach ( $parent as $ind => $val ) {
405
+ if ( isset( $list[$val->term_id] ) ) {
406
+ $val->children = self::create_terms_tree( $list, $list[$val->term_id] );
407
+ }
408
+ $taxTree[] = $val;
409
+ }
410
+ return $taxTree;
411
+ }
412
+
413
+ }
php/classes/class-qsm-settings.php CHANGED
@@ -7,7 +7,8 @@ if ( ! defined( 'ABSPATH' ) ) exit;
7
  *
8
  * @since 5.0.0
9
  */
10
- class QSM_Quiz_Settings {
 
11
 
12
  /**
13
  * ID of the quiz
@@ -15,43 +16,45 @@ class QSM_Quiz_Settings {
15
  * @var int
16
  * @since 5.0.0
17
  */
18
- private $quiz_id;
19
-
20
- /**
21
- * The settings for the quiz
22
- *
23
- * @var array
24
- * @since 5.0.0
25
- */
26
- private $settings;
27
-
28
- /**
29
- * The fields that have been registered
30
- *
31
- * @var array
32
- * @since 5.0.0
33
- */
34
- private $registered_fields;
 
 
 
 
 
 
 
 
 
 
 
 
35
 
36
- /**
37
- * Prepares the settings for the supplied quiz
38
- *
39
- * @since 5.0.0
40
- * @param int $quiz_id the ID of the quiz that we are handling the settings data for
41
- */
42
- public function prepare_quiz( $quiz_id ) {
43
- $this->quiz_id = intval( $quiz_id );
44
- $this->load_settings();
45
- }
46
 
47
-
48
- /**
49
- * Registers a setting be shown on the Options or Text tab
50
- *
51
- * @since 5.0.0
52
- * @param array $field_array An array of the components for the settings field
53
- */
54
- public function register_setting( $field_array, $section = 'quiz_options' ) {
55
 
56
  /*
57
  Example field array
@@ -72,169 +75,222 @@ class QSM_Quiz_Settings {
72
  );
73
  */
74
 
75
- // Adds field to registered fields
76
- $this->registered_fields[ $section ][] = $field_array;
77
-
78
- }
79
 
80
- /**
81
- * Retrieves the registered setting fields
82
- *
83
- * @since 5.0.0
84
- * @param string $section The section whose fields that are being retrieved
85
- * @return array All the fields registered the the section provided
86
- */
87
- public function load_setting_fields( $section = 'quiz_options' ) {
 
88
 
89
  // Checks if section exists in registered fields and returns it if it does
90
- if ( isset( $this->registered_fields[ $section ] ) ) {
91
- return $this->registered_fields[ $section ];
92
- } else {
93
- return false;
 
94
  }
95
- }
96
 
97
- /**
98
- * Retrieves a setting value from a section based on name of section and setting
99
- *
100
- * @since 5.0.0
101
- * @param string $section The name of the section the setting is registered in
102
- * @param string $setting The name of the setting whose value we need to retrieve
103
- * @param mixed $default What we need to return if no setting exists with given $setting
104
- * @return $mixed Value set for $setting or $default if setting does not exist
105
- */
106
- public function get_section_setting( $section, $setting, $default = false ) {
 
107
 
108
  // Return if section or setting is empty
109
- if ( empty( $section ) || empty( $setting ) ) {
110
- return $default;
111
- }
112
 
113
- // Get settings in section
114
- $section_settings = $this->get_setting( $section );
115
 
116
- // Return default if section not found
117
- if ( ! $section_settings ) {
118
- return $default;
119
- }
120
 
121
- // Maybe unserailize
122
- $section_settings = maybe_unserialize( $section_settings );
123
 
124
- // Check if setting exists
125
- if ( isset( $section_settings[ $setting ] ) ) {
126
 
127
  // Try to unserialize it and then return it
128
- return maybe_unserialize( $section_settings[ $setting ] );
129
- } else {
130
 
131
  // Return the default if no setting exists
132
- return $default;
 
133
  }
134
- }
135
-
136
- /**
137
- * Retrieves setting value based on name of setting
138
- *
139
- * @since 5.0.0
140
- * @param string $setting The name of the setting whose value we need to retrieve
141
- * @param mixed $default What we need to return if no setting exists with given $setting
142
- * @return $mixed Value set for $setting or $default if setting does not exist
143
- */
144
- public function get_setting( $setting, $default = false ) {
145
 
146
- global $mlwQuizMasterNext;
147
-
148
- // Return if empty
149
- if ( empty( $setting ) ) {
150
- return false;
151
- }
 
 
 
 
 
 
 
 
 
 
152
 
153
- // Check if ID is not set, for backwards compatibility
154
- if ( ! $this->quiz_id ) {
155
- $quiz_id = $mlwQuizMasterNext->quizCreator->get_id();
156
 
157
- // If get_id doesn't work, return false
158
- if ( ! $quiz_id ) {
159
- return false;
160
- } else {
161
- $this->prepare_quiz( $quiz_id );
162
- }
163
- }
164
 
165
- // Check if setting exists
166
- if ( isset( $this->settings[ $setting ] ) ) {
167
 
168
  // Try to unserialize it and then return it
169
- return maybe_unserialize( $this->settings[ $setting ] );
170
- } else {
171
 
172
  // Return the default if no setting exists
173
- return $default;
 
174
  }
175
- }
176
-
177
- /**
178
- * Updates a settings value, adding it if it didn't already exist
179
- *
180
- * @since 5.0.0
181
- * @param string $setting The name of the setting whose value we need to retrieve.
182
- * @param mixed $value The value that needs to be stored for the setting.
183
- * @return bool True if successful or false if fails
184
- */
185
- public function update_setting( $setting, $value ) {
186
- global $mlwQuizMasterNext;
187
-
188
- // Return if empty.
189
- if ( empty( $setting ) ) {
190
- $mlwQuizMasterNext->log_manager->add( 'Error when updating setting', 'Setting was empty with value equal to ' . print_r( $value, true ), 0, 'error' );
191
- return false;
192
- }
193
-
194
- // Check if ID is not set, for backwards compatibility.
195
- if ( ! $this->quiz_id ) {
196
- $quiz_id = $mlwQuizMasterNext->quizCreator->get_id();
197
-
198
- // If get_id doesn't work, return false.
199
- if ( ! $quiz_id ) {
200
- $mlwQuizMasterNext->log_manager->add( 'Error when updating setting', 'Quiz ID was not found', 0, 'error' );
201
- return false;
202
- } else {
203
- $this->prepare_quiz( $quiz_id );
204
- }
205
- }
206
-
207
- $old_value = $this->get_setting( $setting );
208
-
209
- // If the old value and new value are the same, return false.
210
- if ( $value === $old_value ) {
211
- return true;
212
- }
213
 
214
- // Try to serialize the value.
215
- $serialized_value = maybe_serialize( $value );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
216
 
217
- // Set the new value.
218
- $this->settings[ $setting ] = $serialized_value;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
219
 
220
- // Update the database.
221
- global $wpdb;
222
- $serialized_settings = serialize( $this->settings );
223
- $results = $wpdb->update(
224
- $wpdb->prefix . 'mlw_quizzes',
225
- array( 'quiz_settings' => $serialized_settings ),
226
- array( 'quiz_id' => $this->quiz_id ),
227
- array( '%s' ),
228
- array( '%d' )
229
- );
230
-
231
- if ( false === $results ) {
232
- $mlwQuizMasterNext->log_manager->add( 'Error when updating setting', $wpdb->last_error . ' from ' . $wpdb->last_query, 0, 'error' );
233
- return false;
234
- } else {
235
- return true;
236
- }
237
- }
238
 
239
  /**
240
  * Loads the settings for the quiz
7
  *
8
  * @since 5.0.0
9
  */
10
+ class QSM_Quiz_Settings
11
+ {
12
 
13
  /**
14
  * ID of the quiz
16
  * @var int
17
  * @since 5.0.0
18
  */
19
+ private $quiz_id;
20
+
21
+ /**
22
+ * The settings for the quiz
23
+ *
24
+ * @var array
25
+ * @since 5.0.0
26
+ */
27
+ private $settings;
28
+
29
+ /**
30
+ * The fields that have been registered
31
+ *
32
+ * @var array
33
+ * @since 5.0.0
34
+ */
35
+ private $registered_fields;
36
+
37
+ /**
38
+ * Prepares the settings for the supplied quiz
39
+ *
40
+ * @since 5.0.0
41
+ * @param int $quiz_id the ID of the quiz that we are handling the settings data for
42
+ */
43
+ public function prepare_quiz($quiz_id)
44
+ {
45
+ $this->quiz_id = intval($quiz_id);
46
+ $this->load_settings();
47
+ }
48
 
 
 
 
 
 
 
 
 
 
 
49
 
50
+ /**
51
+ * Registers a setting be shown on the Options or Text tab
52
+ *
53
+ * @since 5.0.0
54
+ * @param array $field_array An array of the components for the settings field
55
+ */
56
+ public function register_setting($field_array, $section = 'quiz_options')
57
+ {
58
 
59
  /*
60
  Example field array
75
  );
76
  */
77
 
78
+ // Adds field to registered fields
79
+ $this->registered_fields[ $section ][] = $field_array;
80
+ }
 
81
 
82
+ /**
83
+ * Retrieves the registered setting fields
84
+ *
85
+ * @since 5.0.0
86
+ * @param string $section The section whose fields that are being retrieved
87
+ * @return array All the fields registered the the section provided
88
+ */
89
+ public function load_setting_fields($section = 'quiz_options')
90
+ {
91
 
92
  // Checks if section exists in registered fields and returns it if it does
93
+ if (isset($this->registered_fields[ $section ])) {
94
+ return $this->registered_fields[ $section ];
95
+ } else {
96
+ return false;
97
+ }
98
  }
 
99
 
100
+ /**
101
+ * Retrieves a setting value from a section based on name of section and setting
102
+ *
103
+ * @since 5.0.0
104
+ * @param string $section The name of the section the setting is registered in
105
+ * @param string $setting The name of the setting whose value we need to retrieve
106
+ * @param mixed $default What we need to return if no setting exists with given $setting
107
+ * @return $mixed Value set for $setting or $default if setting does not exist
108
+ */
109
+ public function get_section_setting($section, $setting, $default = false)
110
+ {
111
 
112
  // Return if section or setting is empty
113
+ if (empty($section) || empty($setting)) {
114
+ return $default;
115
+ }
116
 
117
+ // Get settings in section
118
+ $section_settings = $this->get_setting($section);
119
 
120
+ // Return default if section not found
121
+ if (! $section_settings) {
122
+ return $default;
123
+ }
124
 
125
+ // Maybe unserailize
126
+ $section_settings = maybe_unserialize($section_settings);
127
 
128
+ // Check if setting exists
129
+ if (isset($section_settings[ $setting ])) {
130
 
131
  // Try to unserialize it and then return it
132
+ return maybe_unserialize($section_settings[ $setting ]);
133
+ } else {
134
 
135
  // Return the default if no setting exists
136
+ return $default;
137
+ }
138
  }
 
 
 
 
 
 
 
 
 
 
 
139
 
140
+ /**
141
+ * Retrieves setting value based on name of setting
142
+ *
143
+ * @since 5.0.0
144
+ * @param string $setting The name of the setting whose value we need to retrieve
145
+ * @param mixed $default What we need to return if no setting exists with given $setting
146
+ * @return $mixed Value set for $setting or $default if setting does not exist
147
+ */
148
+ public function get_setting($setting, $default = false)
149
+ {
150
+ global $mlwQuizMasterNext;
151
+
152
+ // Return if empty
153
+ if (empty($setting)) {
154
+ return false;
155
+ }
156
 
157
+ // Check if ID is not set, for backwards compatibility
158
+ if (! $this->quiz_id) {
159
+ $quiz_id = $mlwQuizMasterNext->quizCreator->get_id();
160
 
161
+ // If get_id doesn't work, return false
162
+ if (! $quiz_id) {
163
+ return false;
164
+ } else {
165
+ $this->prepare_quiz($quiz_id);
166
+ }
167
+ }
168
 
169
+ // Check if setting exists
170
+ if (isset($this->settings[ $setting ])) {
171
 
172
  // Try to unserialize it and then return it
173
+ return maybe_unserialize($this->settings[ $setting ]);
174
+ } else {
175
 
176
  // Return the default if no setting exists
177
+ return $default;
178
+ }
179
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
180
 
181
+ /**
182
+ * Updates a settings value, adding it if it didn't already exist
183
+ *
184
+ * @since 5.0.0
185
+ * @param string $setting The name of the setting whose value we need to retrieve.
186
+ * @param mixed $value The value that needs to be stored for the setting.
187
+ * @return bool True if successful or false if fails
188
+ */
189
+ public function update_setting($setting, $value)
190
+ {
191
+ global $mlwQuizMasterNext;
192
+
193
+ // Return if empty.
194
+ if (empty($setting)) {
195
+ $mlwQuizMasterNext->log_manager->add('Error when updating setting', 'Setting was empty with value equal to ' . print_r($value, true), 0, 'error');
196
+ return false;
197
+ }
198
 
199
+ // Check if ID is not set, for backwards compatibility.
200
+ if (! $this->quiz_id) {
201
+ $quiz_id = $mlwQuizMasterNext->quizCreator->get_id();
202
+
203
+ // If get_id doesn't work, return false.
204
+ if (! $quiz_id) {
205
+ $mlwQuizMasterNext->log_manager->add('Error when updating setting', 'Quiz ID was not found', 0, 'error');
206
+ return false;
207
+ } else {
208
+ $this->prepare_quiz($quiz_id);
209
+ }
210
+ }
211
+
212
+
213
+ $old_value = $this->get_setting($setting);
214
+ if (isset($_POST['global_setting'])) {
215
+ $setDefaultvalue=$old_value;
216
+ $getdefaultvalue=get_option('qsm-quiz-settings');
217
+
218
+ $setDefaultvalue['form_type']=$getdefaultvalue['form_type'];
219
+ $setDefaultvalue['system']=$getdefaultvalue['system'];
220
+ $setDefaultvalue['score_roundoff']=$getdefaultvalue['score_roundoff'];
221
+ $setDefaultvalue['progress_bar']=$getdefaultvalue['progress_bar'];
222
+ $setDefaultvalue['require_log_in']=$getdefaultvalue['require_log_in'];
223
+ $setDefaultvalue['pagination']=$getdefaultvalue['pagination'];
224
+ $setDefaultvalue['timer_limit']=$getdefaultvalue['timer_limit'];
225
+ $setDefaultvalue['enable_result_after_timer_end']=$getdefaultvalue['enable_result_after_timer_end'];
226
+ $setDefaultvalue['skip_validation_time_expire']=$getdefaultvalue['skip_validation_time_expire'];
227
+ $setDefaultvalue['total_user_tries']=$getdefaultvalue['total_user_tries'];
228
+ $setDefaultvalue['limit_total_entries']=$getdefaultvalue['limit_total_entries'];
229
+ $setDefaultvalue['question_from_total']=$getdefaultvalue['question_from_total'];
230
+ $setDefaultvalue['question_per_category']=$getdefaultvalue['question_per_category'];
231
+ $setDefaultvalue['contact_info_location']=$getdefaultvalue['contact_info_location'];
232
+ $setDefaultvalue['loggedin_user_contact']=$getdefaultvalue['loggedin_user_contact'];
233
+ $setDefaultvalue['comment_section']=$getdefaultvalue['comment_section'];
234
+ $setDefaultvalue['question_numbering']=$getdefaultvalue['question_numbering'];
235
+ $setDefaultvalue['store_responses']=$getdefaultvalue['store_responses'];
236
+ $setDefaultvalue['disable_answer_onselect']=$getdefaultvalue['disable_answer_onselect'];
237
+ $setDefaultvalue['ajax_show_correct']=$getdefaultvalue['ajax_show_correct'];
238
+ $setDefaultvalue['contact_disable_autofill']=$getdefaultvalue['contact_disable_autofill'];
239
+ $setDefaultvalue['form_disable_autofill']=$getdefaultvalue['form_disable_autofill'];
240
+ $setDefaultvalue['show_category_on_front']=$getdefaultvalue['show_category_on_front'];
241
+ $setDefaultvalue['enable_quick_result_mc']=$getdefaultvalue['enable_quick_result_mc'];
242
+ $setDefaultvalue['end_quiz_if_wrong']=$getdefaultvalue['end_quiz_if_wrong'];
243
+ $setDefaultvalue['enable_quick_correct_answer_info']=$getdefaultvalue['enable_quick_correct_answer_info'];
244
+ $setDefaultvalue['enable_retake_quiz_button']=$getdefaultvalue['enable_retake_quiz_button'];
245
+ $setDefaultvalue['enable_pagination_quiz']=$getdefaultvalue['enable_pagination_quiz'];
246
+ $setDefaultvalue['enable_deselect_option']=$getdefaultvalue['enable_deselect_option'];
247
+ $setDefaultvalue['disable_description_on_result']=$getdefaultvalue['disable_description_on_result'];
248
+ $setDefaultvalue['disable_scroll_next_previous_click']=$getdefaultvalue['disable_scroll_next_previous_click'];
249
+ $setDefaultvalue['quiz_animation']=$getdefaultvalue['quiz_animation'];
250
+ $setDefaultvalue['result_page_fb_image']=$getdefaultvalue['result_page_fb_image'];
251
+ $setDefaultvalue['randomness_order']=$getdefaultvalue['randomness_order'];
252
+ $setDefaultvalue['scheduled_time_start']=$getdefaultvalue['scheduled_time_start'];
253
+ $setDefaultvalue['scheduled_time_end']=$getdefaultvalue['scheduled_time_end'];
254
+ $setDefaultvalue['not_allow_after_expired_time']=$getdefaultvalue['not_allow_after_expired_time'];
255
+ // Try to serialize the value.
256
+
257
+ return $this->save_quiz_settings($setting,$setDefaultvalue);
258
+ }
259
+ // If the old value and new value are the same, return false.
260
+ if ($value === $old_value) {
261
+ return true;
262
+ }
263
+ // Try to serialize the value.
264
+ return $this->save_quiz_settings($setting,$value);
265
+ }
266
+ /**
267
+ * Update setting option fdor Quiz
268
+ *
269
+ * @since 5.0.0
270
+ */
271
+ private function save_quiz_settings($setting,$settingArray) {
272
+ global $mlwQuizMasterNext;
273
+ $serialized_value = maybe_serialize( $settingArray );
274
+ // Set the new value.
275
+ $this->settings[ $setting ] = $serialized_value;
276
+ // Update the database.
277
+ global $wpdb;
278
+ $serialized_settings = serialize( $this->settings );
279
+ $results = $wpdb->update(
280
+ $wpdb->prefix . 'mlw_quizzes',
281
+ array( 'quiz_settings' => $serialized_settings ),
282
+ array( 'quiz_id' => $this->quiz_id ),
283
+ array( '%s' ),
284
+ array( '%d' )
285
+ );
286
+ if ( false === $results ) {
287
+ $mlwQuizMasterNext->log_manager->add( 'Error when updating setting', $wpdb->last_error . ' from ' . $wpdb->last_query, 0, 'error' );
288
+ return false;
289
+ } else {
290
+ return true;
291
+ }
292
 
293
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
294
 
295
  /**
296
  * Loads the settings for the quiz
php/question-types.php CHANGED
@@ -1195,7 +1195,7 @@ function qmn_fill_blank_review( $id, $question, $answers ) {
1195
  if ( strpos( $question, '%BLANK%' ) !== false || strpos( $question, '%blank%' ) !== false ) {
1196
  $return_array['question_text'] = str_replace( array( '%BLANK%', '%blank%' ), array( '__________', '__________' ), do_shortcode( htmlspecialchars_decode( $question, ENT_QUOTES ) ) );
1197
  }
1198
- $user_input = $user_text = array();
1199
  if ( isset( $_POST[ 'question' . $id ] ) && ! empty( $_POST[ 'question' . $id ] ) ) {
1200
  foreach ( $_POST[ 'question' . $id ] as $input ) {
1201
  $decode_user_answer = sanitize_textarea_field( strval( stripslashes( htmlspecialchars_decode( $input, ENT_QUOTES ) ) ) );
@@ -1204,7 +1204,7 @@ function qmn_fill_blank_review( $id, $question, $answers ) {
1204
  $user_text[] = $mlw_user_answer;
1205
  }
1206
  }
1207
-
1208
  $total_correct = $user_correct = 0;
1209
  if ( $match_answer == 'sequence' ) {
1210
  foreach ( $answers as $key => $answer ) {
@@ -1215,7 +1215,9 @@ function qmn_fill_blank_review( $id, $question, $answers ) {
1215
  $user_correct += 1;
1216
  }
1217
  $total_correct++;
 
1218
  }
 
1219
  $return_array['user_text'] = implode( '.', $user_text );
1220
  $return_array['user_compare_text'] = implode( '=====', $user_text );
1221
  if($total_correct == $user_correct){
@@ -1234,31 +1236,36 @@ function qmn_fill_blank_review( $id, $question, $answers ) {
1234
  if($total_user_input < $total_option){
1235
  foreach($user_input as $k => $input){
1236
  $key = array_search( $input, $answers_array );
1237
- if($key !== false){
1238
  $return_array['points'] += $answers[$key][1];
1239
  } else {
1240
  $correct = false;
1241
  }
 
1242
  }
1243
  } else {
1244
  foreach($answers_array as $k => $answer){
1245
  $key = array_search( $answer, $user_input );
1246
- if($key !== false){
1247
  $return_array['points'] += $answers[$k][1];
1248
  } else {
1249
  $correct = false;
1250
  }
 
1251
  }
1252
  }
1253
  if($correct){
1254
  $return_array['correct'] = 'correct';
1255
  }
 
 
1256
  $return_array['user_compare_text'] = implode( '=====', $user_text );
1257
  }
1258
 
1259
  /**
1260
  * Hook to filter answers array
1261
  */
 
1262
  return apply_filters( 'qmn_fill_blank_review', $return_array, $answers );
1263
  }
1264
 
1195
  if ( strpos( $question, '%BLANK%' ) !== false || strpos( $question, '%blank%' ) !== false ) {
1196
  $return_array['question_text'] = str_replace( array( '%BLANK%', '%blank%' ), array( '__________', '__________' ), do_shortcode( htmlspecialchars_decode( $question, ENT_QUOTES ) ) );
1197
  }
1198
+ $correct_text=$user_input = $user_text = array();
1199
  if ( isset( $_POST[ 'question' . $id ] ) && ! empty( $_POST[ 'question' . $id ] ) ) {
1200
  foreach ( $_POST[ 'question' . $id ] as $input ) {
1201
  $decode_user_answer = sanitize_textarea_field( strval( stripslashes( htmlspecialchars_decode( $input, ENT_QUOTES ) ) ) );
1204
  $user_text[] = $mlw_user_answer;
1205
  }
1206
  }
1207
+
1208
  $total_correct = $user_correct = 0;
1209
  if ( $match_answer == 'sequence' ) {
1210
  foreach ( $answers as $key => $answer ) {
1215
  $user_correct += 1;
1216
  }
1217
  $total_correct++;
1218
+ $correct_text[]=$answers[$key][0];
1219
  }
1220
+ $return_array['correct_text'] = implode( '.', $correct_text );
1221
  $return_array['user_text'] = implode( '.', $user_text );
1222
  $return_array['user_compare_text'] = implode( '=====', $user_text );
1223
  if($total_correct == $user_correct){
1236
  if($total_user_input < $total_option){
1237
  foreach($user_input as $k => $input){
1238
  $key = array_search( $input, $answers_array );
1239
+ if($key !== false){
1240
  $return_array['points'] += $answers[$key][1];
1241
  } else {
1242
  $correct = false;
1243
  }
1244
+ $correct_text[]=$answers[$key][0];
1245
  }
1246
  } else {
1247
  foreach($answers_array as $k => $answer){
1248
  $key = array_search( $answer, $user_input );
1249
+ if($key !== false){
1250
  $return_array['points'] += $answers[$k][1];
1251
  } else {
1252
  $correct = false;
1253
  }
1254
+ $correct_text[]=$answers[$k][0];
1255
  }
1256
  }
1257
  if($correct){
1258
  $return_array['correct'] = 'correct';
1259
  }
1260
+ $return_array['user_text'] = implode( '.', $user_text );
1261
+ $return_array['correct_text'] = implode( '.', $correct_text );
1262
  $return_array['user_compare_text'] = implode( '=====', $user_text );
1263
  }
1264
 
1265
  /**
1266
  * Hook to filter answers array
1267
  */
1268
+
1269
  return apply_filters( 'qmn_fill_blank_review', $return_array, $answers );
1270
  }
1271
 
php/rest-api.php CHANGED
@@ -122,6 +122,16 @@ function qsm_register_rest_routes() {
122
  },
123
  )
124
  );
 
 
 
 
 
 
 
 
 
 
125
  }
126
 
127
  /**
@@ -677,4 +687,29 @@ function qsm_rest_save_question( WP_REST_Request $request ) {
677
  'status' => 'error',
678
  'msg' => __( 'User not logged in', 'quiz-master-next' ),
679
  );
680
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
122
  },
123
  )
124
  );
125
+ // Get Categories of quiz
126
+ register_rest_route(
127
+ 'quiz-survey-master/v1',
128
+ '/quizzes/(?P<id>\d+)/categories',
129
+ array(
130
+ 'methods' => WP_REST_Server::READABLE,
131
+ 'callback' => 'qsm_rest_get_categories',
132
+ 'permission_callback' => '__return_true',
133
+ )
134
+ );
135
  }
136
 
137
  /**
687
  'status' => 'error',
688
  'msg' => __( 'User not logged in', 'quiz-master-next' ),
689
  );
690
+ }
691
+
692
+ /**
693
+ * Gets categories for a quiz.
694
+ *
695
+ * @since 7.2.1
696
+ * @param WP_REST_Request $request The request sent from WP REST API.
697
+ * @return array Categories for the quiz.
698
+ */
699
+ function qsm_rest_get_categories( WP_REST_Request $request ) {
700
+ if ( is_user_logged_in() ) {
701
+ $current_user = wp_get_current_user();
702
+ if ( 0 !== $current_user ) {
703
+ $categories = array();
704
+ $quiz_id = isset( $request['id'] ) ? intval( $request['id'] ) : 0;
705
+ if ( 0 !== $quiz_id ) {
706
+ $categories = QSM_Questions::get_quiz_categories( $quiz_id );
707
+ }
708
+ return $categories;
709
+ }
710
+ }
711
+ return array(
712
+ 'status' => 'error',
713
+ 'msg' => __( 'User not logged in', 'quiz-master-next' ),
714
+ );
715
+ }
php/shortcodes.php CHANGED
@@ -240,7 +240,7 @@ function qsm_get_post_id_from_quiz_id( $quiz_id ) {
240
  }
241
 
242
  add_filter( 'qmn_end_shortcode', 'qsm_display_popup_div', 10, 3 );
243
- function qsm_display_popup_div( $return_display, $qmn_quiz_options, $qmn_array_for_variables ) {
244
  if ( $qmn_quiz_options->enable_result_after_timer_end == 0 ) {
245
  $return_display .= '<div style="display: none;" class="qsm-popup qsm-popup-slide" id="modal-3" aria-hidden="false">';
246
  $return_display .= '<div class="qsm-popup__overlay" tabindex="-1" data-micromodal-close="">';
@@ -255,4 +255,21 @@ function qsm_display_popup_div( $return_display, $qmn_quiz_options, $qmn_array_f
255
  $return_display .= '</div>';
256
  }
257
  return $return_display;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
258
  }
240
  }
241
 
242
  add_filter( 'qmn_end_shortcode', 'qsm_display_popup_div', 10, 3 );
243
+ function qsm_display_popup_div( $return_display, $qmn_quiz_options ) {
244
  if ( $qmn_quiz_options->enable_result_after_timer_end == 0 ) {
245
  $return_display .= '<div style="display: none;" class="qsm-popup qsm-popup-slide" id="modal-3" aria-hidden="false">';
246
  $return_display .= '<div class="qsm-popup__overlay" tabindex="-1" data-micromodal-close="">';
255
  $return_display .= '</div>';
256
  }
257
  return $return_display;
258
+ }
259
+ add_filter( 'qmn_end_shortcode', 'qsm_display_popup_div_expired_quiz', 10, 3 );
260
+ function qsm_display_popup_div_expired_quiz( $return_display, $qmn_quiz_options ) {
261
+ if ( $qmn_quiz_options->enable_result_after_timer_end == 0 ) {
262
+ $return_display .= '<div style="display: none;" class="qsm-popup qsm-popup-slide" id="modal-4" aria-hidden="false">';
263
+ $return_display .= '<div class="qsm-popup__overlay" tabindex="-1" data-micromodal-close="">';
264
+ $return_display .= '<div class="qsm-popup__container qmn_quiz_container" role="dialog" aria-modal="true">';
265
+ $return_display .= '<div class="qsm-popup__content">';
266
+ $return_display .= '<img src="' . QSM_PLUGIN_URL . 'assets/clock.png' . '" alt="clock.png"/>';
267
+ $return_display .= '<p class="qsm-time-up-text">Time\'s up</p>';
268
+ $return_display .= '</div>';
269
+ $return_display .= '<footer class="qsm-popup__footer"><button class="qsm-popup-secondary-button qmn_btn" data-micromodal-close="" aria-label="Close this dialog window" onclick="location.reload();">Cancel</button></footer>';
270
+ $return_display .= '</div>';
271
+ $return_display .= '</div>';
272
+ $return_display .= '</div>';
273
+ }
274
+ return $return_display;
275
  }
php/template-variables.php CHANGED
@@ -910,7 +910,7 @@ function qsm_questions_answers_shortcode_to_text( $mlw_quiz_array, $qmn_question
910
  if ( $disable_description_on_result == 1 ) {
911
  $mlw_question_answer_display = str_replace( '%QUESTION%', '<b>' . htmlspecialchars_decode( $answer['question_title'], ENT_QUOTES ) . '</b>', $mlw_question_answer_display );
912
  } else {
913
- $mlw_question_answer_display = str_replace( '%QUESTION%', '<b>' . htmlspecialchars_decode( $answer['question_title'], ENT_QUOTES ) . '</b>' . $add_br . htmlspecialchars_decode( $answer[0], ENT_QUOTES ), $mlw_question_answer_display );
914
  }
915
  } else {
916
  $mlw_question_answer_display = str_replace( '%QUESTION%', '<b>' . htmlspecialchars_decode( $answer[0], ENT_QUOTES ) . '</b>', $mlw_question_answer_display );
@@ -933,6 +933,15 @@ function qsm_questions_answers_shortcode_to_text( $mlw_quiz_array, $qmn_question
933
  $quiz_system = isset( $mlw_quiz_array['quiz_system'] ) ? $mlw_quiz_array['quiz_system'] : 0;
934
  if ( isset( $answer['id'] ) && isset( $questions[ $answer['id'] ] ) && ! empty( $questions[ $answer['id'] ] ) ) {
935
  $total_answers = isset( $questions[ $answer['id'] ]['answers'] ) ? $questions[ $answer['id'] ]['answers'] : array();
 
 
 
 
 
 
 
 
 
936
  if ( $total_answers ) {
937
  if ( isset( $answer['question_type'] ) && in_array( $answer['question_type'], $show_two_option_questions ) ) {
938
  $do_show_wrong = true;
@@ -1172,13 +1181,14 @@ function qsm_questions_answers_shortcode_to_text( $mlw_quiz_array, $qmn_question
1172
  }
1173
  }
1174
  $mlw_question_answer_display = str_replace( '%USER_ANSWERS_DEFAULT%', do_shortcode( $question_with_answer_text ), $mlw_question_answer_display );
 
1175
  }
1176
  if ( isset( $answer['question_type'] ) && $answer['question_type'] == 11 ) {
1177
  $file_extension = substr( $answer[1], -4 );
1178
  if ( $file_extension == '.jpg' || $file_extension == '.jpeg' || $file_extension == '.png' || $file_extension == '.gif' ) {
1179
- $mlw_question_answer_display = str_replace( '%USER_ANSWER%', "<span class='$user_answer_class'><img src='$answer[1]'/></span>", $mlw_question_answer_display );
1180
  } else {
1181
- $mlw_question_answer_display = str_replace( '%USER_ANSWER%', "<span class='$user_answer_class'>" . trim( htmlspecialchars_decode( $answer[1], ENT_QUOTES ) ) . '</span>', $mlw_question_answer_display );
1182
  }
1183
  } else {
1184
  $user_answer_new = $answer[1];
@@ -1187,17 +1197,17 @@ function qsm_questions_answers_shortcode_to_text( $mlw_quiz_array, $qmn_question
1187
  }
1188
  if ( isset( $question_settings['answerEditor'] ) && $question_settings['answerEditor'] == 'image' && $user_answer_new != '' ) {
1189
  $image_url = htmlspecialchars_decode( $user_answer_new, ENT_QUOTES );
1190
- $mlw_question_answer_display = str_replace( '%USER_ANSWER%', "<span class='$user_answer_class'><img src='$image_url'/></span>", $mlw_question_answer_display );
1191
  } else {
1192
- $mlw_question_answer_display = str_replace( '%USER_ANSWER%', "<span class='$user_answer_class'>" . htmlspecialchars_decode( $user_answer_new, ENT_QUOTES ) . '</span>', $mlw_question_answer_display );
1193
  }
1194
  }
1195
  $answer_2 = ! empty( $answer[2] ) ? $answer[2] : 'NA';
1196
  if ( isset( $question_settings['answerEditor'] ) && $question_settings['answerEditor'] == 'image' && $answer_2 != 'NA' ) {
1197
  $image_url = htmlspecialchars_decode( $answer_2, ENT_QUOTES );
1198
- $mlw_question_answer_display = str_replace( '%CORRECT_ANSWER%', '<img src="' . $image_url . '"/>', $mlw_question_answer_display );
1199
  } else {
1200
- $mlw_question_answer_display = str_replace( '%CORRECT_ANSWER%', htmlspecialchars_decode( $answer_2, ENT_QUOTES ), $mlw_question_answer_display );
1201
  }
1202
  $answer_3 = ! empty( $answer[3] ) ? $answer[3] : 'NA';
1203
  $mlw_question_answer_display = str_replace( '%USER_COMMENTS%', $answer_3, $mlw_question_answer_display );
910
  if ( $disable_description_on_result == 1 ) {
911
  $mlw_question_answer_display = str_replace( '%QUESTION%', '<b>' . htmlspecialchars_decode( $answer['question_title'], ENT_QUOTES ) . '</b>', $mlw_question_answer_display );
912
  } else {
913
+ $mlw_question_answer_display = str_replace( '%QUESTION%', '<b>' . htmlspecialchars_decode( $answer['question_title'], ENT_QUOTES ) . '</b>' . $add_br . htmlspecialchars_decode( $answer[0], ENT_QUOTES ).$add_br, $mlw_question_answer_display );
914
  }
915
  } else {
916
  $mlw_question_answer_display = str_replace( '%QUESTION%', '<b>' . htmlspecialchars_decode( $answer[0], ENT_QUOTES ) . '</b>', $mlw_question_answer_display );
933
  $quiz_system = isset( $mlw_quiz_array['quiz_system'] ) ? $mlw_quiz_array['quiz_system'] : 0;
934
  if ( isset( $answer['id'] ) && isset( $questions[ $answer['id'] ] ) && ! empty( $questions[ $answer['id'] ] ) ) {
935
  $total_answers = isset( $questions[ $answer['id'] ]['answers'] ) ? $questions[ $answer['id'] ]['answers'] : array();
936
+
937
+ $qsm_random_quetion_answer = get_post_meta($answer['id'],'qsm_random_quetion_answer',true);
938
+ if(!empty($qsm_random_quetion_answer))
939
+ {
940
+ $total_answers = $qsm_random_quetion_answer;
941
+ // No longer Need This Value
942
+ delete_post_meta( $answer['id'], 'qsm_random_quetion_answer');
943
+ }
944
+
945
  if ( $total_answers ) {
946
  if ( isset( $answer['question_type'] ) && in_array( $answer['question_type'], $show_two_option_questions ) ) {
947
  $do_show_wrong = true;
1181
  }
1182
  }
1183
  $mlw_question_answer_display = str_replace( '%USER_ANSWERS_DEFAULT%', do_shortcode( $question_with_answer_text ), $mlw_question_answer_display );
1184
+ $mlw_question_answer_display = str_replace( '%USER_ANSWER%', do_shortcode( $question_with_answer_text ), $mlw_question_answer_display );
1185
  }
1186
  if ( isset( $answer['question_type'] ) && $answer['question_type'] == 11 ) {
1187
  $file_extension = substr( $answer[1], -4 );
1188
  if ( $file_extension == '.jpg' || $file_extension == '.jpeg' || $file_extension == '.png' || $file_extension == '.gif' ) {
1189
+ $mlw_question_answer_display = str_replace( '%USER_ANSWER%', "<span class='$user_answer_class'><img src='$answer[1]'/></span><br/>", $mlw_question_answer_display );
1190
  } else {
1191
+ $mlw_question_answer_display = str_replace( '%USER_ANSWER%', "<span class='$user_answer_class'>" . trim( htmlspecialchars_decode( $answer[1], ENT_QUOTES ) ) . '</span><br/>', $mlw_question_answer_display );
1192
  }
1193
  } else {
1194
  $user_answer_new = $answer[1];
1197
  }
1198
  if ( isset( $question_settings['answerEditor'] ) && $question_settings['answerEditor'] == 'image' && $user_answer_new != '' ) {
1199
  $image_url = htmlspecialchars_decode( $user_answer_new, ENT_QUOTES );
1200
+ $mlw_question_answer_display = str_replace( '%USER_ANSWER%', "<span class='$user_answer_class'><img src='$image_url'/></span><br/>", $mlw_question_answer_display );
1201
  } else {
1202
+ $mlw_question_answer_display = str_replace( '%USER_ANSWER%', "<span class='$user_answer_class'>" . htmlspecialchars_decode( $user_answer_new, ENT_QUOTES ) . '</span><br/>', $mlw_question_answer_display );
1203
  }
1204
  }
1205
  $answer_2 = ! empty( $answer[2] ) ? $answer[2] : 'NA';
1206
  if ( isset( $question_settings['answerEditor'] ) && $question_settings['answerEditor'] == 'image' && $answer_2 != 'NA' ) {
1207
  $image_url = htmlspecialchars_decode( $answer_2, ENT_QUOTES );
1208
+ $mlw_question_answer_display = str_replace( '%CORRECT_ANSWER%', '<br/><img src="' . $image_url . '"/>', $mlw_question_answer_display );
1209
  } else {
1210
+ $mlw_question_answer_display = str_replace( '%CORRECT_ANSWER%', ''.htmlspecialchars_decode( $answer_2, ENT_QUOTES ).'<br/>', $mlw_question_answer_display );
1211
  }
1212
  $answer_3 = ! empty( $answer[3] ) ? $answer[3] : 'NA';
1213
  $mlw_question_answer_display = str_replace( '%USER_COMMENTS%', $answer_3, $mlw_question_answer_display );
readme.txt CHANGED
@@ -2,9 +2,9 @@
2
  Contributors: quizsurvey,expresstech
3
  Tags: quiz, survey, lead, test, score, exam, questionnaire, question,wordpress quiz plugin
4
  Requires at least: 4.9
5
- Tested up to: 5.7
6
  Requires PHP: 5.4
7
- Stable tag: 7.3.0
8
  License: GPLv2
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
@@ -152,6 +152,15 @@ This is usually a theme conflict. You can [checkout out our common conflict solu
152
 
153
  == Changelog ==
154
 
 
 
 
 
 
 
 
 
 
155
  = 7.3.0 (July 29, 2021) =
156
  * Feature: Added option to add multiple categories to single question.
157
  * Feature: Added option to display quiz results based on category points.
2
  Contributors: quizsurvey,expresstech
3
  Tags: quiz, survey, lead, test, score, exam, questionnaire, question,wordpress quiz plugin
4
  Requires at least: 4.9
5
+ Tested up to: 5.8
6
  Requires PHP: 5.4
7
+ Stable tag: 7.3.1
8
  License: GPLv2
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
152
 
153
  == Changelog ==
154
 
155
+ = 7.3.1 (August 13, 2021) =
156
+ * Bug: Fixed the error on updating database.
157
+ * Bug: Fixed the issue of everything displayed in the same line in the results page.
158
+ * Bug: Fixed the issue of fill in the blank question type not showing user answer and correct answer in the results page and email.
159
+ * Feature: Added global default settings for quiz options.
160
+ * Enhancement: Added option to deny quiz submission after end date/time
161
+ * Enhancement: Made order of random questions same on the results page and the quiz frontend.
162
+
163
+
164
  = 7.3.0 (July 29, 2021) =
165
  * Feature: Added option to add multiple categories to single question.
166
  * Feature: Added option to display quiz results based on category points.
uninstall.php CHANGED
@@ -56,6 +56,7 @@ $qsm_options = array(
56
  'qsm_change_the_post_type',
57
  'qmn_quiz_taken_cnt',
58
  'qmn-settings',
 
59
  'mlw_quiz_master_version',
60
  'qmn_tracker_last_time',
61
  'qmn-tracking-notice',
56
  'qsm_change_the_post_type',
57
  'qmn_quiz_taken_cnt',
58
  'qmn-settings',
59
+ 'qsm-quiz-settings',
60
  'mlw_quiz_master_version',
61
  'qmn_tracker_last_time',
62
  'qmn-tracking-notice',