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

Version Description

(Feb 24, 2020)= * Bug: Security Issues reported by WORDFENCE * Bug: Change text in Get a Free Addon page * Feature: Change sendy to sendinblue in free addon page * Feature: Added sorting functionality on name and last activity

Download this release

Release Info

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

Code changes from version 6.4.3 to 6.4.4

js/admin.js CHANGED
@@ -69,7 +69,7 @@ var QSMAdmin;
69
  email = $form.find('input[name="email"]').val(),
70
  action = 'qsm_send_data_sendy';
71
  $form.find('#submit').attr('disabled', true);
72
- $.post(ajaxurl, {name: name, email: email, action: action},
73
  function (data) {
74
  if (data)
75
  {
@@ -103,7 +103,9 @@ var QSMAdmin;
103
  }
104
  );
105
  });
106
- /**/
107
- jQuery('.buttonset').buttonset();
 
 
108
  });
109
  }(jQuery));
69
  email = $form.find('input[name="email"]').val(),
70
  action = 'qsm_send_data_sendy';
71
  $form.find('#submit').attr('disabled', true);
72
+ $.post(ajaxurl, {name: name, email: email, nonce: qsmAdminObject.saveNonce, action: action},
73
  function (data) {
74
  if (data)
75
  {
103
  }
104
  );
105
  });
106
+ /**/
107
+ if(jQuery('.buttonset').length > 0){
108
+ jQuery('.buttonset').buttonset();
109
+ }
110
  });
111
  }(jQuery));
js/qsm-admin-contact.js CHANGED
@@ -129,7 +129,8 @@ var QSMContact;
129
  var data = {
130
  action: 'qsm_save_contact',
131
  contact_form: contactForm,
132
- quiz_id : qsmContactObject.quizID
 
133
  };
134
 
135
  jQuery.post( ajaxurl, data, function( response ) {
129
  var data = {
130
  action: 'qsm_save_contact',
131
  contact_form: contactForm,
132
+ quiz_id : qsmContactObject.quizID,
133
+ nonce : qsmContactObject.saveNonce,
134
  };
135
 
136
  jQuery.post( ajaxurl, data, function( response ) {
js/qsm-admin-question.js CHANGED
@@ -172,7 +172,8 @@ var import_button;
172
  var data = {
173
  action: 'qsm_save_pages',
174
  pages: pages,
175
- quiz_id : qsmQuestionSettings.quizID
 
176
  };
177
 
178
  jQuery.ajax( ajaxurl, {
172
  var data = {
173
  action: 'qsm_save_pages',
174
  pages: pages,
175
+ quiz_id : qsmQuestionSettings.quizID,
176
+ nonce : qsmQuestionSettings.saveNonce,
177
  };
178
 
179
  jQuery.ajax( ajaxurl, {
js/qsm-quiz.js CHANGED
@@ -472,6 +472,17 @@ function qmnValidation( element, quiz_form_id ) {
472
  return result;
473
  }
474
 
 
 
 
 
 
 
 
 
 
 
 
475
  function qmnFormSubmit( quiz_form_id ) {
476
  var quiz_id = +jQuery( '#' + quiz_form_id ).find( '.qmn_quiz_id' ).val();
477
  var $container = jQuery( '#' + quiz_form_id ).closest( '.qmn_quiz_container' );
@@ -484,25 +495,32 @@ function qmnFormSubmit( quiz_form_id ) {
484
  jQuery( '.mlw_qmn_quiz select' ).attr( 'disabled', false );
485
  jQuery( '.mlw_qmn_question_comment' ).attr( 'disabled', false );
486
  jQuery( '.mlw_answer_open_text' ).attr( 'disabled', false );
487
-
488
- var data = {
489
- action: 'qmn_process_quiz',
490
- quizData: jQuery( '#' + quiz_form_id ).serialize()
491
- };
492
-
 
 
 
493
  qsmEndTimeTakenTimer();
494
-
495
  if ( qmn_quiz_data[quiz_id].hasOwnProperty( 'timer_limit' ) ) {
496
  QSM.endTimer( quiz_id );
497
  }
498
-
499
  jQuery( '#' + quiz_form_id + ' input[type=submit]' ).attr( 'disabled', 'disabled' );
500
  qsmDisplayLoading( $container );
501
-
502
- jQuery.post( qmn_ajax_object.ajaxurl, data, function( response ) {
503
- qmnDisplayResults( JSON.parse( response ), quiz_form_id, $container );
504
- });
505
-
 
 
 
 
 
 
506
  return false;
507
  }
508
 
472
  return result;
473
  }
474
 
475
+ function getFormData($form){
476
+ var unindexed_array = $form.serializeArray();
477
+ var indexed_array = {};
478
+
479
+ jQuery.map(unindexed_array, function(n, i){
480
+ indexed_array[n['name']] = n['value'];
481
+ });
482
+
483
+ return indexed_array;
484
+ }
485
+
486
  function qmnFormSubmit( quiz_form_id ) {
487
  var quiz_id = +jQuery( '#' + quiz_form_id ).find( '.qmn_quiz_id' ).val();
488
  var $container = jQuery( '#' + quiz_form_id ).closest( '.qmn_quiz_container' );
495
  jQuery( '.mlw_qmn_quiz select' ).attr( 'disabled', false );
496
  jQuery( '.mlw_qmn_question_comment' ).attr( 'disabled', false );
497
  jQuery( '.mlw_answer_open_text' ).attr( 'disabled', false );
498
+
499
+ //Convert serialize data into index array
500
+ var unindexed_array = jQuery( '#' + quiz_form_id ).serializeArray();
501
+ var fd = new FormData();
502
+ jQuery.each(unindexed_array,function(key,input){
503
+ fd.append(input.name,input.value);
504
+ });
505
+ fd.append("action", 'qmn_process_quiz');
506
+
507
  qsmEndTimeTakenTimer();
 
508
  if ( qmn_quiz_data[quiz_id].hasOwnProperty( 'timer_limit' ) ) {
509
  QSM.endTimer( quiz_id );
510
  }
 
511
  jQuery( '#' + quiz_form_id + ' input[type=submit]' ).attr( 'disabled', 'disabled' );
512
  qsmDisplayLoading( $container );
513
+ jQuery.ajax({
514
+ url: qmn_ajax_object.ajaxurl,
515
+ data: fd,
516
+ contentType: false,
517
+ processData: false,
518
+ type: 'POST',
519
+ success: function( response ){
520
+ qmnDisplayResults( JSON.parse( response ), quiz_form_id, $container );
521
+ }
522
+ });
523
+
524
  return false;
525
  }
526
 
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: 6.4.3
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 6.4.3
13
  * @package QSM
14
  */
15
 
@@ -37,7 +37,7 @@ class MLWQuizMasterNext {
37
  * @var string
38
  * @since 4.0.0
39
  */
40
- public $version = '6.4.3';
41
 
42
  /**
43
  * 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: 6.4.4
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 6.4.4
13
  * @package QSM
14
  */
15
 
37
  * @var string
38
  * @since 4.0.0
39
  */
40
+ public $version = '6.4.4';
41
 
42
  /**
43
  * QSM Alert Manager Object
php/admin/addons-page.php CHANGED
@@ -134,6 +134,7 @@ add_action('plugins_loaded', 'qsm_featured_addons_tab');
134
  function qsm_display_optin_page() {
135
  global $mlwQuizMasterNext;
136
  wp_enqueue_script( 'qsm_admin_script', plugins_url( '../../js/admin.js', __FILE__ ), array( 'jquery' ), $mlwQuizMasterNext->version );
 
137
  ?>
138
  <div class="wrap about-wrap">
139
 
@@ -160,28 +161,161 @@ function qsm_display_optin_page() {
160
 
161
  <h2><?php esc_html_e('How to Get Your Free Addon', 'quiz-master-next'); ?></h2>
162
 
163
- <p><?php echo sprintf(__('Getting your addon is dead simple: just subscribe to our newsletter and then you will get the free addon by e-mail. We will not spam you. We usually send out newsletters to talk about new features in Awesome Support, let you know when new or updated addons are being released and provide informative articles that show you how to use Awesome Support to its full potential. <a href="%s" %s>View our privacy policy</a>', 'quiz-master-next'), 'https://quizandsurveymaster.com/privacy-policy/', 'target="_blank"'); ?></p>
164
 
165
  <div id="wpas-mailchimp-signup-form-wrapper">
166
  <div id="status"></div>
167
- <form id="sendySignupForm" action="http://sendy.expresstech.io/subscribe" method="POST" accept-charset="utf-8">
168
- <table class="form-table">
169
- <tr>
170
- <td class="row-title"><label for="name">First Name</label> <input type="text" name="name" id="name"/></td>
171
- <td class="row-title">
172
- <label for="email">Email Address</label>
173
- <input type="email" name="email" id="email"/>
174
- <div style="display:none;">
175
- <label for="hp">HP</label><br/>
176
- <input type="text" name="hp" id="hp"/>
177
- </div>
178
- <input type="hidden" name="list" value="4v8zvoyXyTHSS80jeavOpg"/>
179
- <input type="hidden" name="subform" value="yes"/>
180
- <input type="submit" name="submit" id="submit" value="Subscribe" class="button-secondary"/>
181
- </td>
182
- </tr>
183
- </table>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
184
  </form>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
185
  </div>
186
  </div>
187
 
134
  function qsm_display_optin_page() {
135
  global $mlwQuizMasterNext;
136
  wp_enqueue_script( 'qsm_admin_script', plugins_url( '../../js/admin.js', __FILE__ ), array( 'jquery' ), $mlwQuizMasterNext->version );
137
+ wp_localize_script( 'qsm_admin_script', 'qsmAdminObject', array( 'saveNonce' => wp_create_nonce('ajax-nonce-sendy-save') ) );
138
  ?>
139
  <div class="wrap about-wrap">
140
 
161
 
162
  <h2><?php esc_html_e('How to Get Your Free Addon', 'quiz-master-next'); ?></h2>
163
 
164
+ <p><?php echo sprintf(__('Getting your addon is dead simple: just subscribe to our newsletter and then you will get the free addon by e-mail. We will not spam you. We usually send out newsletters to talk about new features in <b>Quiz and Survey Master</b>, let you know when new or updated addons are being released and provide informative articles that show you how to use <b>Quiz and Survey Master</b> to its full potential. <a href="%s" %s>View our privacy policy</a>', 'quiz-master-next'), 'https://quizandsurveymaster.com/privacy-policy/', 'target="_blank"'); ?></p>
165
 
166
  <div id="wpas-mailchimp-signup-form-wrapper">
167
  <div id="status"></div>
168
+ <!-- Begin Sendinblue Form -->
169
+ <!-- START - We recommend to place the below code in head tag of your website html -->
170
+ <style>
171
+ @font-face {
172
+ font-display: block;
173
+ font-family: Roboto;
174
+ src: url(https://assets.sendinblue.com/font/Roboto/Latin/normal/normal/7529907e9eaf8ebb5220c5f9850e3811.woff2) format("woff2"), url(https://assets.sendinblue.com/font/Roboto/Latin/normal/normal/25c678feafdc175a70922a116c9be3e7.woff) format("woff")
175
+ }
176
+
177
+ @font-face {
178
+ font-display: fallback;
179
+ font-family: Roboto;
180
+ font-weight: 600;
181
+ src: url(https://assets.sendinblue.com/font/Roboto/Latin/medium/normal/6e9caeeafb1f3491be3e32744bc30440.woff2) format("woff2"), url(https://assets.sendinblue.com/font/Roboto/Latin/medium/normal/71501f0d8d5aa95960f6475d5487d4c2.woff) format("woff")
182
+ }
183
+
184
+ @font-face {
185
+ font-display: fallback;
186
+ font-family: Roboto;
187
+ font-weight: 700;
188
+ src: url(https://assets.sendinblue.com/font/Roboto/Latin/bold/normal/3ef7cf158f310cf752d5ad08cd0e7e60.woff2) format("woff2"), url(https://assets.sendinblue.com/font/Roboto/Latin/bold/normal/ece3a1d82f18b60bcce0211725c476aa.woff) format("woff")
189
+ }
190
+
191
+ #sib-container input:-ms-input-placeholder {
192
+ text-align: left;
193
+ font-family: "Helvetica", sans-serif;
194
+ color: #c0ccda;
195
+ border-width: px;
196
+ }
197
+
198
+ #sib-container input::placeholder {
199
+ text-align: left;
200
+ font-family: "Helvetica", sans-serif;
201
+ color: #c0ccda;
202
+ border-width: px;
203
+ }
204
+ </style>
205
+ <link rel="stylesheet" href="https://assets.sendinblue.com/component/form/2ef8d8058c0694a305b0.css">
206
+ <link rel="stylesheet" href="https://assets.sendinblue.com/component/clickable/b056d6397f4ba3108595.css">
207
+ <link rel="stylesheet" href="https://assets.sendinblue.com/component/progress-indicator/f86d65a4a9331c5e2851.css">
208
+ <link rel="stylesheet" href="https://sibforms.com/forms/end-form/build/sib-styles.css">
209
+ <!-- END - We recommend to place the above code in head tag of your website html -->
210
+
211
+ <!-- START - We recommend to place the below code where you want the form in your website html -->
212
+ <div class="sib-form" style="text-align: center;">
213
+ <div id="sib-form-container" class="sib-form-container">
214
+ <div id="error-message" class="sib-form-message-panel" style="font-size:16px; text-align:left; font-family:&quot;Helvetica&quot;, sans-serif; color:#661d1d; background-color:#ffeded; border-radius:3px; border-width:px; border-color:#ff4949;max-width:540px; border-width:px;">
215
+ <div class="sib-form-message-panel__text sib-form-message-panel__text--center">
216
+ <svg viewBox="0 0 512 512" class="sib-icon sib-notification__icon">
217
+ <path d="M256 40c118.621 0 216 96.075 216 216 0 119.291-96.61 216-216 216-119.244 0-216-96.562-216-216 0-119.203 96.602-216 216-216m0-32C119.043 8 8 119.083 8 256c0 136.997 111.043 248 248 248s248-111.003 248-248C504 119.083 392.957 8 256 8zm-11.49 120h22.979c6.823 0 12.274 5.682 11.99 12.5l-7 168c-.268 6.428-5.556 11.5-11.99 11.5h-8.979c-6.433 0-11.722-5.073-11.99-11.5l-7-168c-.283-6.818 5.167-12.5 11.99-12.5zM256 340c-15.464 0-28 12.536-28 28s12.536 28 28 28 28-12.536 28-28-12.536-28-28-28z"
218
+ />
219
+ </svg>
220
+ <span class="sib-form-message-panel__inner-text">
221
+ Your subscription could not be saved. Please try again.
222
+ </span>
223
+ </div>
224
+ </div>
225
+ <div></div>
226
+ <div id="success-message" class="sib-form-message-panel" style="font-size:16px; text-align:left; font-family:&quot;Helvetica&quot;, sans-serif; color:#085229; background-color:#e7faf0; border-radius:3px; border-width:px; border-color:#13ce66;max-width:540px; border-width:px;">
227
+ <div class="sib-form-message-panel__text sib-form-message-panel__text--center">
228
+ <svg viewBox="0 0 512 512" class="sib-icon sib-notification__icon">
229
+ <path d="M256 8C119.033 8 8 119.033 8 256s111.033 248 248 248 248-111.033 248-248S392.967 8 256 8zm0 464c-118.664 0-216-96.055-216-216 0-118.663 96.055-216 216-216 118.664 0 216 96.055 216 216 0 118.663-96.055 216-216 216zm141.63-274.961L217.15 376.071c-4.705 4.667-12.303 4.637-16.97-.068l-85.878-86.572c-4.667-4.705-4.637-12.303.068-16.97l8.52-8.451c4.705-4.667 12.303-4.637 16.97.068l68.976 69.533 163.441-162.13c4.705-4.667 12.303-4.637 16.97.068l8.451 8.52c4.668 4.705 4.637 12.303-.068 16.97z"
230
+ />
231
+ </svg>
232
+ <span class="sib-form-message-panel__inner-text">
233
+ Your subscription has been successful.
234
+ </span>
235
+ </div>
236
+ </div>
237
+ <div></div>
238
+ <div id="sib-container" class="sib-container--large sib-container--vertical" style="text-align:center; background-color:rgba(255,255,255,1); max-width:540px; border-radius:3px; border-width:1px; border-color:#C0CCD9; border-style:solid;">
239
+ <form id="sib-form" method="POST" action="https://cddf18fd.sibforms.com/serve/MUIEAO9t8eOB2GOqY73EWqFatPi328RiosfYMKieZ_8IxVL2jyEazmQ9LlkDj6pYrTlvB7JBsx3su8WdK5A4l445X0P-0r0Qf82LWXLSFa3yK0YZuypiIxy8hZfBXClZMANBeEVpBkswLw0RxDt2uWrN7B7zHTFXWY0W4mftpWo3Nqen7SQW1L9DYnXrex6lyw5EfHvZ3ZwsU6Xp"
240
+ data-type="subscription">
241
+ <div style="padding: 16px 0;">
242
+ <div class="sib-input sib-form-block">
243
+ <div class="form__entry entry_block">
244
+ <div class="form__label-row ">
245
+ <label class="entry__label" style="font-size:16px; text-align:left; font-weight:700; font-family:&quot;Helvetica&quot;, sans-serif; color:#3c4858; border-width:px;" for="EMAIL" data-required="*">
246
+ Enter your email address to subscribe
247
+ </label>
248
+
249
+ <div class="entry__field">
250
+ <input class="input" type="text" id="EMAIL" name="EMAIL" autocomplete="off" placeholder="EMAIL" data-required="true" required />
251
+ </div>
252
+ </div>
253
+
254
+ <label class="entry__error entry__error--primary" style="font-size:16px; text-align:left; font-family:&quot;Helvetica&quot;, sans-serif; color:#661d1d; background-color:#ffeded; border-radius:3px; border-width:px; border-color:#ff4949;">
255
+ </label>
256
+ <label class="entry__specification" style="font-size:12px; text-align:left; font-family:&quot;Helvetica&quot;, sans-serif; color:#8390A4; border-width:px;">
257
+ Provide your email address to subscribe. For e.g abc@xyz.com
258
+ </label>
259
+ </div>
260
+ </div>
261
+ </div>
262
+ <div style="padding: 16px 0;">
263
+ <div class="sib-form-block" style="text-align: left">
264
+ <button class="sib-form-block__button sib-form-block__button-with-loader" style="font-size:16px; text-align:left; font-weight:700; font-family:&quot;Helvetica&quot;, sans-serif; color:#FFFFFF; background-color:#3E4857; border-radius:3px; border-width:0px;"
265
+ form="sib-form" type="submit">
266
+ <svg class="icon clickable__icon progress-indicator__icon sib-hide-loader-icon" viewBox="0 0 512 512">
267
+ <path d="M460.116 373.846l-20.823-12.022c-5.541-3.199-7.54-10.159-4.663-15.874 30.137-59.886 28.343-131.652-5.386-189.946-33.641-58.394-94.896-95.833-161.827-99.676C261.028 55.961 256 50.751 256 44.352V20.309c0-6.904 5.808-12.337 12.703-11.982 83.556 4.306 160.163 50.864 202.11 123.677 42.063 72.696 44.079 162.316 6.031 236.832-3.14 6.148-10.75 8.461-16.728 5.01z"
268
+ />
269
+ </svg>
270
+ SUBSCRIBE
271
+ </button>
272
+ </div>
273
+ </div>
274
+ <div style="padding: 16px 0;">
275
+ <div class="sib-form-block" style="font-size:14px; text-align:center; font-family:&quot;Helvetica&quot;, sans-serif; color:#333; background-color:transparent; border-width:px;">
276
+ <div class="sib-text-form-block">
277
+ <p>
278
+ <a href="https://sendinblue.com" target="_blank">Terms &amp; Privacy policy</a>
279
+ </p>
280
+ </div>
281
+ </div>
282
+ </div>
283
+
284
+ <input type="text" name="email_address_check" value="" class="input--hidden">
285
+ <input type="hidden" name="locale" value="en">
286
  </form>
287
+ </div>
288
+ </div>
289
+ </div>
290
+ <!-- END - We recommend to place the below code where you want the form in your website html -->
291
+
292
+ <!-- START - We recommend to place the below code in footer or bottom of your website html -->
293
+ <script>
294
+ window.REQUIRED_CODE_ERROR_MESSAGE = 'Please choose a country code';
295
+
296
+ window.EMAIL_INVALID_MESSAGE = window.SMS_INVALID_MESSAGE = "The information provided is invalid. Please review the field format and try again.";
297
+
298
+ window.REQUIRED_ERROR_MESSAGE = "This field cannot be left blank. ";
299
+
300
+ window.GENERIC_INVALID_MESSAGE = "The information provided is invalid. Please review the field format and try again.";
301
+
302
+
303
+
304
+
305
+ window.translation = {
306
+ common: {
307
+ selectedList: '{quantity} list selected',
308
+ selectedLists: '{quantity} lists selected'
309
+ }
310
+ };
311
+
312
+ var AUTOHIDE = Boolean(0);
313
+ </script>
314
+ <script src="https://sibforms.com/forms/end-form/build/main.js">
315
+ </script>
316
+ <script src="https://www.google.com/recaptcha/api.js?hl=en"></script>
317
+ <!-- END - We recommend to place the above code in footer or bottom of your website html -->
318
+ <!-- End Sendinblue Form -->
319
  </div>
320
  </div>
321
 
php/admin/options-page-contact-tab.php CHANGED
@@ -29,7 +29,7 @@ function qsm_options_contact_tab_content() {
29
  $contact_form = QSM_Contact_Manager::load_fields();
30
 
31
  wp_enqueue_script( 'qsm_contact_admin_script', plugins_url( '../../js/qsm-admin-contact.js' , __FILE__ ), array( 'jquery-ui-sortable' ), $mlwQuizMasterNext->version );
32
- wp_localize_script( 'qsm_contact_admin_script', 'qsmContactObject', array( 'contactForm' => $contact_form, 'quizID' => $quiz_id ) );
33
  wp_enqueue_style( 'qsm_contact_admin_style', plugins_url( '../../css/qsm-admin-contact.css' , __FILE__ ), array(), $mlwQuizMasterNext->version );
34
 
35
  /**
@@ -67,6 +67,10 @@ add_action( 'wp_ajax_qsm_save_contact', 'qsm_contact_form_admin_ajax' );
67
  * @return void
68
  */
69
  function qsm_contact_form_admin_ajax() {
 
 
 
 
70
  global $wpdb;
71
  global $mlwQuizMasterNext;
72
  // Sends posted form data to Contact Manager to sanitize and save.
29
  $contact_form = QSM_Contact_Manager::load_fields();
30
 
31
  wp_enqueue_script( 'qsm_contact_admin_script', plugins_url( '../../js/qsm-admin-contact.js' , __FILE__ ), array( 'jquery-ui-sortable' ), $mlwQuizMasterNext->version );
32
+ wp_localize_script( 'qsm_contact_admin_script', 'qsmContactObject', array( 'contactForm' => $contact_form, 'quizID' => $quiz_id, 'saveNonce' => wp_create_nonce('ajax-nonce-contact-save') ) );
33
  wp_enqueue_style( 'qsm_contact_admin_style', plugins_url( '../../css/qsm-admin-contact.css' , __FILE__ ), array(), $mlwQuizMasterNext->version );
34
 
35
  /**
67
  * @return void
68
  */
69
  function qsm_contact_form_admin_ajax() {
70
+ $nonce = $_POST['nonce'];
71
+ if ( ! wp_verify_nonce( $nonce, 'ajax-nonce-contact-save' ) )
72
+ die ( 'Busted!');
73
+
74
  global $wpdb;
75
  global $mlwQuizMasterNext;
76
  // Sends posted form data to Contact Manager to sanitize and save.
php/admin/options-page-questions-tab.php CHANGED
@@ -38,7 +38,8 @@ function qsm_options_questions_tab_content() {
38
  'answerText' => __( 'Answer', 'quiz-master-next' ),
39
  'nonce' => wp_create_nonce( 'wp_rest' ),
40
  'pages' => $mlwQuizMasterNext->pluginHelper->get_quiz_setting( 'pages', array() ),
41
- 'qsm_user_ve' => get_user_meta($user_id, 'rich_editing', true)
 
42
  );
43
 
44
  // Scripts and styles.
@@ -299,6 +300,11 @@ add_action( 'wp_ajax_qsm_save_pages', 'qsm_ajax_save_pages' );
299
  * @since 5.2.0
300
  */
301
  function qsm_ajax_save_pages() {
 
 
 
 
 
302
  global $mlwQuizMasterNext;
303
  $json = array(
304
  'status' => 'error',
@@ -351,6 +357,11 @@ add_action( 'wp_ajax_qsm_send_data_sendy', 'qsm_send_data_sendy' );
351
  * Send data to sendy
352
  */
353
  function qsm_send_data_sendy(){
 
 
 
 
 
354
  $sendy_url = 'http://sendy.expresstech.io';
355
  $list = '4v8zvoyXyTHSS80jeavOpg';
356
  $name = sanitize_text_field($_POST['name']);
38
  'answerText' => __( 'Answer', 'quiz-master-next' ),
39
  'nonce' => wp_create_nonce( 'wp_rest' ),
40
  'pages' => $mlwQuizMasterNext->pluginHelper->get_quiz_setting( 'pages', array() ),
41
+ 'qsm_user_ve' => get_user_meta($user_id, 'rich_editing', true),
42
+ 'saveNonce' => wp_create_nonce('ajax-nonce-sandy-page')
43
  );
44
 
45
  // Scripts and styles.
300
  * @since 5.2.0
301
  */
302
  function qsm_ajax_save_pages() {
303
+
304
+ $nonce = $_POST['nonce'];
305
+ if ( ! wp_verify_nonce( $nonce, 'ajax-nonce-sandy-page' ) )
306
+ die ( 'Busted!');
307
+
308
  global $mlwQuizMasterNext;
309
  $json = array(
310
  'status' => 'error',
357
  * Send data to sendy
358
  */
359
  function qsm_send_data_sendy(){
360
+
361
+ $nonce = $_POST['nonce'];
362
+ if ( ! wp_verify_nonce( $nonce, 'ajax-nonce-sendy-save' ) )
363
+ die ( 'Busted!');
364
+
365
  $sendy_url = 'http://sendy.expresstech.io';
366
  $list = '4v8zvoyXyTHSS80jeavOpg';
367
  $name = sanitize_text_field($_POST['name']);
php/admin/quizzes-page.php CHANGED
@@ -76,20 +76,35 @@ function qsm_generate_quizzes_surveys_page() {
76
  $mlwQuizMasterNext->log_manager->add( 'Error resetting stats', $wpdb->last_error . ' from ' . $wpdb->last_query, 0, 'error' );
77
  }
78
  }
79
-
80
- // Load our quizzes.
81
- $quizzes = $mlwQuizMasterNext->pluginHelper->get_quizzes();
82
-
83
- // Load quiz posts.
84
- $post_to_quiz_array = array();
85
- $my_query = new WP_Query( array(
86
  'post_type' => 'quiz',
87
  'posts_per_page' => -1,
88
  'post_status' => array('publish', 'pending', 'draft', 'auto-draft', 'future', 'private')
89
- ));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
90
  if ( $my_query->have_posts() ) {
91
  while ( $my_query->have_posts() ) {
92
- $my_query->the_post();
93
  $post_to_quiz_array[ get_post_meta( get_the_ID(), 'quiz_id', true ) ] = array(
94
  'link' => get_the_permalink(get_the_ID()),
95
  'id' => get_the_ID(),
@@ -97,7 +112,7 @@ function qsm_generate_quizzes_surveys_page() {
97
  );
98
  }
99
  }
100
- wp_reset_postdata();
101
  $quiz_json_array = array();
102
  foreach ( $quizzes as $quiz ) {
103
  if ( ! isset( $post_to_quiz_array[ $quiz->quiz_id ] ) ) {
@@ -169,12 +184,45 @@ function qsm_generate_quizzes_surveys_page() {
169
  </div>
170
  </div>
171
  <table class="widefat">
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
172
  <thead>
173
  <tr>
174
- <th><?php esc_html_e( 'Name', 'quiz-master-next' ); ?></th>
 
 
 
 
 
175
  <th><?php esc_html_e( 'Shortcode', 'quiz-master-next' ); ?></th>
176
  <th><?php esc_html_e( 'Views/Taken', 'quiz-master-next' ); ?></th>
177
- <th><?php esc_html_e( 'Last Modified', 'quiz-master-next' ); ?></th>
 
 
 
 
 
178
  </tr>
179
  </thead>
180
  <tbody id="the-list">
@@ -182,10 +230,20 @@ function qsm_generate_quizzes_surveys_page() {
182
  </tbody>
183
  <tfoot>
184
  <tr>
185
- <th><?php esc_html_e( 'Name', 'quiz-master-next' ); ?></th>
 
 
 
 
 
186
  <th><?php esc_html_e( 'Shortcode', 'quiz-master-next' ); ?></th>
187
  <th><?php esc_html_e( 'Views/Taken', 'quiz-master-next' ); ?></th>
188
- <th><?php esc_html_e( 'Last Modified', 'quiz-master-next' ); ?></th>
 
 
 
 
 
189
  </tr>
190
  </tfoot>
191
  </table>
76
  $mlwQuizMasterNext->log_manager->add( 'Error resetting stats', $wpdb->last_error . ' from ' . $wpdb->last_query, 0, 'error' );
77
  }
78
  }
79
+
80
+ //Query for post
81
+ $post_arr = array(
 
 
 
 
82
  'post_type' => 'quiz',
83
  'posts_per_page' => -1,
84
  'post_status' => array('publish', 'pending', 'draft', 'auto-draft', 'future', 'private')
85
+ );
86
+ if(isset($_GET['order']) && $_GET['order'] == 'asc'){
87
+ $post_arr['orderby'] = isset($_GET['orderby']) && $_GET['orderby'] == 'title' ? 'title' : 'last_activity';
88
+ $post_arr['order'] = 'ASC';
89
+ // Load our quizzes.
90
+ $quizzes = $mlwQuizMasterNext->pluginHelper->get_quizzes(false, $post_arr['orderby'], 'ASC');
91
+ }else if( isset($_GET['order']) && $_GET['order'] == 'desc' ){
92
+ $post_arr['orderby'] = isset($_GET['orderby']) && $_GET['orderby'] == 'title' ? 'title' : 'last_activity';
93
+ $post_arr['order'] = 'DESC';
94
+ // Load our quizzes.
95
+ $quizzes = $mlwQuizMasterNext->pluginHelper->get_quizzes(false, $post_arr['orderby'], 'DESC');
96
+ } else{
97
+ // Load our quizzes.
98
+ $quizzes = $mlwQuizMasterNext->pluginHelper->get_quizzes();
99
+ }
100
+
101
+ // Load quiz posts.
102
+ $post_to_quiz_array = array();
103
+ $my_query = new WP_Query( $post_arr );
104
+
105
  if ( $my_query->have_posts() ) {
106
  while ( $my_query->have_posts() ) {
107
+ $my_query->the_post();
108
  $post_to_quiz_array[ get_post_meta( get_the_ID(), 'quiz_id', true ) ] = array(
109
  'link' => get_the_permalink(get_the_ID()),
110
  'id' => get_the_ID(),
112
  );
113
  }
114
  }
115
+ wp_reset_postdata();
116
  $quiz_json_array = array();
117
  foreach ( $quizzes as $quiz ) {
118
  if ( ! isset( $post_to_quiz_array[ $quiz->quiz_id ] ) ) {
184
  </div>
185
  </div>
186
  <table class="widefat">
187
+ <?php
188
+ $orderby_slug = '&orderby=title&order=asc';
189
+ $orderby_date_slug = '&orderby=date&order=asc';
190
+ $orderby_class = $orderby_date_class = 'sortable desc';
191
+ //Title order
192
+ if( isset($_GET['orderby']) && $_GET['orderby'] === 'title' ){
193
+ if(isset($_GET['order']) && $_GET['order'] === 'asc'){
194
+ $orderby_slug = '&orderby=title&order=desc';
195
+ $orderby_class = 'sorted asc';
196
+ }else if( isset($_GET['order']) && $_GET['order'] === 'desc' ){
197
+ $orderby_slug = '&orderby=title&order=asc';
198
+ $orderby_class = 'sorted desc';
199
+ }
200
+ } else if( isset($_GET['orderby']) && $_GET['orderby'] === 'date' ){
201
+ if(isset($_GET['order']) && $_GET['order'] === 'asc'){
202
+ $orderby_date_slug = '&orderby=date&order=desc';
203
+ $orderby_date_class = 'sorted asc';
204
+ }else if( isset($_GET['order']) && $_GET['order'] === 'desc' ){
205
+ $orderby_date_slug = '&orderby=date&order=asc';
206
+ $orderby_date_class = 'sorted desc';
207
+ }
208
+ }
209
+ ?>
210
  <thead>
211
  <tr>
212
+ <th class="<?php echo $orderby_class; ?>">
213
+ <a href="<?php echo '?page=' . QSM_PLUGIN_BASENAME . $orderby_slug; ?>">
214
+ <span><?php esc_html_e( 'Name', 'quiz-master-next' ); ?></span>
215
+ <span class="sorting-indicator"></span>
216
+ </a>
217
+ </th>
218
  <th><?php esc_html_e( 'Shortcode', 'quiz-master-next' ); ?></th>
219
  <th><?php esc_html_e( 'Views/Taken', 'quiz-master-next' ); ?></th>
220
+ <th class="<?php echo $orderby_date_class; ?>">
221
+ <a href="<?php echo '?page=' . QSM_PLUGIN_BASENAME . $orderby_date_slug; ?>">
222
+ <span><?php esc_html_e( 'Last Modified', 'quiz-master-next' ); ?></span>
223
+ <span class="sorting-indicator"></span>
224
+ </a>
225
+ </th>
226
  </tr>
227
  </thead>
228
  <tbody id="the-list">
230
  </tbody>
231
  <tfoot>
232
  <tr>
233
+ <th class="<?php echo $orderby_class; ?>">
234
+ <a href="<?php echo '?page=' . QSM_PLUGIN_BASENAME . $orderby_slug; ?>">
235
+ <span><?php esc_html_e( 'Name', 'quiz-master-next' ); ?></span>
236
+ <span class="sorting-indicator"></span>
237
+ </a>
238
+ </th>
239
  <th><?php esc_html_e( 'Shortcode', 'quiz-master-next' ); ?></th>
240
  <th><?php esc_html_e( 'Views/Taken', 'quiz-master-next' ); ?></th>
241
+ <th class="<?php echo $orderby_date_class; ?>">
242
+ <a href="<?php echo '?page=' . QSM_PLUGIN_BASENAME . $orderby_date_slug; ?>">
243
+ <span><?php esc_html_e( 'Last Modified', 'quiz-master-next' ); ?></span>
244
+ <span class="sorting-indicator"></span>
245
+ </a>
246
+ </th>
247
  </tr>
248
  </tfoot>
249
  </table>
php/classes/class-qmn-plugin-helper.php CHANGED
@@ -131,6 +131,10 @@ class QMNPluginHelper {
131
  case 'quiz_taken':
132
  $order_field = 'quiz_taken';
133
  break;
 
 
 
 
134
 
135
  default:
136
  $order_field = 'quiz_id';
131
  case 'quiz_taken':
132
  $order_field = 'quiz_taken';
133
  break;
134
+
135
+ case 'title':
136
+ $order_field = 'quiz_name';
137
+ break;
138
 
139
  default:
140
  $order_field = 'quiz_id';
php/classes/class-qmn-quiz-manager.php CHANGED
@@ -924,8 +924,8 @@ class QMNQuizManager {
924
  */
925
  public function ajax_submit_results() {
926
  global $qmn_allowed_visit;
927
- global $mlwQuizMasterNext;
928
- parse_str($_POST["quizData"], $_POST);
929
  $qmn_allowed_visit = true;
930
  $quiz = intval($_POST["qmn_quiz_id"]);
931
  $mlwQuizMasterNext->pluginHelper->prepare_quiz($quiz);
924
  */
925
  public function ajax_submit_results() {
926
  global $qmn_allowed_visit;
927
+ global $mlwQuizMasterNext;
928
+
929
  $qmn_allowed_visit = true;
930
  $quiz = intval($_POST["qmn_quiz_id"]);
931
  $mlwQuizMasterNext->pluginHelper->prepare_quiz($quiz);
readme.txt CHANGED
@@ -4,7 +4,7 @@ Tags: quiz, survey, lead, test, score, exam, questionnaire, question,wordpress q
4
  Requires at least: 4.9
5
  Tested up to: 5.3.2
6
  Requires PHP: 5.4
7
- Stable tag: 6.4.3
8
  License: GPLv2
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
@@ -82,6 +82,9 @@ While Quiz And Survey Master is fully functional and is packed full of features
82
  **About Us**
83
  QSM is a WordPress Quiz Plugin which is owned completely by [ExpressTech](https://expresstech.io)
84
 
 
 
 
85
  == Installation ==
86
 
87
  * Navigate to Add New Plugin page within your WordPress
@@ -118,6 +121,12 @@ This is usually a theme conflict. You can [checkout out our common conflict solu
118
 
119
  == Changelog ==
120
 
 
 
 
 
 
 
121
  = 6.4.3 (Feb 6, 2020)=
122
  * Bug: Solved user limit issue with ip address
123
  * Bug: Solved Search input issue on Quizzes/Surveys
4
  Requires at least: 4.9
5
  Tested up to: 5.3.2
6
  Requires PHP: 5.4
7
+ Stable tag: 6.4.4
8
  License: GPLv2
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
82
  **About Us**
83
  QSM is a WordPress Quiz Plugin which is owned completely by [ExpressTech](https://expresstech.io)
84
 
85
+ **Facebook Group**
86
+ Join our [offical FB group](https://www.facebook.com/groups/516958552587745) for quicker response time on your technical queries
87
+
88
  == Installation ==
89
 
90
  * Navigate to Add New Plugin page within your WordPress
121
 
122
  == Changelog ==
123
 
124
+ = 6.4.4 (Feb 24, 2020)=
125
+ * Bug: Security Issues reported by WORDFENCE
126
+ * Bug: Change text in Get a Free Addon page
127
+ * Feature: Change sendy to sendinblue in free addon page
128
+ * Feature: Added sorting functionality on name and last activity
129
+
130
  = 6.4.3 (Feb 6, 2020)=
131
  * Bug: Solved user limit issue with ip address
132
  * Bug: Solved Search input issue on Quizzes/Surveys
uninstall.php CHANGED
@@ -1,30 +1,42 @@
1
  <?php
2
- // If uninstall not called from WordPress, then exit
 
 
 
 
 
3
  if ( ! defined( 'WP_UNINSTALL_PLUGIN' ) ) {
4
  exit();
5
  }
6
 
7
  global $wpdb;
8
- $table_name = $wpdb->prefix . "mlw_results";
9
- $results = $wpdb->query( "DROP TABLE IF EXISTS $table_name" );
10
 
11
- $table_name = $wpdb->prefix . "mlw_quizzes";
12
- $results = $wpdb->query( "DROP TABLE IF EXISTS $table_name" );
13
 
14
- $table_name = $wpdb->prefix . "mlw_questions";
15
- $results = $wpdb->query( "DROP TABLE IF EXISTS $table_name" );
16
 
17
- $table_name = $wpdb->prefix . "mlw_qm_audit_trail";
18
- $results = $wpdb->query( "DROP TABLE IF EXISTS $table_name" );
19
 
20
  // Taken from Easy Digital Downloads. Much better way of doing it than I was doing :)
21
- // Cycle through custom post type array, retreive all posts, delete each one
22
  $qsm_post_types = array( 'quiz', 'qmn_log' );
23
  foreach ( $qsm_post_types as $post_type ) {
24
- $items = get_posts( array( 'post_type' => $post_type, 'post_status' => 'any', 'numberposts' => -1, 'fields' => 'ids' ) );
 
 
 
 
 
 
 
25
  if ( $items ) {
26
  foreach ( $items as $item ) {
27
- wp_delete_post( $item, true);
28
  }
29
  }
30
  }
@@ -35,4 +47,4 @@ delete_option( 'mlw_qmn_review_notice' );
35
  delete_option( 'mlw_advert_shows' );
36
  delete_option( 'qmn-settings' );
37
  delete_option( 'qmn-tracking-notice' );
38
- ?>
1
  <?php
2
+ /**
3
+ * If uninstall not called from WordPress, then exit.
4
+ *
5
+ * @package QSM
6
+ */
7
+
8
  if ( ! defined( 'WP_UNINSTALL_PLUGIN' ) ) {
9
  exit();
10
  }
11
 
12
  global $wpdb;
13
+ $table_name = $wpdb->prefix . 'mlw_results';
14
+ $results = $wpdb->query( "DROP TABLE IF EXISTS $table_name" );
15
 
16
+ $table_name = $wpdb->prefix . 'mlw_quizzes';
17
+ $results = $wpdb->query( "DROP TABLE IF EXISTS $table_name" );
18
 
19
+ $table_name = $wpdb->prefix . 'mlw_questions';
20
+ $results = $wpdb->query( "DROP TABLE IF EXISTS $table_name" );
21
 
22
+ $table_name = $wpdb->prefix . 'mlw_qm_audit_trail';
23
+ $results = $wpdb->query( "DROP TABLE IF EXISTS $table_name" );
24
 
25
  // Taken from Easy Digital Downloads. Much better way of doing it than I was doing :)
26
+ // Cycle through custom post type array, retreive all posts, delete each one.
27
  $qsm_post_types = array( 'quiz', 'qmn_log' );
28
  foreach ( $qsm_post_types as $post_type ) {
29
+ $items = get_posts(
30
+ array(
31
+ 'post_type' => $post_type,
32
+ 'post_status' => 'any',
33
+ 'numberposts' => -1,
34
+ 'fields' => 'ids',
35
+ )
36
+ );
37
  if ( $items ) {
38
  foreach ( $items as $item ) {
39
+ wp_delete_post( $item, true );
40
  }
41
  }
42
  }
47
  delete_option( 'mlw_advert_shows' );
48
  delete_option( 'qmn-settings' );
49
  delete_option( 'qmn-tracking-notice' );
50
+