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

Version Description

(May 28, 2021) = * Bug: Fixed the issue where page title shows Nan:Nan:Nan on reload. * Bug: Fixed the issue when editing duplicate questions updates original questions.

Download this release

Release Info

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

Code changes from version 7.1.16 to 7.1.17

js/qsm-quiz.js CHANGED
@@ -14,34 +14,34 @@ var QSMPageTimer;
14
  /**
15
  * Initializes all quizzes or surveys on the page
16
  */
17
- init: function() {
18
  // Makes sure we have quizzes on this page
19
- if ( typeof qmn_quiz_data != 'undefined' && qmn_quiz_data) {
20
  // hide the recaptcha by default
21
- $( '.g-recaptcha' ).hide();
22
  // Cycle through all quizzes
23
- _.each( qmn_quiz_data, function( quiz ) {
24
- quizID = parseInt( quiz.quiz_id );
25
- QSM.initPagination( quizID );
26
 
27
- if(quiz.hasOwnProperty('pagination') || quiz.qpages.hasOwnProperty(2)){
28
  qsmEndTimeTakenTimer();
29
- jQuery( '#timer' ).val(0);
30
  jQuery("input[name='timer_ms']").val(0);
31
  quizType = 'paginated';
32
  }
33
 
34
  if (qmn_quiz_data[quizID].hasOwnProperty('advanced_timer')) {
35
  qsmEndTimeTakenTimer();
36
- jQuery( '#timer' ).val(0);
37
  jQuery("input[name='timer_ms']").val(0);
38
  QSMPageTimer.endPageTimer(quizID, true);
39
  }
40
- if ( quiz.hasOwnProperty( 'timer_limit' ) && 0 != quiz.timer_limit ) {
41
  qsmEndTimeTakenTimer();
42
- jQuery( '#timer' ).val(0);
43
  jQuery("input[name='timer_ms']").val(0);
44
- QSM.initTimer( quizID );
45
  quizType = 'timer';
46
  }
47
  });
@@ -53,15 +53,15 @@ var QSMPageTimer;
53
  *
54
  * @param int quizID The ID of the quiz
55
  */
56
- initTimer: function( quizID ) {
57
-
58
- jQuery(document).trigger('qsm_init_timer_before', [quizID]);
59
-
60
  // Gets our form
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) {
@@ -71,36 +71,36 @@ var QSMPageTimer;
71
  $('#quizForm' + quizID).closest('.qmn_quiz_container').find('.mlw_next').on('click', function (event) {
72
  event.preventDefault();
73
  if (qmn_quiz_data[quizID].hasOwnProperty('advanced_timer')) {
74
- var start_timer = parseInt(qmn_quiz_data[quizID].advanced_timer.start_timer_page);
75
  if ($('#quizForm' + quizID).closest('.qmn_quiz_container').find('.qmn_pagination > .current_page_hidden').val() == start_timer) {
76
  QSM.activateTimer(quizID);
77
  $('#quizForm' + quizID).closest('.qmn_quiz_container').find('.stoptimer-p').show();
78
  }
79
  } else {
80
- if ( ! qmn_quiz_data[ quizID ].timerStatus && qmnValidatePage( 'quizForm' + quizID ) ) {
81
- QSM.activateTimer(quizID);
82
  $('#quizForm' + quizID).closest('.qmn_quiz_container').find('.stoptimer-p').show();
83
- }
84
- }
85
  });
86
- // ...else, activate the timer on page load.
87
  } else {
88
  QSM.activateTimer(quizID);
89
  $('#quizForm' + quizID).closest('.qmn_quiz_container').find('.stoptimer-p').show();
90
  }
91
- // ...else, we must be using the questions per page option.
92
  } else {
93
  if (qmn_quiz_data[quizID].hasOwnProperty('pagination') && qmn_quiz_data[quizID].first_page) {
94
  $('#quizForm' + quizID).closest('.qmn_quiz_container').find('.mlw_next').on('click', function (event) {
95
  event.preventDefault();
96
  if (qmn_quiz_data[quizID].hasOwnProperty('advanced_timer')) {
97
- var start_timer = parseInt(qmn_quiz_data[quizID].advanced_timer.start_timer_page);
98
  if ($('#quizForm' + quizID).closest('.qmn_quiz_container').find('.qmn_pagination > .slide_number_hidden').val() == start_timer) {
99
  QSM.activateTimer(quizID);
100
  $('#quizForm' + quizID).closest('.qmn_quiz_container').find('.stoptimer-p').show();
101
  }
102
  } else {
103
- if (!qmn_quiz_data[ quizID ].timerStatus && (0 == $('.quiz_begin:visible').length || (1 == $('.quiz_begin:visible').length && qmnValidatePage('quizForm' + quizID)))) {
104
  QSM.activateTimer(quizID);
105
  $('#quizForm' + quizID).closest('.qmn_quiz_container').find('.stoptimer-p').show();
106
  }
@@ -111,111 +111,114 @@ var QSMPageTimer;
111
  $('#quizForm' + quizID).closest('.qmn_quiz_container').find('.stoptimer-p').show();
112
  }
113
  }
114
- jQuery(document).trigger('qsm_init_timer_after', [quizID]);
115
  },
116
  /**
117
  * Starts the timer for the quiz.
118
  *
119
  * @param int quizID The ID of the quiz.
120
  */
121
- activateTimer: function( quizID ) {
122
  timer_ms = jQuery("input[name='timer_ms']").val();
123
- if(timer_ms == 0){
124
- qsmTimerInterval = setInterval( qmnTimeTakenTimer, 1000 );
125
- jQuery("input[name='timer_ms']").each(function(){
126
  var timems = qsmTimeInMS();
127
  jQuery(this).val(timems);
128
  });
129
  }
130
-
131
  jQuery(document).trigger('qsm_activate_time_before', [quizID, qmn_quiz_data]);
132
  // Gets our form.
133
- var $timer = QSM.getTimer( quizID );
134
 
135
  // Sets up our variables.
136
- qmn_quiz_data[ quizID ].timerStatus = true;
137
  var seconds = 0;
138
 
139
  // Calculates starting time.
140
- var timerStarted = localStorage.getItem( 'mlw_started_quiz' + quizID );
141
- var timerRemaning = localStorage.getItem( 'mlw_time_quiz' + quizID );
142
- if ( 'yes' == timerStarted && 0 < timerRemaning ) {
143
- seconds = parseInt( timerRemaning );
144
  } else {
145
- seconds = parseFloat( qmn_quiz_data[ quizID ].timer_limit ) * 60;
146
  }
147
- qmn_quiz_data[ quizID ].timerRemaning = seconds;
148
 
149
- //hidden timer
150
- jQuery(".hiddentimer").html(seconds);
151
 
152
  // Makes the timer appear.
153
  $timer.show();
154
- $timer.text( QSM.secondsToTimer( seconds ) );
155
 
156
  // Sets up timer interval.
157
- qmn_quiz_data[ quizID ].timerInterval = setInterval( QSM.timer, 1000, quizID );
158
- jQuery(document).trigger('qsm_activate_time_after', [quizID, qmn_quiz_data]);
 
 
 
159
  },
160
  /**
161
  * Reduces the timer by one second and checks if timer is 0
162
  *
163
  * @param int quizID The ID of the quiz.
164
  */
165
- timer: function( quizID ) {
166
- qmn_quiz_data[ quizID ].timerRemaning -= 1;
167
- if ( 0 > qmn_quiz_data[ quizID ].timerRemaning ) {
168
- qmn_quiz_data[ quizID ].timerRemaning = 0;
169
  }
170
- var secondsRemaining = qmn_quiz_data[ quizID ].timerRemaning;
171
- var display = QSM.secondsToTimer( secondsRemaining );
172
 
173
  // Sets our local storage values for the timer being started and current timer value.
174
- localStorage.setItem( 'mlw_time_quiz' + quizID, secondsRemaining );
175
- localStorage.setItem( 'mlw_started_quiz' + quizID, "yes" );
176
 
177
  // Updates timer element and title on browser tab.
178
- var $timer = QSM.getTimer( quizID );
179
- $timer.text( display );
180
  document.title = display + ' ' + qsmTitleText;
181
 
182
  /*CUSTOM TIMER*/
183
- if(qmn_quiz_data[quizID].hasOwnProperty('advanced_timer') && qmn_quiz_data[quizID].advanced_timer.timer_design == 'big_timer'){
184
  $(".second.circle").parent('.mlw_quiz_form').addClass('qsm_big_timer');
185
  $(".second.circle").show();
186
  $(".second.circle strong").html(display);
187
- var datashow =( $(".hiddentimer").html() - secondsRemaining ) / $(".hiddentimer").html();
188
  $(".second.circle").circleProgress({
189
  startAngle: 11,
190
  value: datashow,
191
  animation: false,
192
- fill: {gradient: ["#00bb40", "#00511c"]}
193
  });
194
  }
195
 
196
- var $quizForm = QSM.getQuizForm( quizID );
197
- var total_seconds = parseFloat( qmn_quiz_data[ quizID ].timer_limit ) * 60;
198
- var ninety_sec = total_seconds - ( total_seconds * 90 / 100 );
199
- if(ninety_sec == secondsRemaining){
200
- $quizForm.closest( '.qmn_quiz_container' ).find('.qsm_ninety_warning').fadeIn();
201
  }
202
 
203
  // If timer is run out, disable fields.
204
- if ( 0 >= secondsRemaining ) {
205
- clearInterval( qmn_quiz_data[ quizID ].timerInterval );
206
- $( ".mlw_qmn_quiz input:radio" ).attr( 'disabled', true );
207
- $( ".mlw_qmn_quiz input:checkbox" ).attr( 'disabled', true );
208
- $( ".mlw_qmn_quiz select" ).attr( 'disabled', true );
209
- $( ".mlw_qmn_question_comment" ).attr( 'disabled', true );
210
- $( ".mlw_answer_open_text" ).attr( 'disabled', true );
211
- $( ".mlw_answer_number" ).attr( 'readonly', true );
212
-
213
- $quizForm.closest( '.qmn_quiz_container' ).addClass( 'qsm_timer_ended' );
214
- $quizForm.closest( '.qmn_quiz_container' ).prepend('<p style="color: red;">Quiz time is over</p>');
215
- if(qmn_quiz_data[ quizID ].enable_result_after_timer_end == 1){
216
- $quizForm.closest( '.qmn_quiz_container' ).find('.qsm-submit-btn').trigger('click');
217
- }else{
218
- MicroModal.show( 'modal-3' );
219
  }
220
  return;
221
  }
@@ -225,14 +228,14 @@ var QSMPageTimer;
225
  *
226
  * @param int quizID The ID of the quiz
227
  */
228
- endTimer: function( quizID ) {
229
- localStorage.setItem( 'mlw_time_quiz' + quizID, 'completed' );
230
- localStorage.setItem( 'mlw_started_quiz' + quizID, 'no' );
231
  document.title = qsmTitleText;
232
- if ( typeof qmn_quiz_data[ quizID ].timerInterval != 'undefined' ) {
233
- clearInterval( qmn_quiz_data[ quizID ].timerInterval );
234
  }
235
- jQuery(document).trigger('qsm_end_timer', [quizID, qmn_quiz_data]);
236
  },
237
  /**
238
  * Converts seconds to 00:00:00 format
@@ -240,35 +243,35 @@ var QSMPageTimer;
240
  * @param int seconds The number of seconds
241
  * @return string A string in H:M:S format
242
  */
243
- secondsToTimer: function( seconds ) {
244
  var formattedTime = '';
245
- seconds = parseInt( seconds );
246
 
247
  // Prepares the hours part.
248
- var hours = Math.floor( seconds / 3600 );
249
- if ( 0 === hours) {
250
  formattedTime = '00:';
251
- } else if ( 10 > hours ) {
252
  formattedTime = '0' + hours + ':';
253
  } else {
254
  formattedTime = hours + ':';
255
  }
256
 
257
  // Prepares the minutes part.
258
- var minutes = Math.floor( ( seconds % 3600 ) / 60 );
259
- if ( 0 === minutes) {
260
  formattedTime = formattedTime + '00:';
261
- } else if ( 10 > minutes ) {
262
  formattedTime = formattedTime + '0' + minutes + ':';
263
  } else {
264
  formattedTime = formattedTime + minutes + ':';
265
  }
266
 
267
  // Prepares the seconds part.
268
- var remainder = Math.floor( ( seconds % 60 ) );
269
- if ( 0 === remainder) {
270
  formattedTime = formattedTime + '00';
271
- } else if ( 10 > remainder ) {
272
  formattedTime = formattedTime + '0' + remainder;
273
  } else {
274
  formattedTime = formattedTime + remainder;
@@ -278,77 +281,77 @@ var QSMPageTimer;
278
  /**
279
  * Gets the jQuery object for the timer
280
  */
281
- getTimer: function( quizID ) {
282
- var $quizForm = QSM.getQuizForm( quizID );
283
- return $quizForm.children( '.mlw_qmn_timer' );
284
  },
285
  /**
286
  * Sets up pagination for a quiz
287
  *
288
  * @param int quizID The ID of the quiz.
289
  */
290
- initPagination: function( quizID ) {
291
- var $quizForm = QSM.getQuizForm( quizID );
292
- if ( 0 < $quizForm.children( '.qsm-page' ).length ) {
293
- $quizForm.children( '.qsm-page' ).hide();
294
- template = wp.template( 'qsm-pagination-'+quizID );
295
- $quizForm.append( template() );
296
- if( $quizForm.find( '.qsm-pagination > .current_page_hidden' ).length == 0){
297
- $quizForm.find( '.qsm-pagination' ).append( '<input type="hidden" value="0" name="current_page" class="current_page_hidden" />');
298
  }
299
- if ( '1' == qmn_quiz_data[ quizID ].progress_bar ) {
300
- jQuery(document).trigger('qsm_init_progressbar_before', [quizID, qmn_quiz_data]);
301
  $('#quizForm' + quizID).find('.qsm-progress-bar').show();
302
- qmn_quiz_data[ quizID ].bar = new ProgressBar.Line('#quizForm' + quizID + ' .qsm-progress-bar', {
303
  strokeWidth: 2,
304
  easing: 'easeInOut',
305
  duration: 1400,
306
  color: '#3498db',
307
  trailColor: '#eee',
308
  trailWidth: 1,
309
- svgStyle: {width: '100%', height: '100%'},
310
  text: {
311
- style: {
312
- // color: '#999',
313
- position: 'absolute',
314
- padding: 0,
315
- margin: 0,
316
- top: 0,
317
- right: '10px',
318
- 'font-size': '13px',
319
- 'font-weight': 'bold',
320
- transform: null
321
- },
322
- autoStyleContainer: false
323
  },
324
- from: {color: '#3498db'},
325
- to: {color: '#ED6A5A'},
326
- step: function(state, bar) {
327
  //bar.setText(Math.round(bar.value() * 100) + ' %');
328
  }
329
  });
330
- jQuery(document).trigger('qsm_init_progressbar_after', [quizID, qmn_quiz_data]);
331
  }
332
- QSM.goToPage( quizID, 1 );
333
- $quizForm.find( '.qsm-pagination .qsm-next' ).on( 'click', function( event ) {
334
- jQuery(document).trigger('qsm_next_button_click_before', [quizID]);
335
  event.preventDefault();
336
- QSM.nextPage( quizID );
337
- var $container = jQuery( '#quizForm' + quizID ).closest( '.qmn_quiz_container' );
338
- if( qmn_quiz_data[ quizID ].disable_scroll_next_previous_click != 1 ){
339
- qsmScrollTo( $container );
340
- }
341
- jQuery(document).trigger('qsm_next_button_click_after', [quizID]);
342
  });
343
- $quizForm.find( '.qsm-pagination .qsm-previous' ).on( 'click', function( event ) {
344
- jQuery(document).trigger('qsm_previous_button_click_before', [quizID]);
345
  event.preventDefault();
346
- QSM.prevPage( quizID );
347
- var $container = jQuery( '#quizForm' + quizID ).closest( '.qmn_quiz_container' );
348
- if( qmn_quiz_data[ quizID ].disable_scroll_next_previous_click != 1 ){
349
- qsmScrollTo( $container );
350
- }
351
- jQuery(document).trigger('qsm_previous_button_click_after', [quizID]);
352
  });
353
  }
354
  },
@@ -357,11 +360,11 @@ var QSMPageTimer;
357
  *
358
  * @param int pageNumber The number of the page
359
  */
360
- goToPage: function( quizID, pageNumber ) {
361
- jQuery(document).trigger('qsm_go_to_page_before', [quizID, pageNumber]);
362
- var $quizForm = QSM.getQuizForm( quizID );
363
- var $pages = $quizForm.children( '.qsm-page' );
364
- var $currentPage = $quizForm.children( '.qsm-page:nth-of-type(' + pageNumber + ')' );
365
  $pages.hide();
366
  $currentPage.show();
367
 
@@ -370,53 +373,53 @@ var QSMPageTimer;
370
  QSMPageTimer.initPageTimer(quizID, $currentPage);
371
  }
372
 
373
- $quizForm.find('.current_page_hidden').val( pageNumber - 1 );
374
- $quizForm.find( '.qsm-previous' ).hide();
375
- $quizForm.find( '.qsm-next' ).hide();
376
- $quizForm.find( '.qsm-submit-btn' ).hide();
377
- $quizForm.find( '.g-recaptcha' ).hide();
378
- if ( pageNumber < $pages.length ) {
379
- $quizForm.find( '.qsm-next' ).show();
380
  } else {
381
- $quizForm.find( '.qsm-submit-btn' ).show();
382
- $quizForm.find( '.g-recaptcha' ).show();
383
  }
384
- if ( 1 < pageNumber ) {
385
- $quizForm.find( '.qsm-previous' ).show();
386
  }
387
  if (1 == $currentPage.data('prevbtn')) {
388
- $quizForm.find( '.qsm-previous' ).hide();
389
  }
390
- if ( '1' == qmn_quiz_data[ quizID ].progress_bar ) {
391
- var current_page = jQuery('#quizForm' + quizID).find('.current_page_hidden').val();
392
- var total_page_length = $pages.length - 1;
393
- if( qmn_quiz_data[ quizID ].contact_info_location == 0 ){
394
- //Do nothing.
395
- }else if( qmn_quiz_data[ quizID ].contact_info_location == 1 ){
396
- if($quizForm.children( '.qsm-page' ).find('.qsm_contact_div ').length > 0){
397
- //total_page_length = total_page_length - 1;
398
- }
399
- }
400
- var animate_value = current_page / total_page_length;
401
- if( animate_value <= 1){
402
- qmn_quiz_data[ quizID ].bar.animate( animate_value );
403
- var old_text = jQuery( '#quizForm' + quizID ).find( '.progressbar-text' ).text().replace(' %', '');
404
- var new_text = Math.round(animate_value * 100);
405
- jQuery({
406
- Counter: old_text
407
- }).animate({
408
- Counter: new_text
409
- }, {
410
- duration: 1000,
411
- easing: 'swing',
412
- step: function () {
413
- jQuery( '#quizForm' + quizID ).find( '.progressbar-text' ).text(Math.round(this.Counter) + ' %');
414
- }
415
- });
416
- }
417
  }
418
- QSM.savePage( quizID, pageNumber );
419
- jQuery(document).trigger('qsm_go_to_page_after', [quizID, pageNumber]);
420
  },
421
  /**
422
  * Moves forward or backwards through the pages
@@ -424,25 +427,25 @@ var QSMPageTimer;
424
  * @param int quizID The ID of the quiz
425
  * @param int difference The number of pages to forward or back
426
  */
427
- changePage: function( quizID, difference ) {
428
- var page = QSM.getPage( quizID );
429
  page += difference;
430
- QSM.goToPage( quizID, page );
431
  },
432
- nextPage: function( quizID ) {
433
- if ( qmnValidatePage( 'quizForm' + quizID ) ) {
434
- QSM.changePage( quizID, 1 );
435
  }
436
  },
437
- prevPage: function( quizID ) {
438
- QSM.changePage( quizID, -1 );
439
  },
440
- savePage: function( quizID, pageNumber ) {
441
- sessionStorage.setItem( 'quiz' + quizID + 'page', pageNumber );
442
  },
443
- getPage: function( quizID ) {
444
- pageNumber = parseInt( sessionStorage.getItem( 'quiz' + quizID + 'page' ) );
445
- if ( isNaN( pageNumber ) || null == pageNumber ) {
446
  pageNumber = 1;
447
  }
448
  return pageNumber;
@@ -452,18 +455,18 @@ var QSMPageTimer;
452
  *
453
  * @param jQueryObject The jQuery version of an element. i.e. $('#quizForm3')
454
  */
455
- scrollTo: function( $element ) {
456
- jQuery( 'html, body' ).animate(
457
  {
458
  scrollTop: $element.offset().top - 150
459
  },
460
- 1000 );
461
  },
462
  /**
463
  * Gets the jQuery object of the quiz form
464
  */
465
- getQuizForm: function( quizID ) {
466
- return $( '#quizForm' + quizID );
467
  }
468
  };
469
 
@@ -472,11 +475,11 @@ var QSMPageTimer;
472
  * Init Page Timer
473
  */
474
  initPageTimer: function (quizID, $currentpage) {
475
- jQuery(document).trigger('qsm_init_page_timer_before', [quizID, $currentpage]);
476
  var $quizForm = QSM.getQuizForm(quizID);
477
  var pid = $currentpage.data('pid');
478
  if (undefined != pid) {
479
- var $qpages = qmn_quiz_data[ quizID ].qpages;
480
  var $curr_page_opt = $qpages[pid];
481
  if ($curr_page_opt.hasOwnProperty('pagetimer') && 0 != $curr_page_opt.pagetimer) {
482
  var $timer_box = $currentpage.find('.qsm-pagetimer');
@@ -495,14 +498,14 @@ var QSMPageTimer;
495
  seconds = parseFloat($curr_page_opt.pagetimer) * 60;
496
  }
497
  }
498
- qmn_quiz_data[ quizID ].qpages[ pid ].timerRemaning = seconds;
499
  /* Makes the timer appear. */
500
  $timer_box.show();
501
  $timer_box.text(QSMPageTimer.secondsToTimer(seconds));
502
  /* Sets up timer interval. */
503
- qmn_quiz_data[ quizID ].qpages[ pid ].timerInterval = setInterval(QSMPageTimer.timer, 1000, quizID, pid, $timer_box);
504
  }
505
- $currentpage.find('.page_intro_wrapper video').each(function(){
506
  var $this = jQuery(this);
507
  var src = $this.find('source').attr('src');
508
  $this.attr('src', src)
@@ -510,7 +513,7 @@ var QSMPageTimer;
510
  $this.get(0).play();
511
  });
512
  }
513
- jQuery(document).trigger('qsm_init_page_timer_after',[quizID, $currentpage]);
514
  },
515
  /**
516
  * Reduces the timer by one second and checks if timer is 0
@@ -518,17 +521,17 @@ var QSMPageTimer;
518
  */
519
  timer: function (quizID, pid, $timer_box) {
520
  var $quizForm = QSM.getQuizForm(quizID);
521
- var $page = qmn_quiz_data[ quizID ].qpages[pid];
522
- qmn_quiz_data[ quizID ].qpages[ pid ].timerRemaning -= 1;
523
- if (0 > qmn_quiz_data[ quizID ].qpages[ pid ].timerRemaning) {
524
- qmn_quiz_data[ quizID ].qpages[ pid ].timerRemaning = 0;
525
  }
526
  var total_seconds = parseFloat($page.pagetimer) * 60;
527
- var secondsRemaining = qmn_quiz_data[ quizID ].qpages[ pid ].timerRemaning;
528
  var display = QSMPageTimer.secondsToTimer(secondsRemaining);
529
  $timer_box.text(display);
530
  var pageTimeTaken = total_seconds - secondsRemaining;
531
- jQuery('#pagetime_'+pid).val(pageTimeTaken);
532
  /* Sets our local storage values for the timer being started and current timer value. */
533
  localStorage.setItem('mlw_started_q' + quizID + '_page' + pid, "yes");
534
  localStorage.setItem('mlw_time_q' + quizID + '_page' + pid, secondsRemaining);
@@ -540,7 +543,7 @@ var QSMPageTimer;
540
  }
541
  /* If timer is run out, disable fields. */
542
  if (0 >= secondsRemaining) {
543
- clearInterval(qmn_quiz_data[ quizID ].qpages[ pid ].timerInterval);
544
 
545
  $(".qsm-page:visible input:radio").attr('disabled', true);
546
  $(".qsm-page:visible input:checkbox").attr('disabled', true);
@@ -566,11 +569,11 @@ var QSMPageTimer;
566
  localStorage.removeItem('mlw_stoped_q' + quizID + '_page' + value.id);
567
  localStorage.removeItem('mlw_time_q' + quizID + '_page' + value.id);
568
  }
569
- var secondsRemaining = qmn_quiz_data[ quizID ].qpages[ value.id ].timerRemaning;
570
  localStorage.setItem('mlw_stoped_q' + quizID + '_page' + value.id, secondsRemaining);
571
  localStorage.setItem('mlw_time_q' + quizID + '_page' + value.id, 'completed');
572
- if (typeof qmn_quiz_data[ quizID ].qpages[ value.id ].timerInterval != 'undefined') {
573
- clearInterval(qmn_quiz_data[ quizID ].qpages[ value.id ].timerInterval);
574
  }
575
  }
576
  });
@@ -612,7 +615,7 @@ var QSMPageTimer;
612
  }
613
 
614
  // On load code
615
- $(function() {
616
 
617
  // Legacy init.
618
  qmnInit();
@@ -620,12 +623,12 @@ var QSMPageTimer;
620
  // Call main initialization.
621
  qsminstance = QSM.init();
622
 
623
- jQuery(".qsm-quiz-container").on("click", ".mlw_next", function(){
624
- if(quizType == 'paginated'){
625
  timer_ms = jQuery("input[name='timer_ms']").val();
626
- if(timer_ms == 0){
627
- qsmTimerInterval = setInterval( qmnTimeTakenTimer, 1000 );
628
- jQuery("input[name='timer_ms']").each(function(){
629
  var timems = qsmTimeInMS();
630
  jQuery(this).val(timems);
631
  });
@@ -634,7 +637,7 @@ var QSMPageTimer;
634
  });
635
  });
636
 
637
- jQuery("input[name='timer_ms']").each(function(){
638
  var timems = qsmTimeInMS();
639
  jQuery(this).val(timems);
640
  });
@@ -649,11 +652,11 @@ var qsmTitleText = document.title;
649
  * @param email The Email Id to validate.
650
  * @returns Boolean
651
  */
652
- function isEmail( email ) {
653
  var regex = /^([a-zA-Z0-9_\.\-\+])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/;
654
- if( ! regex.test( email ) ) {
655
  return false;
656
- }else{
657
  return true;
658
  }
659
  }
@@ -663,29 +666,29 @@ function isEmail( email ) {
663
  * Limit multiple response based on question limit
664
  * @returns {undefined}
665
  */
666
- function qsmCheckMR(event, limit){
667
- var checked = jQuery(event).parents('.quiz_section').find(':checkbox:checked').length;
668
- if (checked > limit) {
669
- event.checked = false;
670
- if( jQuery(event).parents('.quiz_section').find('.multi-checkbox-limit-reach').length == 0 ){
671
- jQuery(event).parents('.quiz_section').append('<span class="multi-checkbox-limit-reach">'+ qmn_ajax_object.multicheckbox_limit_reach +'</span>');
672
- }
673
- } else {
674
- jQuery(event).parents('.quiz_section').find('.multi-checkbox-limit-reach').remove();
675
- }
676
  }
677
 
678
  function qmnTimeTakenTimer() {
679
- var x = +jQuery( '#timer' ).val();
680
- if ( NaN === x ) {
681
  x = 0;
682
  }
683
  x = x + 1;
684
- jQuery( '#timer' ).val( x );
685
  }
686
 
687
  function qsmEndTimeTakenTimer() {
688
- clearInterval( qsmTimerInterval );
689
  }
690
 
691
  function qsmTimeInMS() {
@@ -694,220 +697,221 @@ function qsmTimeInMS() {
694
  return n;
695
  }
696
 
697
- function qmnClearField( field ) {
698
- if ( field.defaultValue == field.value ) field.value = '';
699
  }
700
 
701
- function qsmScrollTo( $element ) {
702
- if($element.length > 0){
703
- jQuery(document).trigger('qsm_scroll_to_top_before', [$element]);
704
- jQuery( 'html, body' ).animate( { scrollTop: $element.offset().top - 150 }, 1000 );
705
- jQuery(document).trigger('qsm_scroll_to_top_after', [$element]);
706
- }
707
  }
708
 
709
- function qmnDisplayError( message, field, quiz_form_id ) {
710
- jQuery( '#' + quiz_form_id + ' .qmn_error_message_section' ).addClass( 'qmn_error_message' );
711
- jQuery( '#' + quiz_form_id + ' .qmn_error_message' ).text( message );
712
- field.closest( '.quiz_section' ).addClass( 'qmn_error' );
713
  }
714
 
715
- function qmnResetError( quiz_form_id ) {
716
- jQuery( '#' + quiz_form_id + ' .qmn_error_message' ).text( '' );
717
- jQuery( '#' + quiz_form_id + ' .qmn_error_message_section' ).removeClass( 'qmn_error_message' );
718
- jQuery( '#' + quiz_form_id + ' .quiz_section' ).removeClass( 'qmn_error' );
719
  }
720
 
721
- function qmnValidation( element, quiz_form_id ) {
722
- jQuery(document).trigger('qsm_before_validation', [element, quiz_form_id]);
723
  var result = true;
724
- var quiz_id = +jQuery( '#' + quiz_form_id ).find( '.qmn_quiz_id' ).val();
725
- var email_error = qmn_quiz_data[ quiz_id ].error_messages.email;
726
- var number_error = qmn_quiz_data[ quiz_id ].error_messages.number;
727
- var empty_error = qmn_quiz_data[ quiz_id ].error_messages.empty;
728
- var incorrect_error = qmn_quiz_data[ quiz_id ].error_messages.incorrect;
729
- qmnResetError( quiz_form_id );
730
- jQuery( element ).each(function(){
731
- if ( jQuery( this ).attr( 'class' )) {
732
- if( jQuery( this ).attr( 'class' ).indexOf( 'mlwEmail' ) !== -1 && this.value !== "" ) {
733
  // Remove any trailing and preceeding space.
734
- var x = jQuery.trim( this.value );
735
- if ( ! isEmail( x ) ) {
736
- qmnDisplayError( email_error, jQuery( this ), quiz_form_id );
737
  result = false;
738
  }
739
  }
740
- var by_pass = true;
741
- if( qmn_quiz_data[ quizID ].timer_limit_val > 0 && qmn_quiz_data[quiz_id].hasOwnProperty('skip_validation_time_expire') && qmn_quiz_data[quiz_id].skip_validation_time_expire == 0 ){
742
- by_pass = false;
743
- }
744
-
745
- if ( localStorage.getItem( 'mlw_time_quiz' + quiz_id ) === null || localStorage.getItem( 'mlw_time_quiz'+quiz_id ) > 0.08 || by_pass === false ) {
746
-
747
- if( jQuery( this ).attr( 'class' ).indexOf( 'mlwRequiredNumber' ) > -1 && this.value === "" && +this.value != NaN ) {
748
- qmnDisplayError( number_error, jQuery( this ), quiz_form_id );
749
- result = false;
 
 
 
 
750
  }
751
- if( jQuery( this ).attr( 'class' ).indexOf( 'mlwRequiredDate' ) > -1 && this.value === "" ) {
752
- qmnDisplayError( empty_error, jQuery( this ), quiz_form_id );
753
- result = false;
754
  }
755
- if( jQuery( this ).attr( 'class' ).indexOf( 'mlwRequiredText' ) > -1 && jQuery.trim(this.value) === "" ) {
756
- qmnDisplayError( empty_error, jQuery( this ), quiz_form_id );
757
- result = false;
758
  }
759
- if( jQuery( this ).attr( 'class' ).indexOf( 'mlwRequiredCaptcha' ) > -1 && this.value != mlw_code ) {
760
- qmnDisplayError( incorrect_error, jQuery( this ), quiz_form_id );
761
- result = false;
762
  }
763
- if( jQuery( this ).attr( 'class' ).indexOf( 'mlwRequiredAccept' ) > -1 && ! jQuery( this ).prop( 'checked' ) ) {
764
- qmnDisplayError( empty_error, jQuery( this ), quiz_form_id );
765
- result = false;
766
- }
767
- if( jQuery( this ).attr( 'class' ).indexOf( 'mlwRequiredRadio' ) > -1 ) {
768
- check_val = jQuery( this ).find( 'input:checked' ).val();
769
- if ( check_val == "No Answer Provided" || check_val == "" ) {
770
- qmnDisplayError( empty_error, jQuery( this ), quiz_form_id );
771
- result = false;
772
  }
773
  }
774
- if( jQuery( this ).attr( 'class' ).indexOf( 'mlwRequiredFileUpload' ) > -1 ) {
775
- var selected_file = jQuery( this ).get(0).files.length;
776
- if ( selected_file === 0 ) {
777
- qmnDisplayError( empty_error, jQuery( this ), quiz_form_id );
778
- result = false;
779
  }
780
  }
781
- if( jQuery( this ).attr( 'class' ).indexOf( 'qsmRequiredSelect' ) > -1 ) {
782
- check_val = jQuery( this ).val();
783
- if ( check_val == "No Answer Provided" || check_val == "" ) {
784
- qmnDisplayError( empty_error, jQuery( this ), quiz_form_id );
785
- result = false;
786
  }
787
  }
788
- if( jQuery( this ).attr( 'class' ).indexOf( 'mlwRequiredCheck' ) > -1 ) {
789
- if ( ! jQuery( this ).find( 'input:checked' ).length ) {
790
- qmnDisplayError( empty_error, jQuery( this ), quiz_form_id );
791
- result = false;
792
  }
793
  }
794
- //Google recaptcha validation
795
- if( jQuery( this ).attr( 'class' ).indexOf( 'g-recaptcha-response' ) > -1 ) {
796
- if(grecaptcha.getResponse() == "") {
797
  alert('ReCaptcha is missing');
798
- result = false;
799
  }
800
  }
801
  }
802
  }
803
  });
804
- jQuery(document).trigger('qsm_after_validation', [element, quiz_form_id]);
805
  return result;
806
  }
807
 
808
- function getFormData($form){
809
- var unindexed_array = $form.serializeArray();
810
- var indexed_array = {};
811
 
812
- jQuery.map(unindexed_array, function(n, i){
813
- indexed_array[n['name']] = n['value'];
814
- });
815
 
816
- return indexed_array;
817
  }
818
 
819
- function qmnFormSubmit( quiz_form_id ) {
820
- var quiz_id = +jQuery( '#' + quiz_form_id ).find( '.qmn_quiz_id' ).val();
821
- var $container = jQuery( '#' + quiz_form_id ).closest( '.qmn_quiz_container' );
822
- var result = qmnValidation( '#' + quiz_form_id + ' *', quiz_form_id );
823
 
824
 
825
- if ( ! result ) { return result; }
826
 
827
  /**
828
  * Update Timer in MS
829
  */
830
-
831
  var timer_ms = jQuery('#' + quiz_form_id).find("input[name='timer_ms']").val();
832
  var new_timer_ms = qsmTimeInMS();
833
  jQuery('#' + quiz_form_id).find("input[name='timer_ms']").val(Math.abs(new_timer_ms - timer_ms));
834
 
835
- jQuery( '.mlw_qmn_quiz input:radio' ).attr( 'disabled', false );
836
- jQuery( '.mlw_qmn_quiz input:checkbox' ).attr( 'disabled', false );
837
- jQuery( '.mlw_qmn_quiz select' ).attr( 'disabled', false );
838
- jQuery( '.mlw_qmn_question_comment' ).attr( 'disabled', false );
839
- jQuery( '.mlw_answer_open_text' ).attr( 'disabled', false );
840
-
841
- //Convert serialize data into index array
842
- var unindexed_array = jQuery( '#' + quiz_form_id ).serializeArray();
843
- var fd = new FormData();
844
- jQuery.each(unindexed_array,function(key,input){
845
- fd.append(input.name,input.value);
846
- });
847
- fd.append("action", 'qmn_process_quiz');
848
 
849
 
850
  qsmEndTimeTakenTimer();
851
  if (qmn_quiz_data[quizID].hasOwnProperty('advanced_timer')) {
852
  QSMPageTimer.endPageTimer(quiz_id);
853
  }
854
- if ( qmn_quiz_data[quiz_id].hasOwnProperty( 'timer_limit' ) ) {
855
- QSM.endTimer( quiz_id );
856
  }
857
- jQuery(document).trigger('qsm_before_quiz_submit', [quiz_form_id]);
858
- jQuery( '#' + quiz_form_id + ' input[type=submit]' ).attr( 'disabled', 'disabled' );
859
- qsmDisplayLoading( $container );
860
  // console.log( 'submitted data:' + unindexed_array );
861
- jQuery.ajax({
862
- url: qmn_ajax_object.ajaxurl,
863
- data: fd,
864
- contentType: false,
865
- processData: false,
866
- type: 'POST',
867
- success: function( response ){
868
- qmnDisplayResults( JSON.parse( response ), quiz_form_id, $container );
869
- }
870
- });
871
- jQuery(document).trigger('qsm_after_quiz_submit', [quiz_form_id]);
 
872
  return false;
873
  }
874
 
875
- function qsmDisplayLoading( $container ) {
876
  $container.empty();
877
- $container.append( '<div class="qsm-spinner-loader"></div>' );
878
- qsmScrollTo( $container );
879
  }
880
 
881
- function qmnDisplayResults( results, quiz_form_id, $container ) {
882
  $container.empty();
883
- if ( results.redirect ) {
884
- window.location.replace( results.redirect );
885
  } else {
886
- $container.append( '<div class="qmn_results_page"></div>' );
887
- $container.find( '.qmn_results_page' ).html( results.display );
888
- qsmScrollTo( $container );
889
- MathJax.Hub.queue.Push(["Typeset", MathJax.Hub]);
890
  }
891
  }
892
 
893
  function qmnInit() {
894
- if ( typeof qmn_quiz_data != 'undefined' && qmn_quiz_data ) {
895
- for ( var key in qmn_quiz_data ) {
896
- if ( qmn_quiz_data[key].ajax_show_correct === '1' ) {
897
- jQuery( '#quizForm' + qmn_quiz_data[key].quiz_id + ' .qmn_quiz_radio').change(function() {
898
  var chosen_answer = jQuery(this).val();
899
- var question_id = jQuery(this).attr('name').replace(/question/i,'');
900
  var chosen_id = jQuery(this).attr('id');
901
- jQuery.each( qmn_quiz_data[key].question_list, function( i, value ) {
902
- if ( question_id == value.question_id ) {
903
- jQuery.each( value.answers, function(j, answer ) {
904
- if ( answer[0] === chosen_answer ) {
905
- if ( answer[2] !== 1) {
906
- jQuery( '#'+chosen_id ).parent().addClass( "qmn_incorrect_answer" );
907
  }
908
  }
909
- if ( answer[2] === 1) {
910
- jQuery( ':radio[name=question'+question_id+'][value="'+answer[0]+'"]' ).parent().addClass( "qmn_correct_answer" );
911
  }
912
  });
913
  }
@@ -915,132 +919,132 @@ function qmnInit() {
915
  });
916
  }
917
 
918
- if ( qmn_quiz_data[key].disable_answer === '1' ) {
919
- jQuery( '#quizForm' + qmn_quiz_data[key].quiz_id + ' .qmn_quiz_radio').change(function() {
920
  var radio_group = jQuery(this).attr('name');
921
- jQuery('input[type=radio][name='+radio_group+']').prop('disabled',true);
922
  });
923
  }
924
 
925
- if ( qmn_quiz_data[key].hasOwnProperty('pagination') ) {
926
- qmnInitPagination( qmn_quiz_data[key].quiz_id );
927
  }
928
  }
929
  }
930
  }
931
 
932
  //Function to validate the answers provided in quiz
933
- function qmnValidatePage( quiz_form_id ) {
934
- var result = qmnValidation( '#' + quiz_form_id + ' .quiz_section:visible *', quiz_form_id );
935
  return result;
936
  }
937
 
938
  //Function to advance quiz to next page
939
- function qmnNextSlide( pagination, go_to_top, quiz_form_id ) {
940
- jQuery(document).trigger('qsm_next_button_click_before', [quiz_form_id]);
941
- var quiz_id = +jQuery( quiz_form_id ).find( '.qmn_quiz_id' ).val();
942
- var $container = jQuery( quiz_form_id ).closest( '.qmn_quiz_container' );
943
- var slide_number = +$container.find( '.slide_number_hidden' ).val();
944
- var page_number = +$container.find( '.current_page_hidden' ).val();
945
- var section_totals = +$container.find( '.total_sections_hidden' ).val();
946
- if(pagination == 1){
947
  section_totals = section_totals - 1;
948
- }
949
- var total_pages = $container.find( '.total_pages_hidden' ).val();
950
-
951
- jQuery( quiz_form_id + " .qsm-auto-page-row" ).hide();
952
- if( page_number >= total_pages ){
953
- alert('Next page not found.');
954
- $container.find( ".mlw_next" ).hide();
955
- jQuery( quiz_form_id + " .qsm-auto-page-row.quiz_end" ).show();
956
- return true;
957
- }
958
- if( slide_number == 0 && page_number == 0 ){
959
- jQuery( quiz_form_id + " .qsm-auto-page-row.quiz_begin" ).show();
960
- $container.find( ".mlw_previous" ).hide();
961
- $container.find( '.current_page_hidden' ).val( '1' );
962
- } else if( total_pages == parseInt( page_number ) + 1 ){ //Last page
963
- $container.find( ".mlw_next" ).hide();
964
- jQuery( quiz_form_id + " .qsm-auto-page-row.quiz_end" ).show();
965
- $container.find( '.slide_number_hidden' ).val( parseInt( slide_number ) + 1 );
966
- $container.find( '.current_page_hidden' ).val( parseInt( page_number ) + 1 );
967
- $container.find( ".mlw_previous" ).show();
968
- $container.find( '.g-recaptcha' ).show();
969
- }else if( slide_number >=0 && page_number >= 1 ){
970
- $container.find( '.qsm-auto-page-row.qsm-apc-' + page_number ).show();
971
- $container.find( '.slide_number_hidden' ).val( parseInt( slide_number ) + 1 );
972
- $container.find( '.current_page_hidden' ).val( parseInt( page_number ) + 1 );
973
- $container.find( ".mlw_previous" ).show();
974
- }
975
- if( jQuery(quiz_form_id + " .quiz_section.quiz_end").is(':visible') ){
976
- var button_width = jQuery( quiz_form_id + ' .qsm-submit-btn' ).width();
977
- var progress_width = jQuery( quiz_form_id ).parent().find('.qmn_pagination').width();
978
- jQuery( quiz_form_id ).parent().find('.qmn_pagination').css('width', progress_width - button_width - 40 );
979
- }else{
980
- jQuery( quiz_form_id ).parent().find('.qmn_pagination').css('width', '100%' );
981
- }
982
- if (go_to_top == 1 && qmn_quiz_data[ quiz_id ].disable_scroll_next_previous_click != 1 ) {
983
- qsmScrollTo( $container );
984
  }
985
- //Show the page counts
986
- if(page_number > 0 && jQuery( quiz_form_id ).closest( '.qmn_quiz_container' ).find('.pages_count').length > 0){
987
- var actual_pages = total_pages - 2;
988
- if( page_number <= actual_pages ){
989
- jQuery( quiz_form_id ).closest( '.qmn_quiz_container' ).find('.pages_count').text('').text( page_number + qmn_ajax_object.out_of_text + actual_pages);
990
- jQuery( quiz_form_id ).closest( '.qmn_quiz_container' ).find('.pages_count').show();
991
- }else{
992
- jQuery( quiz_form_id ).closest( '.qmn_quiz_container' ).find('.pages_count').hide();
993
- }
994
- }else{
995
- jQuery( quiz_form_id ).closest( '.qmn_quiz_container' ).find('.pages_count').hide();
996
- }
997
- qmnInitProgressbarOnClick(quiz_id, page_number, total_pages);
998
- jQuery(document).trigger('qsm_next_button_click_after', [quiz_form_id]);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
999
  }
1000
 
1001
- function qmnPrevSlide( pagination, go_to_top, quiz_form_id ) {
1002
- jQuery(document).trigger('qsm_previous_button_click_before', [quiz_form_id]);
1003
- var quiz_id = +jQuery( quiz_form_id ).find( '.qmn_quiz_id' ).val();
1004
- var $container = jQuery( quiz_form_id ).closest( '.qmn_quiz_container' );
1005
- var slide_number = +$container.find( '.slide_number_hidden' ).val();
1006
- var previous = +$container.find( '.previous_amount_hidden' ).val();
1007
- var section_totals = +$container.find( '.total_sections_hidden' ).val();
1008
- var page_number = +$container.find( '.current_page_hidden' ).val();
1009
- var total_pages = $container.find( '.total_pages_hidden' ).val();
1010
- jQuery( quiz_form_id + " .qsm-auto-page-row" ).hide();
1011
- jQuery( quiz_form_id + " .g-recaptcha" ).hide();
1012
- var slide_original_val = parseInt( slide_number ) - 1;
1013
- if( slide_original_val == 0 ){
1014
- $container.find( ".mlw_next" ).show();
1015
- jQuery( quiz_form_id + " .qsm-auto-page-row.quiz_begin" ).show();
1016
- $container.find( '.slide_number_hidden' ).val( slide_original_val );
1017
- $container.find( '.current_page_hidden' ).val( parseInt( page_number ) - 1 );
1018
- $container.find( ".mlw_previous" ).hide();
1019
- } else {
1020
- $container.find( '.qsm-auto-page-row.qsm-apc-' + slide_original_val ).show();
1021
- $container.find( '.slide_number_hidden' ).val( slide_original_val );
1022
- $container.find( '.current_page_hidden' ).val( parseInt( page_number ) - 1 );
1023
- $container.find( ".mlw_next" ).show();
1024
- }
1025
- if (go_to_top == 1 && qmn_quiz_data[ quiz_id ].disable_scroll_next_previous_click != 1 ) {
1026
- qsmScrollTo( $container );
 
 
 
 
 
 
 
 
 
 
 
 
 
1027
  }
1028
- if(page_number > 0 && jQuery( quiz_form_id ).closest( '.qmn_quiz_container' ).find('.pages_count').length > 0){
1029
- var actual_pages = total_pages - 2;
1030
- if( slide_original_val <= actual_pages ){
1031
- jQuery( quiz_form_id ).closest( '.qmn_quiz_container' ).find('.pages_count').text('').text( slide_original_val + qmn_ajax_object.out_of_text + actual_pages);
1032
- if(slide_original_val == 0){
1033
- jQuery( quiz_form_id ).closest( '.qmn_quiz_container' ).find('.pages_count').hide();
1034
- }else{
1035
- jQuery( quiz_form_id ).closest( '.qmn_quiz_container' ).find('.pages_count').show();
1036
- }
1037
- }else{
1038
- jQuery( quiz_form_id ).closest( '.qmn_quiz_container' ).find('.pages_count').hide();
1039
- }
1040
- }
1041
- jQuery( quiz_form_id ).parent().find('.qmn_pagination').css('width', '100%' );
1042
- qmnInitProgressbarOnClick(quiz_id, slide_original_val, total_pages);
1043
- jQuery(document).trigger('qsm_auto_previous_button_click_after', [quiz_form_id]);
1044
  }
1045
 
1046
  /**
@@ -1050,146 +1054,146 @@ function qmnPrevSlide( pagination, go_to_top, quiz_form_id ) {
1050
  * @param {int} total_page_number
1051
  * @returns Change progress bar on next and previous button click
1052
  */
1053
- function qmnInitProgressbarOnClick(quiz_id, page_number, total_page_number){
1054
- if ( '1' == qmn_quiz_data[ quiz_id ].progress_bar ) {
1055
- var qmn_total_questions = qmn_quiz_data[quiz_id].pagination.total_questions;
1056
- var pagination = qmn_quiz_data[quiz_id].pagination.amount;
1057
- total_page_number = Math.ceil(qmn_total_questions / pagination);
1058
- total_page_number = total_page_number + 1; //Increase for quiz end section
1059
- var animate_value = page_number / total_page_number;
1060
- if( animate_value <= 1){
1061
- qmn_quiz_data[ quiz_id ].bar.animate( animate_value );
1062
- var old_text = jQuery( '#qsm_progress_bar_' + quiz_id ).find( '.progressbar-text' ).text().replace(' %', '');
1063
- var new_text = Math.round(animate_value * 100);
1064
- jQuery({
1065
- Counter: old_text
1066
- }).animate({
1067
- Counter: new_text
1068
- }, {
1069
- duration: 1000,
1070
- easing: 'swing',
1071
- step: function () {
1072
- jQuery( '#qsm_progress_bar_' + quiz_id ).find( '.progressbar-text' ).text(Math.round(this.Counter) + ' %');
1073
- }
1074
- });
1075
- }
1076
- }
1077
  }
1078
 
1079
- function qmnUpdatePageNumber( amount, quiz_form_id ) {
1080
- var current_page = +jQuery( quiz_form_id ).closest( '.qmn_quiz_container' ).find( '.current_page_hidden' ).val();
1081
- var total_pages = jQuery( quiz_form_id ).closest( '.qmn_quiz_container' ).find( '.total_pages_hidden' ).val();
1082
  current_page += amount;
1083
  //jQuery( quiz_form_id ).siblings( '.qmn_pagination' ).find( " .qmn_page_counter_message" ).text( current_page + "/" + total_pages );
1084
  }
1085
 
1086
- function qmnInitPagination( quiz_id ) {
1087
- var qmn_section_total = +qmn_quiz_data[quiz_id].pagination.total_questions;
1088
- var qmn_total_pages = Math.ceil( qmn_section_total / +qmn_quiz_data[quiz_id].pagination.amount );
1089
-
1090
- qmn_total_pages = qmn_total_pages + 1; //quiz begin
1091
- qmn_total_pages = qmn_total_pages + 1; //quiz end
1092
-
1093
- jQuery( '#quizForm' + quiz_id ).closest( '.qmn_quiz_container' ).append( '<div class="qmn_pagination border margin-bottom"></div>' );
1094
- jQuery( '#quizForm' + quiz_id ).closest( '.qmn_quiz_container' ).find( '.qmn_pagination' ).append( '<input type="hidden" value="0" name="slide_number" class="slide_number_hidden" />')
1095
- .append( '<input type="hidden" value="0" name="current_page" class="current_page_hidden" />')
1096
- .append( '<input type="hidden" value="' + qmn_total_pages + '" name="total_pages" class="total_pages_hidden" />')
1097
- .append( '<input type="hidden" value="' + qmn_section_total + '" name="total_sections" class="total_sections_hidden" />')
1098
- .append( '<input type="hidden" value="0" name="previous_amount" class="previous_amount_hidden" />')
1099
- .append( '<a class="qmn_btn mlw_qmn_quiz_link mlw_previous" href="#">' + qmn_quiz_data[quiz_id].pagination.previous_text + '</a>' )
1100
- .append( '<span class="qmn_page_message"></span>' )
1101
- .append( '<div class="qmn_page_counter_message"></div>' )
1102
- .append( '<div class="qsm-progress-bar" id="qsm_progress_bar_'+ quiz_id +'" style="display:none;"><div class="progressbar-text"></div></div>' )
1103
- .append( '<a class="qmn_btn mlw_qmn_quiz_link mlw_next" href="#">' + qmn_quiz_data[quiz_id].pagination.next_text + '</a>' );
1104
-
1105
- if ( '1' == qmn_quiz_data[ quiz_id ].progress_bar ) {
1106
- jQuery(document).trigger('qsm_init_progressbar_before', [quiz_id, qmn_quiz_data]);
1107
- jQuery('#quizForm' + quiz_id).closest( '.qmn_quiz_container' ).find('.qsm-progress-bar').show();
1108
- qmn_quiz_data[ quiz_id ].bar = new ProgressBar.Line('#qsm_progress_bar_' + quiz_id, {
1109
- strokeWidth: 2,
1110
- easing: 'easeInOut',
1111
- duration: 500,
1112
- color: '#3498db',
1113
- trailColor: '#eee',
1114
- trailWidth: 1,
1115
- svgStyle: {width: '100%', height: '100%'},
1116
- text: {
1117
- style: {
1118
- // color: '#999',
1119
- position: 'absolute',
1120
- padding: 0,
1121
- margin: 0,
1122
- top: 0,
1123
- right: '10px',
1124
- 'font-size': '13px',
1125
- 'font-weight': 'bold',
1126
- transform: null
1127
- },
1128
- autoStyleContainer: false
1129
- },
1130
- from: {color: '#3498db'},
1131
- to: {color: '#ED6A5A'},
1132
- step: function(state, bar) {
1133
- }
1134
- });
1135
- jQuery(document).trigger('qsm_init_progressbar_after', [quiz_id, qmn_quiz_data]);
1136
- }
1137
-
1138
- jQuery(".mlw_next").click(function(event) {
1139
- event.preventDefault();
1140
- var quiz_id = +jQuery( this ).closest( '.qmn_quiz_container' ).find( '.qmn_quiz_id' ).val();
1141
- jQuery(document).trigger('qsm_auto_next_button_click_before', [quiz_id]);
1142
- if ( qmnValidatePage( 'quizForm' + quiz_id ) ) {
1143
- qmnNextSlide( qmn_quiz_data[quiz_id].pagination.amount, 1, '#quizForm' + quiz_id );
1144
  }
1145
  });
1146
 
1147
- jQuery(".mlw_previous").click(function(event) {
1148
  event.preventDefault();
1149
- var quiz_id = +jQuery( this ).closest( '.qmn_quiz_container' ).find( '.qmn_quiz_id' ).val();
1150
- qmnPrevSlide( qmn_quiz_data[quiz_id].pagination.amount, 1, '#quizForm' + quiz_id );
1151
  });
1152
 
1153
- if ( qmn_quiz_data[quiz_id].first_page ) {
1154
- qmnNextSlide( 1, 0, '#quizForm' + quiz_id );
1155
  } else {
1156
- qmnNextSlide( qmn_quiz_data[quiz_id].pagination.amount, 0, '#quizForm' + quiz_id );
1157
  }
1158
 
1159
  }
1160
 
1161
- function qmnSocialShare( network, mlw_qmn_social_text, mlw_qmn_title, facebook_id, share_url ) {
1162
- var sTop = window.screen.height / 2 - ( 218 );
1163
- var sLeft = window.screen.width / 2 - ( 313 );
1164
  var sqShareOptions = "height=400,width=580,toolbar=0,status=0,location=0,menubar=0,directories=0,scrollbars=0,top=" + sTop + ",left=" + sLeft;
1165
  var pageUrl = window.location.href;
1166
- var pageUrlEncoded = encodeURIComponent( share_url );
1167
  var url = '';
1168
- if ( network == 'facebook' ) {
1169
- url = "https://www.facebook.com/dialog/feed?" + "display=popup&" + "app_id="+facebook_id +
1170
  "&" + "link=" + pageUrlEncoded + "&" + "name=" + encodeURIComponent(mlw_qmn_social_text) +
1171
  "&" + "description=";
1172
  }
1173
- if ( network == 'twitter' ) {
1174
  url = "https://twitter.com/intent/tweet?text=" + encodeURIComponent(mlw_qmn_social_text);
1175
  }
1176
- window.open( url, "Share", sqShareOptions );
1177
  return false;
1178
  }
1179
 
1180
- jQuery(function() {
1181
- jQuery( '.qmn_quiz_container' ).tooltip();
1182
 
1183
- jQuery( '.qmn_quiz_container input' ).on( 'keypress', function ( e ) {
1184
- if ( e.which === 13 ) {
1185
  e.preventDefault();
1186
  }
1187
  });
1188
 
1189
- jQuery(document).on( 'click', ".qsm-submit-btn", function( event ) {
1190
  event.preventDefault();
1191
  var form = jQuery(this).closest('form')[0];
1192
- qmnFormSubmit( form.id );
1193
  });
1194
 
1195
  jQuery(document).on('click', '.btn-reload-quiz', function (e) {
@@ -1216,6 +1220,9 @@ jQuery(function() {
1216
  });
1217
  setInterval(qmnTimeTakenTimer, 1000);
1218
  MathJax.Hub.queue.Push(["Typeset", MathJax.Hub]);
 
 
 
1219
  },
1220
  error: function (errorThrown) {
1221
  console.log('error');
@@ -1223,12 +1230,12 @@ jQuery(function() {
1223
  });
1224
  });
1225
 
1226
- jQuery(document).on('change','.qmn_radio_answers input',function(e){
1227
  var quizID = jQuery(this).parents('.qsm-quiz-container').find('.qmn_quiz_id').val();
1228
- if (qmn_quiz_data[ quizID ].enable_quick_result_mc == 1) {
1229
  var question_id = jQuery(this).attr('name').split('question')[1],
1230
- value = jQuery(this).val(),
1231
- $this = jQuery(this).parents('.quiz_section');
1232
  jQuery.ajax({
1233
  type: 'POST',
1234
  url: qmn_ajax_object.ajaxurl,
@@ -1236,17 +1243,17 @@ jQuery(function() {
1236
  action: "qsm_get_question_quick_result",
1237
  question_id: question_id,
1238
  answer: value,
1239
- show_correct_info: qmn_quiz_data[ quizID ].enable_quick_correct_answer_info
1240
  },
1241
  success: function (response) {
1242
  var data = jQuery.parseJSON(response);
1243
  $this.find('.quick-question-res-p').remove();
1244
  $this.find('.qsm-inline-correct-info').remove();
1245
  if (data.success == 'correct') {
1246
- $this.append('<div style="color: green" class="quick-question-res-p">' + qmn_quiz_data[ quizID ].quick_result_correct_answer_text + '</div>')
1247
  $this.append('<div class="qsm-inline-correct-info">' + data.message + '</div>');
1248
  } else if (data.success == 'incorrect') {
1249
- $this.append('<div style="color: red" class="quick-question-res-p">' + qmn_quiz_data[ quizID ].quick_result_wrong_answer_text + '</div>')
1250
  $this.append('<div class="qsm-inline-correct-info">' + data.message + '</div>');
1251
  }
1252
  MathJax.Hub.queue.Push(["Typeset", MathJax.Hub]);
@@ -1258,24 +1265,24 @@ jQuery(function() {
1258
  }
1259
  });
1260
 
1261
- // Autocomplete off
1262
-
1263
- var quizID = jQuery('.qsm-quiz-container').find('.qmn_quiz_id').val();
1264
- var $quizForm = QSM.getQuizForm( quizID );
1265
- if (qmn_quiz_data[ quizID ].form_disable_autofill == 1) {
1266
- jQuery('#quizForm'+quizID).attr('autocomplete' , 'off');
1267
- }
1268
-
1269
-
1270
 
1271
  // End Quiz If Wrong
1272
- jQuery(document).on('change ','.qmn_radio_answers input , .qmn_check_answers input , .qsm_select',function(e){
1273
  var quizID = jQuery(this).parents('.qsm-quiz-container').find('.qmn_quiz_id').val();
1274
- var $quizForm = QSM.getQuizForm( quizID );
1275
- if (qmn_quiz_data[ quizID ].end_quiz_if_wrong == 1) {
1276
  var question_id = jQuery(this).attr('name').split('question')[1],
1277
- value = jQuery(this).val(),
1278
- $this = jQuery(this).parents('.quiz_section');
1279
  jQuery.ajax({
1280
  type: 'POST',
1281
  url: qmn_ajax_object.ajaxurl,
@@ -1283,26 +1290,26 @@ jQuery(function() {
1283
  action: "qsm_get_question_quick_result",
1284
  question_id: question_id,
1285
  answer: value,
1286
- show_correct_info: qmn_quiz_data[ quizID ].enable_quick_correct_answer_info
1287
  },
1288
  success: function (response) {
1289
  var data = jQuery.parseJSON(response);
1290
  $this.find('.quick-question-res-p').remove();
1291
  $this.find('.qsm-inline-correct-info').remove();
1292
  if (data.success == 'correct') {
1293
-
1294
  } else if (data.success == 'incorrect') {
1295
-
1296
-
1297
 
1298
- $this.append('<div style="color: red" class="quick-question-res-p">' + qmn_quiz_data[ quizID ].quick_result_wrong_answer_text + '</div>')
 
 
1299
  $this.append('<div class="qsm-inline-correct-info">' + data.message + '</div>');
1300
 
1301
- setTimeout(function() {
1302
- $quizForm.closest( '.qmn_quiz_container' ).find('.qsm-submit-btn').trigger('click');
1303
- }, 1000);
 
1304
 
1305
-
1306
  }
1307
  MathJax.Hub.queue.Push(["Typeset", MathJax.Hub]);
1308
  },
@@ -1314,14 +1321,14 @@ jQuery(function() {
1314
  });
1315
 
1316
  //Ajax upload file code
1317
- jQuery('.quiz_section .mlw_answer_file_upload').on('change', function(){
1318
  var $this = jQuery(this);
1319
  var hidden_val = jQuery(this).parent('.quiz_section').find('.mlw_file_upload_hidden_path').val();
1320
  var file_data = jQuery(this).prop('files')[0];
1321
  var form_data = new FormData();
1322
  form_data.append('file', file_data);
1323
  form_data.append('action', 'qsm_upload_image_fd_question');
1324
- var question_id = $this.parent('.quiz_section').find('.mlw_file_upload_hidden_value').attr("name").replace('question','');
1325
  form_data.append('question_id', question_id);
1326
  $this.next('.loading-uploaded-file').show();
1327
  jQuery.ajax({
@@ -1334,23 +1341,25 @@ jQuery(function() {
1334
  success: function (response) {
1335
  var obj = jQuery.parseJSON(response);
1336
  $this.next('.loading-uploaded-file').hide();
1337
- if(obj.type == 'success'){
1338
  $this.next().next('.remove-uploaded-file').show();
1339
  $this.next().next().next('.mlw_file_upload_hidden_value').val(obj.file_url);
1340
  $this.parent('.quiz_section').find('.mlw_file_upload_hidden_path').val(obj.file_path);
1341
  $this.parent('.quiz_section').find('.mlw-file-upload-error-msg').hide();
1342
- }else{
1343
  $this.parent('.quiz_section').find('.mlw-file-upload-error-msg').text('').text(obj.message);
1344
  $this.parent('.quiz_section').find('.mlw-file-upload-error-msg').show();
1345
  $this.parent('.quiz_section').find('.mlw_answer_file_upload').val('');
1346
  }
 
 
1347
  }
1348
  });
1349
  return false;
1350
  });
1351
 
1352
  //Ajax remove file code
1353
- jQuery('.quiz_section .remove-uploaded-file').on('click', function(){
1354
  var $this = jQuery(this);
1355
  var file_data = jQuery(this).parent('.quiz_section').find('.mlw_file_upload_hidden_path').val();
1356
  var form_data = new FormData();
@@ -1365,13 +1374,13 @@ jQuery(function() {
1365
  processData: false,
1366
  success: function (response) {
1367
  var obj = jQuery.parseJSON(response);
1368
- if(obj.type == 'success'){
1369
  $this.hide();
1370
  $this.parent('.quiz_section').find('.mlw_file_upload_hidden_value').val('');
1371
  $this.parent('.quiz_section').find('.mlw_file_upload_hidden_path').val('');
1372
  $this.parent('.quiz_section').find('.mlw_answer_file_upload').val('');
1373
  $this.parent('.quiz_section').find('.mlw-file-upload-error-msg').hide();
1374
- }else{
1375
  $this.parent('.quiz_section').find('.mlw-file-upload-error-msg').text('').text(obj.message);
1376
  $this.parent('.quiz_section').find('.mlw-file-upload-error-msg').show();
1377
  }
@@ -1381,7 +1390,7 @@ jQuery(function() {
1381
  });
1382
 
1383
  //Deselect all answer on select
1384
- jQuery('.qsm-deselect-answer').click(function(e){
1385
  e.preventDefault();
1386
  jQuery(this).parents('.quiz_section').find('input[type="radio"]').prop('checked', false);
1387
  jQuery(this).parents('.quiz_section').find('input[type="radio"][value="No Answer Provided"]').prop('checked', true);
@@ -1389,10 +1398,10 @@ jQuery(function() {
1389
  });
1390
 
1391
  //Submit the form on popup click
1392
- jQuery(document).on( 'click', '.submit-the-form', function(e) {
1393
  e.preventDefault();
1394
  // Triggger the click event on the quiz form's submit button.
1395
- jQuery( '.qsm-submit-btn' ).trigger( 'click' );
1396
  jQuery('#modal-3').removeClass('is-open');
1397
  });
1398
 
@@ -1403,10 +1412,10 @@ jQuery(function() {
1403
  var $container = jQuery('#quizForm' + quiz_id).closest('.qmn_quiz_container');
1404
  qsmScrollTo($container);
1405
  });
1406
-
1407
- jQuery(document).on('keyup', '.mlwPhoneNumber', function(e){
1408
- this.value = this.value.replace(/[^- +()0-9\.]/g,'');
1409
- });
1410
 
1411
  jQuery(document).on('click', '.qsm_social_share_link', function (e) {
1412
  e.preventDefault();
@@ -1417,7 +1426,7 @@ jQuery(function() {
1417
  var url = '';
1418
  if (network == 'facebook') {
1419
  url = "https://www.facebook.com/dialog/feed?" + "display=popup&" + "app_id=" + social_id +
1420
- "&" + "link=" + encodeURIComponent(share_url) + "&" + "name=" + social_text;
1421
  }
1422
  if (network == 'twitter') {
1423
  url = "https://twitter.com/intent/tweet?text=" + social_text;
@@ -1430,5 +1439,5 @@ jQuery(function() {
1430
  });
1431
  });
1432
 
1433
- var qsmTimerInterval = setInterval( qmnTimeTakenTimer, 1000 );
1434
  var quizType = 'default';
14
  /**
15
  * Initializes all quizzes or surveys on the page
16
  */
17
+ init: function () {
18
  // Makes sure we have quizzes on this page
19
+ if (typeof qmn_quiz_data != 'undefined' && qmn_quiz_data) {
20
  // hide the recaptcha by default
21
+ $('.g-recaptcha').hide();
22
  // Cycle through all quizzes
23
+ _.each(qmn_quiz_data, function (quiz) {
24
+ quizID = parseInt(quiz.quiz_id);
25
+ QSM.initPagination(quizID);
26
 
27
+ if (quiz.hasOwnProperty('pagination') || quiz.qpages.hasOwnProperty(2)) {
28
  qsmEndTimeTakenTimer();
29
+ jQuery('#timer').val(0);
30
  jQuery("input[name='timer_ms']").val(0);
31
  quizType = 'paginated';
32
  }
33
 
34
  if (qmn_quiz_data[quizID].hasOwnProperty('advanced_timer')) {
35
  qsmEndTimeTakenTimer();
36
+ jQuery('#timer').val(0);
37
  jQuery("input[name='timer_ms']").val(0);
38
  QSMPageTimer.endPageTimer(quizID, true);
39
  }
40
+ if (quiz.hasOwnProperty('timer_limit') && 0 != quiz.timer_limit) {
41
  qsmEndTimeTakenTimer();
42
+ jQuery('#timer').val(0);
43
  jQuery("input[name='timer_ms']").val(0);
44
+ QSM.initTimer(quizID);
45
  quizType = 'timer';
46
  }
47
  });
53
  *
54
  * @param int quizID The ID of the quiz
55
  */
56
+ initTimer: function (quizID) {
57
+
58
+ jQuery(document).trigger('qsm_init_timer_before', [quizID]);
59
+
60
  // Gets our form
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) {
71
  $('#quizForm' + quizID).closest('.qmn_quiz_container').find('.mlw_next').on('click', function (event) {
72
  event.preventDefault();
73
  if (qmn_quiz_data[quizID].hasOwnProperty('advanced_timer')) {
74
+ var start_timer = parseInt(qmn_quiz_data[quizID].advanced_timer.start_timer_page);
75
  if ($('#quizForm' + quizID).closest('.qmn_quiz_container').find('.qmn_pagination > .current_page_hidden').val() == start_timer) {
76
  QSM.activateTimer(quizID);
77
  $('#quizForm' + quizID).closest('.qmn_quiz_container').find('.stoptimer-p').show();
78
  }
79
  } else {
80
+ if (!qmn_quiz_data[quizID].timerStatus && qmnValidatePage('quizForm' + quizID)) {
81
+ QSM.activateTimer(quizID);
82
  $('#quizForm' + quizID).closest('.qmn_quiz_container').find('.stoptimer-p').show();
83
+ }
84
+ }
85
  });
86
+ // ...else, activate the timer on page load.
87
  } else {
88
  QSM.activateTimer(quizID);
89
  $('#quizForm' + quizID).closest('.qmn_quiz_container').find('.stoptimer-p').show();
90
  }
91
+ // ...else, we must be using the questions per page option.
92
  } else {
93
  if (qmn_quiz_data[quizID].hasOwnProperty('pagination') && qmn_quiz_data[quizID].first_page) {
94
  $('#quizForm' + quizID).closest('.qmn_quiz_container').find('.mlw_next').on('click', function (event) {
95
  event.preventDefault();
96
  if (qmn_quiz_data[quizID].hasOwnProperty('advanced_timer')) {
97
+ var start_timer = parseInt(qmn_quiz_data[quizID].advanced_timer.start_timer_page);
98
  if ($('#quizForm' + quizID).closest('.qmn_quiz_container').find('.qmn_pagination > .slide_number_hidden').val() == start_timer) {
99
  QSM.activateTimer(quizID);
100
  $('#quizForm' + quizID).closest('.qmn_quiz_container').find('.stoptimer-p').show();
101
  }
102
  } else {
103
+ if (!qmn_quiz_data[quizID].timerStatus && (0 == $('.quiz_begin:visible').length || (1 == $('.quiz_begin:visible').length && qmnValidatePage('quizForm' + quizID)))) {
104
  QSM.activateTimer(quizID);
105
  $('#quizForm' + quizID).closest('.qmn_quiz_container').find('.stoptimer-p').show();
106
  }
111
  $('#quizForm' + quizID).closest('.qmn_quiz_container').find('.stoptimer-p').show();
112
  }
113
  }
114
+ jQuery(document).trigger('qsm_init_timer_after', [quizID]);
115
  },
116
  /**
117
  * Starts the timer for the quiz.
118
  *
119
  * @param int quizID The ID of the quiz.
120
  */
121
+ activateTimer: function (quizID) {
122
  timer_ms = jQuery("input[name='timer_ms']").val();
123
+ if (timer_ms == 0) {
124
+ qsmTimerInterval = setInterval(qmnTimeTakenTimer, 1000);
125
+ jQuery("input[name='timer_ms']").each(function () {
126
  var timems = qsmTimeInMS();
127
  jQuery(this).val(timems);
128
  });
129
  }
130
+
131
  jQuery(document).trigger('qsm_activate_time_before', [quizID, qmn_quiz_data]);
132
  // Gets our form.
133
+ var $timer = QSM.getTimer(quizID);
134
 
135
  // Sets up our variables.
136
+ qmn_quiz_data[quizID].timerStatus = true;
137
  var seconds = 0;
138
 
139
  // Calculates starting time.
140
+ var timerStarted = localStorage.getItem('mlw_started_quiz' + quizID);
141
+ var timerRemaning = localStorage.getItem('mlw_time_quiz' + quizID);
142
+ if ('yes' == timerStarted && 0 < timerRemaning) {
143
+ seconds = parseInt(timerRemaning);
144
  } else {
145
+ seconds = parseFloat(qmn_quiz_data[quizID].timer_limit) * 60;
146
  }
147
+ qmn_quiz_data[quizID].timerRemaning = seconds;
148
 
149
+ //hidden timer
150
+ jQuery(".hiddentimer").html(seconds);
151
 
152
  // Makes the timer appear.
153
  $timer.show();
154
+ $timer.text(QSM.secondsToTimer(seconds));
155
 
156
  // Sets up timer interval.
157
+ if (!isNaN(qmn_quiz_data[quizID].timerRemaning)) {
158
+ clearInterval(qmn_quiz_data[quizID].timerInterval);
159
+ qmn_quiz_data[quizID].timerInterval = setInterval(QSM.timer, 1000, quizID);
160
+ }
161
+ jQuery(document).trigger('qsm_activate_time_after', [quizID, qmn_quiz_data]);
162
  },
163
  /**
164
  * Reduces the timer by one second and checks if timer is 0
165
  *
166
  * @param int quizID The ID of the quiz.
167
  */
168
+ timer: function (quizID) {
169
+ qmn_quiz_data[quizID].timerRemaning -= 1;
170
+ if (0 > qmn_quiz_data[quizID].timerRemaning) {
171
+ qmn_quiz_data[quizID].timerRemaning = 0;
172
  }
173
+ var secondsRemaining = qmn_quiz_data[quizID].timerRemaning;
174
+ var display = QSM.secondsToTimer(secondsRemaining);
175
 
176
  // Sets our local storage values for the timer being started and current timer value.
177
+ localStorage.setItem('mlw_time_quiz' + quizID, secondsRemaining);
178
+ localStorage.setItem('mlw_started_quiz' + quizID, "yes");
179
 
180
  // Updates timer element and title on browser tab.
181
+ var $timer = QSM.getTimer(quizID);
182
+ $timer.text(display);
183
  document.title = display + ' ' + qsmTitleText;
184
 
185
  /*CUSTOM TIMER*/
186
+ if (qmn_quiz_data[quizID].hasOwnProperty('advanced_timer') && qmn_quiz_data[quizID].advanced_timer.timer_design == 'big_timer') {
187
  $(".second.circle").parent('.mlw_quiz_form').addClass('qsm_big_timer');
188
  $(".second.circle").show();
189
  $(".second.circle strong").html(display);
190
+ var datashow = ($(".hiddentimer").html() - secondsRemaining) / $(".hiddentimer").html();
191
  $(".second.circle").circleProgress({
192
  startAngle: 11,
193
  value: datashow,
194
  animation: false,
195
+ fill: { gradient: ["#00bb40", "#00511c"] }
196
  });
197
  }
198
 
199
+ var $quizForm = QSM.getQuizForm(quizID);
200
+ var total_seconds = parseFloat(qmn_quiz_data[quizID].timer_limit) * 60;
201
+ var ninety_sec = total_seconds - (total_seconds * 90 / 100);
202
+ if (ninety_sec == secondsRemaining) {
203
+ $quizForm.closest('.qmn_quiz_container').find('.qsm_ninety_warning').fadeIn();
204
  }
205
 
206
  // If timer is run out, disable fields.
207
+ if (0 >= secondsRemaining) {
208
+ clearInterval(qmn_quiz_data[quizID].timerInterval);
209
+ $(".mlw_qmn_quiz input:radio").attr('disabled', true);
210
+ $(".mlw_qmn_quiz input:checkbox").attr('disabled', true);
211
+ $(".mlw_qmn_quiz select").attr('disabled', true);
212
+ $(".mlw_qmn_question_comment").attr('disabled', true);
213
+ $(".mlw_answer_open_text").attr('disabled', true);
214
+ $(".mlw_answer_number").attr('readonly', true);
215
+
216
+ $quizForm.closest('.qmn_quiz_container').addClass('qsm_timer_ended');
217
+ $quizForm.closest('.qmn_quiz_container').prepend('<p style="color: red;">Quiz time is over</p>');
218
+ if (qmn_quiz_data[quizID].enable_result_after_timer_end == 1) {
219
+ $quizForm.closest('.qmn_quiz_container').find('.qsm-submit-btn').trigger('click');
220
+ } else {
221
+ MicroModal.show('modal-3');
222
  }
223
  return;
224
  }
228
  *
229
  * @param int quizID The ID of the quiz
230
  */
231
+ endTimer: function (quizID) {
232
+ localStorage.setItem('mlw_time_quiz' + quizID, 'completed');
233
+ localStorage.setItem('mlw_started_quiz' + quizID, 'no');
234
  document.title = qsmTitleText;
235
+ if (typeof qmn_quiz_data[quizID].timerInterval != 'undefined') {
236
+ clearInterval(qmn_quiz_data[quizID].timerInterval);
237
  }
238
+ jQuery(document).trigger('qsm_end_timer', [quizID, qmn_quiz_data]);
239
  },
240
  /**
241
  * Converts seconds to 00:00:00 format
243
  * @param int seconds The number of seconds
244
  * @return string A string in H:M:S format
245
  */
246
+ secondsToTimer: function (seconds) {
247
  var formattedTime = '';
248
+ seconds = parseInt(seconds);
249
 
250
  // Prepares the hours part.
251
+ var hours = Math.floor(seconds / 3600);
252
+ if (0 === hours) {
253
  formattedTime = '00:';
254
+ } else if (10 > hours) {
255
  formattedTime = '0' + hours + ':';
256
  } else {
257
  formattedTime = hours + ':';
258
  }
259
 
260
  // Prepares the minutes part.
261
+ var minutes = Math.floor((seconds % 3600) / 60);
262
+ if (0 === minutes) {
263
  formattedTime = formattedTime + '00:';
264
+ } else if (10 > minutes) {
265
  formattedTime = formattedTime + '0' + minutes + ':';
266
  } else {
267
  formattedTime = formattedTime + minutes + ':';
268
  }
269
 
270
  // Prepares the seconds part.
271
+ var remainder = Math.floor((seconds % 60));
272
+ if (0 === remainder) {
273
  formattedTime = formattedTime + '00';
274
+ } else if (10 > remainder) {
275
  formattedTime = formattedTime + '0' + remainder;
276
  } else {
277
  formattedTime = formattedTime + remainder;
281
  /**
282
  * Gets the jQuery object for the timer
283
  */
284
+ getTimer: function (quizID) {
285
+ var $quizForm = QSM.getQuizForm(quizID);
286
+ return $quizForm.children('.mlw_qmn_timer');
287
  },
288
  /**
289
  * Sets up pagination for a quiz
290
  *
291
  * @param int quizID The ID of the quiz.
292
  */
293
+ initPagination: function (quizID) {
294
+ var $quizForm = QSM.getQuizForm(quizID);
295
+ if (0 < $quizForm.children('.qsm-page').length) {
296
+ $quizForm.children('.qsm-page').hide();
297
+ template = wp.template('qsm-pagination-' + quizID);
298
+ $quizForm.append(template());
299
+ if ($quizForm.find('.qsm-pagination > .current_page_hidden').length == 0) {
300
+ $quizForm.find('.qsm-pagination').append('<input type="hidden" value="0" name="current_page" class="current_page_hidden" />');
301
  }
302
+ if ('1' == qmn_quiz_data[quizID].progress_bar) {
303
+ jQuery(document).trigger('qsm_init_progressbar_before', [quizID, qmn_quiz_data]);
304
  $('#quizForm' + quizID).find('.qsm-progress-bar').show();
305
+ qmn_quiz_data[quizID].bar = new ProgressBar.Line('#quizForm' + quizID + ' .qsm-progress-bar', {
306
  strokeWidth: 2,
307
  easing: 'easeInOut',
308
  duration: 1400,
309
  color: '#3498db',
310
  trailColor: '#eee',
311
  trailWidth: 1,
312
+ svgStyle: { width: '100%', height: '100%' },
313
  text: {
314
+ style: {
315
+ // color: '#999',
316
+ position: 'absolute',
317
+ padding: 0,
318
+ margin: 0,
319
+ top: 0,
320
+ right: '10px',
321
+ 'font-size': '13px',
322
+ 'font-weight': 'bold',
323
+ transform: null
324
+ },
325
+ autoStyleContainer: false
326
  },
327
+ from: { color: '#3498db' },
328
+ to: { color: '#ED6A5A' },
329
+ step: function (state, bar) {
330
  //bar.setText(Math.round(bar.value() * 100) + ' %');
331
  }
332
  });
333
+ jQuery(document).trigger('qsm_init_progressbar_after', [quizID, qmn_quiz_data]);
334
  }
335
+ QSM.goToPage(quizID, 1);
336
+ $quizForm.find('.qsm-pagination .qsm-next').on('click', function (event) {
337
+ jQuery(document).trigger('qsm_next_button_click_before', [quizID]);
338
  event.preventDefault();
339
+ QSM.nextPage(quizID);
340
+ var $container = jQuery('#quizForm' + quizID).closest('.qmn_quiz_container');
341
+ if (qmn_quiz_data[quizID].disable_scroll_next_previous_click != 1) {
342
+ qsmScrollTo($container);
343
+ }
344
+ jQuery(document).trigger('qsm_next_button_click_after', [quizID]);
345
  });
346
+ $quizForm.find('.qsm-pagination .qsm-previous').on('click', function (event) {
347
+ jQuery(document).trigger('qsm_previous_button_click_before', [quizID]);
348
  event.preventDefault();
349
+ QSM.prevPage(quizID);
350
+ var $container = jQuery('#quizForm' + quizID).closest('.qmn_quiz_container');
351
+ if (qmn_quiz_data[quizID].disable_scroll_next_previous_click != 1) {
352
+ qsmScrollTo($container);
353
+ }
354
+ jQuery(document).trigger('qsm_previous_button_click_after', [quizID]);
355
  });
356
  }
357
  },
360
  *
361
  * @param int pageNumber The number of the page
362
  */
363
+ goToPage: function (quizID, pageNumber) {
364
+ jQuery(document).trigger('qsm_go_to_page_before', [quizID, pageNumber]);
365
+ var $quizForm = QSM.getQuizForm(quizID);
366
+ var $pages = $quizForm.children('.qsm-page');
367
+ var $currentPage = $quizForm.children('.qsm-page:nth-of-type(' + pageNumber + ')');
368
  $pages.hide();
369
  $currentPage.show();
370
 
373
  QSMPageTimer.initPageTimer(quizID, $currentPage);
374
  }
375
 
376
+ $quizForm.find('.current_page_hidden').val(pageNumber - 1);
377
+ $quizForm.find('.qsm-previous').hide();
378
+ $quizForm.find('.qsm-next').hide();
379
+ $quizForm.find('.qsm-submit-btn').hide();
380
+ $quizForm.find('.g-recaptcha').hide();
381
+ if (pageNumber < $pages.length) {
382
+ $quizForm.find('.qsm-next').show();
383
  } else {
384
+ $quizForm.find('.qsm-submit-btn').show();
385
+ $quizForm.find('.g-recaptcha').show();
386
  }
387
+ if (1 < pageNumber) {
388
+ $quizForm.find('.qsm-previous').show();
389
  }
390
  if (1 == $currentPage.data('prevbtn')) {
391
+ $quizForm.find('.qsm-previous').hide();
392
  }
393
+ if ('1' == qmn_quiz_data[quizID].progress_bar) {
394
+ var current_page = jQuery('#quizForm' + quizID).find('.current_page_hidden').val();
395
+ var total_page_length = $pages.length - 1;
396
+ if (qmn_quiz_data[quizID].contact_info_location == 0) {
397
+ //Do nothing.
398
+ } else if (qmn_quiz_data[quizID].contact_info_location == 1) {
399
+ if ($quizForm.children('.qsm-page').find('.qsm_contact_div ').length > 0) {
400
+ //total_page_length = total_page_length - 1;
401
+ }
402
+ }
403
+ var animate_value = current_page / total_page_length;
404
+ if (animate_value <= 1) {
405
+ qmn_quiz_data[quizID].bar.animate(animate_value);
406
+ var old_text = jQuery('#quizForm' + quizID).find('.progressbar-text').text().replace(' %', '');
407
+ var new_text = Math.round(animate_value * 100);
408
+ jQuery({
409
+ Counter: old_text
410
+ }).animate({
411
+ Counter: new_text
412
+ }, {
413
+ duration: 1000,
414
+ easing: 'swing',
415
+ step: function () {
416
+ jQuery('#quizForm' + quizID).find('.progressbar-text').text(Math.round(this.Counter) + ' %');
417
+ }
418
+ });
419
+ }
420
  }
421
+ QSM.savePage(quizID, pageNumber);
422
+ jQuery(document).trigger('qsm_go_to_page_after', [quizID, pageNumber]);
423
  },
424
  /**
425
  * Moves forward or backwards through the pages
427
  * @param int quizID The ID of the quiz
428
  * @param int difference The number of pages to forward or back
429
  */
430
+ changePage: function (quizID, difference) {
431
+ var page = QSM.getPage(quizID);
432
  page += difference;
433
+ QSM.goToPage(quizID, page);
434
  },
435
+ nextPage: function (quizID) {
436
+ if (qmnValidatePage('quizForm' + quizID)) {
437
+ QSM.changePage(quizID, 1);
438
  }
439
  },
440
+ prevPage: function (quizID) {
441
+ QSM.changePage(quizID, -1);
442
  },
443
+ savePage: function (quizID, pageNumber) {
444
+ sessionStorage.setItem('quiz' + quizID + 'page', pageNumber);
445
  },
446
+ getPage: function (quizID) {
447
+ pageNumber = parseInt(sessionStorage.getItem('quiz' + quizID + 'page'));
448
+ if (isNaN(pageNumber) || null == pageNumber) {
449
  pageNumber = 1;
450
  }
451
  return pageNumber;
455
  *
456
  * @param jQueryObject The jQuery version of an element. i.e. $('#quizForm3')
457
  */
458
+ scrollTo: function ($element) {
459
+ jQuery('html, body').animate(
460
  {
461
  scrollTop: $element.offset().top - 150
462
  },
463
+ 1000);
464
  },
465
  /**
466
  * Gets the jQuery object of the quiz form
467
  */
468
+ getQuizForm: function (quizID) {
469
+ return $('#quizForm' + quizID);
470
  }
471
  };
472
 
475
  * Init Page Timer
476
  */
477
  initPageTimer: function (quizID, $currentpage) {
478
+ jQuery(document).trigger('qsm_init_page_timer_before', [quizID, $currentpage]);
479
  var $quizForm = QSM.getQuizForm(quizID);
480
  var pid = $currentpage.data('pid');
481
  if (undefined != pid) {
482
+ var $qpages = qmn_quiz_data[quizID].qpages;
483
  var $curr_page_opt = $qpages[pid];
484
  if ($curr_page_opt.hasOwnProperty('pagetimer') && 0 != $curr_page_opt.pagetimer) {
485
  var $timer_box = $currentpage.find('.qsm-pagetimer');
498
  seconds = parseFloat($curr_page_opt.pagetimer) * 60;
499
  }
500
  }
501
+ qmn_quiz_data[quizID].qpages[pid].timerRemaning = seconds;
502
  /* Makes the timer appear. */
503
  $timer_box.show();
504
  $timer_box.text(QSMPageTimer.secondsToTimer(seconds));
505
  /* Sets up timer interval. */
506
+ qmn_quiz_data[quizID].qpages[pid].timerInterval = setInterval(QSMPageTimer.timer, 1000, quizID, pid, $timer_box);
507
  }
508
+ $currentpage.find('.page_intro_wrapper video').each(function () {
509
  var $this = jQuery(this);
510
  var src = $this.find('source').attr('src');
511
  $this.attr('src', src)
513
  $this.get(0).play();
514
  });
515
  }
516
+ jQuery(document).trigger('qsm_init_page_timer_after', [quizID, $currentpage]);
517
  },
518
  /**
519
  * Reduces the timer by one second and checks if timer is 0
521
  */
522
  timer: function (quizID, pid, $timer_box) {
523
  var $quizForm = QSM.getQuizForm(quizID);
524
+ var $page = qmn_quiz_data[quizID].qpages[pid];
525
+ qmn_quiz_data[quizID].qpages[pid].timerRemaning -= 1;
526
+ if (0 > qmn_quiz_data[quizID].qpages[pid].timerRemaning) {
527
+ qmn_quiz_data[quizID].qpages[pid].timerRemaning = 0;
528
  }
529
  var total_seconds = parseFloat($page.pagetimer) * 60;
530
+ var secondsRemaining = qmn_quiz_data[quizID].qpages[pid].timerRemaning;
531
  var display = QSMPageTimer.secondsToTimer(secondsRemaining);
532
  $timer_box.text(display);
533
  var pageTimeTaken = total_seconds - secondsRemaining;
534
+ jQuery('#pagetime_' + pid).val(pageTimeTaken);
535
  /* Sets our local storage values for the timer being started and current timer value. */
536
  localStorage.setItem('mlw_started_q' + quizID + '_page' + pid, "yes");
537
  localStorage.setItem('mlw_time_q' + quizID + '_page' + pid, secondsRemaining);
543
  }
544
  /* If timer is run out, disable fields. */
545
  if (0 >= secondsRemaining) {
546
+ clearInterval(qmn_quiz_data[quizID].qpages[pid].timerInterval);
547
 
548
  $(".qsm-page:visible input:radio").attr('disabled', true);
549
  $(".qsm-page:visible input:checkbox").attr('disabled', true);
569
  localStorage.removeItem('mlw_stoped_q' + quizID + '_page' + value.id);
570
  localStorage.removeItem('mlw_time_q' + quizID + '_page' + value.id);
571
  }
572
+ var secondsRemaining = qmn_quiz_data[quizID].qpages[value.id].timerRemaning;
573
  localStorage.setItem('mlw_stoped_q' + quizID + '_page' + value.id, secondsRemaining);
574
  localStorage.setItem('mlw_time_q' + quizID + '_page' + value.id, 'completed');
575
+ if (typeof qmn_quiz_data[quizID].qpages[value.id].timerInterval != 'undefined') {
576
+ clearInterval(qmn_quiz_data[quizID].qpages[value.id].timerInterval);
577
  }
578
  }
579
  });
615
  }
616
 
617
  // On load code
618
+ $(function () {
619
 
620
  // Legacy init.
621
  qmnInit();
623
  // Call main initialization.
624
  qsminstance = QSM.init();
625
 
626
+ jQuery(".qsm-quiz-container").on("click", ".mlw_next", function () {
627
+ if (quizType == 'paginated') {
628
  timer_ms = jQuery("input[name='timer_ms']").val();
629
+ if (timer_ms == 0) {
630
+ qsmTimerInterval = setInterval(qmnTimeTakenTimer, 1000);
631
+ jQuery("input[name='timer_ms']").each(function () {
632
  var timems = qsmTimeInMS();
633
  jQuery(this).val(timems);
634
  });
637
  });
638
  });
639
 
640
+ jQuery("input[name='timer_ms']").each(function () {
641
  var timems = qsmTimeInMS();
642
  jQuery(this).val(timems);
643
  });
652
  * @param email The Email Id to validate.
653
  * @returns Boolean
654
  */
655
+ function isEmail(email) {
656
  var regex = /^([a-zA-Z0-9_\.\-\+])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/;
657
+ if (!regex.test(email)) {
658
  return false;
659
+ } else {
660
  return true;
661
  }
662
  }
666
  * Limit multiple response based on question limit
667
  * @returns {undefined}
668
  */
669
+ function qsmCheckMR(event, limit) {
670
+ var checked = jQuery(event).parents('.quiz_section').find(':checkbox:checked').length;
671
+ if (checked > limit) {
672
+ event.checked = false;
673
+ if (jQuery(event).parents('.quiz_section').find('.multi-checkbox-limit-reach').length == 0) {
674
+ jQuery(event).parents('.quiz_section').append('<span class="multi-checkbox-limit-reach">' + qmn_ajax_object.multicheckbox_limit_reach + '</span>');
675
+ }
676
+ } else {
677
+ jQuery(event).parents('.quiz_section').find('.multi-checkbox-limit-reach').remove();
678
+ }
679
  }
680
 
681
  function qmnTimeTakenTimer() {
682
+ var x = +jQuery('#timer').val();
683
+ if (NaN === x) {
684
  x = 0;
685
  }
686
  x = x + 1;
687
+ jQuery('#timer').val(x);
688
  }
689
 
690
  function qsmEndTimeTakenTimer() {
691
+ clearInterval(qsmTimerInterval);
692
  }
693
 
694
  function qsmTimeInMS() {
697
  return n;
698
  }
699
 
700
+ function qmnClearField(field) {
701
+ if (field.defaultValue == field.value) field.value = '';
702
  }
703
 
704
+ function qsmScrollTo($element) {
705
+ if ($element.length > 0) {
706
+ jQuery(document).trigger('qsm_scroll_to_top_before', [$element]);
707
+ jQuery('html, body').animate({ scrollTop: $element.offset().top - 150 }, 1000);
708
+ jQuery(document).trigger('qsm_scroll_to_top_after', [$element]);
709
+ }
710
  }
711
 
712
+ function qmnDisplayError(message, field, quiz_form_id) {
713
+ jQuery('#' + quiz_form_id + ' .qmn_error_message_section').addClass('qmn_error_message');
714
+ jQuery('#' + quiz_form_id + ' .qmn_error_message').text(message);
715
+ field.closest('.quiz_section').addClass('qmn_error');
716
  }
717
 
718
+ function qmnResetError(quiz_form_id) {
719
+ jQuery('#' + quiz_form_id + ' .qmn_error_message').text('');
720
+ jQuery('#' + quiz_form_id + ' .qmn_error_message_section').removeClass('qmn_error_message');
721
+ jQuery('#' + quiz_form_id + ' .quiz_section').removeClass('qmn_error');
722
  }
723
 
724
+ function qmnValidation(element, quiz_form_id) {
725
+ jQuery(document).trigger('qsm_before_validation', [element, quiz_form_id]);
726
  var result = true;
727
+ var quiz_id = +jQuery('#' + quiz_form_id).find('.qmn_quiz_id').val();
728
+ var email_error = qmn_quiz_data[quiz_id].error_messages.email;
729
+ var number_error = qmn_quiz_data[quiz_id].error_messages.number;
730
+ var empty_error = qmn_quiz_data[quiz_id].error_messages.empty;
731
+ var incorrect_error = qmn_quiz_data[quiz_id].error_messages.incorrect;
732
+ qmnResetError(quiz_form_id);
733
+ jQuery(element).each(function () {
734
+ if (jQuery(this).attr('class')) {
735
+ if (jQuery(this).attr('class').indexOf('mlwEmail') !== -1 && this.value !== "") {
736
  // Remove any trailing and preceeding space.
737
+ var x = jQuery.trim(this.value);
738
+ if (!isEmail(x)) {
739
+ qmnDisplayError(email_error, jQuery(this), quiz_form_id);
740
  result = false;
741
  }
742
  }
743
+ var by_pass = true;
744
+ if (qmn_quiz_data[quizID].timer_limit_val > 0 && qmn_quiz_data[quiz_id].hasOwnProperty('skip_validation_time_expire') && qmn_quiz_data[quiz_id].skip_validation_time_expire == 0) {
745
+ by_pass = false;
746
+ }
747
+
748
+ if (localStorage.getItem('mlw_time_quiz' + quiz_id) === null || localStorage.getItem('mlw_time_quiz' + quiz_id) > 0.08 || by_pass === false) {
749
+
750
+ if (jQuery(this).attr('class').indexOf('mlwRequiredNumber') > -1 && this.value === "" && +this.value != NaN) {
751
+ qmnDisplayError(number_error, jQuery(this), quiz_form_id);
752
+ result = false;
753
+ }
754
+ if (jQuery(this).attr('class').indexOf('mlwRequiredDate') > -1 && this.value === "") {
755
+ qmnDisplayError(empty_error, jQuery(this), quiz_form_id);
756
+ result = false;
757
  }
758
+ if (jQuery(this).attr('class').indexOf('mlwRequiredText') > -1 && jQuery.trim(this.value) === "") {
759
+ qmnDisplayError(empty_error, jQuery(this), quiz_form_id);
760
+ result = false;
761
  }
762
+ if (jQuery(this).attr('class').indexOf('mlwRequiredCaptcha') > -1 && this.value != mlw_code) {
763
+ qmnDisplayError(incorrect_error, jQuery(this), quiz_form_id);
764
+ result = false;
765
  }
766
+ if (jQuery(this).attr('class').indexOf('mlwRequiredAccept') > -1 && !jQuery(this).prop('checked')) {
767
+ qmnDisplayError(empty_error, jQuery(this), quiz_form_id);
768
+ result = false;
769
  }
770
+ if (jQuery(this).attr('class').indexOf('mlwRequiredRadio') > -1) {
771
+ check_val = jQuery(this).find('input:checked').val();
772
+ if (check_val == "No Answer Provided" || check_val == "") {
773
+ qmnDisplayError(empty_error, jQuery(this), quiz_form_id);
774
+ result = false;
 
 
 
 
775
  }
776
  }
777
+ if (jQuery(this).attr('class').indexOf('mlwRequiredFileUpload') > -1) {
778
+ var selected_file = jQuery(this).get(0).files.length;
779
+ if (selected_file === 0) {
780
+ qmnDisplayError(empty_error, jQuery(this), quiz_form_id);
781
+ result = false;
782
  }
783
  }
784
+ if (jQuery(this).attr('class').indexOf('qsmRequiredSelect') > -1) {
785
+ check_val = jQuery(this).val();
786
+ if (check_val == "No Answer Provided" || check_val == "") {
787
+ qmnDisplayError(empty_error, jQuery(this), quiz_form_id);
788
+ result = false;
789
  }
790
  }
791
+ if (jQuery(this).attr('class').indexOf('mlwRequiredCheck') > -1) {
792
+ if (!jQuery(this).find('input:checked').length) {
793
+ qmnDisplayError(empty_error, jQuery(this), quiz_form_id);
794
+ result = false;
795
  }
796
  }
797
+ //Google recaptcha validation
798
+ if (jQuery(this).attr('class').indexOf('g-recaptcha-response') > -1) {
799
+ if (grecaptcha.getResponse() == "") {
800
  alert('ReCaptcha is missing');
801
+ result = false;
802
  }
803
  }
804
  }
805
  }
806
  });
807
+ jQuery(document).trigger('qsm_after_validation', [element, quiz_form_id]);
808
  return result;
809
  }
810
 
811
+ function getFormData($form) {
812
+ var unindexed_array = $form.serializeArray();
813
+ var indexed_array = {};
814
 
815
+ jQuery.map(unindexed_array, function (n, i) {
816
+ indexed_array[n['name']] = n['value'];
817
+ });
818
 
819
+ return indexed_array;
820
  }
821
 
822
+ function qmnFormSubmit(quiz_form_id) {
823
+ var quiz_id = +jQuery('#' + quiz_form_id).find('.qmn_quiz_id').val();
824
+ var $container = jQuery('#' + quiz_form_id).closest('.qmn_quiz_container');
825
+ var result = qmnValidation('#' + quiz_form_id + ' *', quiz_form_id);
826
 
827
 
828
+ if (!result) { return result; }
829
 
830
  /**
831
  * Update Timer in MS
832
  */
833
+
834
  var timer_ms = jQuery('#' + quiz_form_id).find("input[name='timer_ms']").val();
835
  var new_timer_ms = qsmTimeInMS();
836
  jQuery('#' + quiz_form_id).find("input[name='timer_ms']").val(Math.abs(new_timer_ms - timer_ms));
837
 
838
+ jQuery('.mlw_qmn_quiz input:radio').attr('disabled', false);
839
+ jQuery('.mlw_qmn_quiz input:checkbox').attr('disabled', false);
840
+ jQuery('.mlw_qmn_quiz select').attr('disabled', false);
841
+ jQuery('.mlw_qmn_question_comment').attr('disabled', false);
842
+ jQuery('.mlw_answer_open_text').attr('disabled', false);
843
+
844
+ //Convert serialize data into index array
845
+ var unindexed_array = jQuery('#' + quiz_form_id).serializeArray();
846
+ var fd = new FormData();
847
+ jQuery.each(unindexed_array, function (key, input) {
848
+ fd.append(input.name, input.value);
849
+ });
850
+ fd.append("action", 'qmn_process_quiz');
851
 
852
 
853
  qsmEndTimeTakenTimer();
854
  if (qmn_quiz_data[quizID].hasOwnProperty('advanced_timer')) {
855
  QSMPageTimer.endPageTimer(quiz_id);
856
  }
857
+ if (qmn_quiz_data[quiz_id].hasOwnProperty('timer_limit')) {
858
+ QSM.endTimer(quiz_id);
859
  }
860
+ jQuery(document).trigger('qsm_before_quiz_submit', [quiz_form_id]);
861
+ jQuery('#' + quiz_form_id + ' input[type=submit]').attr('disabled', 'disabled');
862
+ qsmDisplayLoading($container);
863
  // console.log( 'submitted data:' + unindexed_array );
864
+ jQuery.ajax({
865
+ url: qmn_ajax_object.ajaxurl,
866
+ data: fd,
867
+ contentType: false,
868
+ processData: false,
869
+ type: 'POST',
870
+ success: function (response) {
871
+ qmnDisplayResults(JSON.parse(response), quiz_form_id, $container);
872
+ jQuery(document).trigger('qsm_after_quiz_submit_load_chart');
873
+ }
874
+ });
875
+ jQuery(document).trigger('qsm_after_quiz_submit', [quiz_form_id]);
876
  return false;
877
  }
878
 
879
+ function qsmDisplayLoading($container) {
880
  $container.empty();
881
+ $container.append('<div class="qsm-spinner-loader"></div>');
882
+ qsmScrollTo($container);
883
  }
884
 
885
+ function qmnDisplayResults(results, quiz_form_id, $container) {
886
  $container.empty();
887
+ if (results.redirect) {
888
+ window.location.replace(results.redirect);
889
  } else {
890
+ $container.append('<div class="qmn_results_page"></div>');
891
+ $container.find('.qmn_results_page').html(results.display);
892
+ qsmScrollTo($container);
893
+ MathJax.Hub.queue.Push(["Typeset", MathJax.Hub]);
894
  }
895
  }
896
 
897
  function qmnInit() {
898
+ if (typeof qmn_quiz_data != 'undefined' && qmn_quiz_data) {
899
+ for (var key in qmn_quiz_data) {
900
+ if (qmn_quiz_data[key].ajax_show_correct === '1') {
901
+ jQuery('#quizForm' + qmn_quiz_data[key].quiz_id + ' .qmn_quiz_radio').change(function () {
902
  var chosen_answer = jQuery(this).val();
903
+ var question_id = jQuery(this).attr('name').replace(/question/i, '');
904
  var chosen_id = jQuery(this).attr('id');
905
+ jQuery.each(qmn_quiz_data[key].question_list, function (i, value) {
906
+ if (question_id == value.question_id) {
907
+ jQuery.each(value.answers, function (j, answer) {
908
+ if (answer[0] === chosen_answer) {
909
+ if (answer[2] !== 1) {
910
+ jQuery('#' + chosen_id).parent().addClass("qmn_incorrect_answer");
911
  }
912
  }
913
+ if (answer[2] === 1) {
914
+ jQuery(':radio[name=question' + question_id + '][value="' + answer[0] + '"]').parent().addClass("qmn_correct_answer");
915
  }
916
  });
917
  }
919
  });
920
  }
921
 
922
+ if (qmn_quiz_data[key].disable_answer === '1') {
923
+ jQuery('#quizForm' + qmn_quiz_data[key].quiz_id + ' .qmn_quiz_radio').change(function () {
924
  var radio_group = jQuery(this).attr('name');
925
+ jQuery('input[type=radio][name=' + radio_group + ']').prop('disabled', true);
926
  });
927
  }
928
 
929
+ if (qmn_quiz_data[key].hasOwnProperty('pagination')) {
930
+ qmnInitPagination(qmn_quiz_data[key].quiz_id);
931
  }
932
  }
933
  }
934
  }
935
 
936
  //Function to validate the answers provided in quiz
937
+ function qmnValidatePage(quiz_form_id) {
938
+ var result = qmnValidation('#' + quiz_form_id + ' .quiz_section:visible *', quiz_form_id);
939
  return result;
940
  }
941
 
942
  //Function to advance quiz to next page
943
+ function qmnNextSlide(pagination, go_to_top, quiz_form_id) {
944
+ jQuery(document).trigger('qsm_next_button_click_before', [quiz_form_id]);
945
+ var quiz_id = +jQuery(quiz_form_id).find('.qmn_quiz_id').val();
946
+ var $container = jQuery(quiz_form_id).closest('.qmn_quiz_container');
947
+ var slide_number = +$container.find('.slide_number_hidden').val();
948
+ var page_number = +$container.find('.current_page_hidden').val();
949
+ var section_totals = +$container.find('.total_sections_hidden').val();
950
+ if (pagination == 1) {
951
  section_totals = section_totals - 1;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
952
  }
953
+ var total_pages = $container.find('.total_pages_hidden').val();
954
+
955
+ jQuery(quiz_form_id + " .qsm-auto-page-row").hide();
956
+ if (page_number >= total_pages) {
957
+ alert('Next page not found.');
958
+ $container.find(".mlw_next").hide();
959
+ jQuery(quiz_form_id + " .qsm-auto-page-row.quiz_end").show();
960
+ return true;
961
+ }
962
+ if (slide_number == 0 && page_number == 0) {
963
+ jQuery(quiz_form_id + " .qsm-auto-page-row.quiz_begin").show();
964
+ $container.find(".mlw_previous").hide();
965
+ $container.find('.current_page_hidden').val('1');
966
+ } else if (total_pages == parseInt(page_number) + 1) { //Last page
967
+ $container.find(".mlw_next").hide();
968
+ jQuery(quiz_form_id + " .qsm-auto-page-row.quiz_end").show();
969
+ $container.find('.slide_number_hidden').val(parseInt(slide_number) + 1);
970
+ $container.find('.current_page_hidden').val(parseInt(page_number) + 1);
971
+ $container.find(".mlw_previous").show();
972
+ $container.find('.g-recaptcha').show();
973
+ } else if (slide_number >= 0 && page_number >= 1) {
974
+ $container.find('.qsm-auto-page-row.qsm-apc-' + page_number).show();
975
+ $container.find('.slide_number_hidden').val(parseInt(slide_number) + 1);
976
+ $container.find('.current_page_hidden').val(parseInt(page_number) + 1);
977
+ $container.find(".mlw_previous").show();
978
+ }
979
+ if (jQuery(quiz_form_id + " .quiz_section.quiz_end").is(':visible')) {
980
+ var button_width = jQuery(quiz_form_id + ' .qsm-submit-btn').width();
981
+ var progress_width = jQuery(quiz_form_id).parent().find('.qmn_pagination').width();
982
+ jQuery(quiz_form_id).parent().find('.qmn_pagination').css('width', progress_width - button_width - 40);
983
+ } else {
984
+ jQuery(quiz_form_id).parent().find('.qmn_pagination').css('width', '100%');
985
+ }
986
+ if (go_to_top == 1 && qmn_quiz_data[quiz_id].disable_scroll_next_previous_click != 1) {
987
+ qsmScrollTo($container);
988
+ }
989
+ //Show the page counts
990
+ if (page_number > 0 && jQuery(quiz_form_id).closest('.qmn_quiz_container').find('.pages_count').length > 0) {
991
+ var actual_pages = total_pages - 2;
992
+ if (page_number <= actual_pages) {
993
+ jQuery(quiz_form_id).closest('.qmn_quiz_container').find('.pages_count').text('').text(page_number + qmn_ajax_object.out_of_text + actual_pages);
994
+ jQuery(quiz_form_id).closest('.qmn_quiz_container').find('.pages_count').show();
995
+ } else {
996
+ jQuery(quiz_form_id).closest('.qmn_quiz_container').find('.pages_count').hide();
997
+ }
998
+ } else {
999
+ jQuery(quiz_form_id).closest('.qmn_quiz_container').find('.pages_count').hide();
1000
+ }
1001
+ qmnInitProgressbarOnClick(quiz_id, page_number, total_pages);
1002
+ jQuery(document).trigger('qsm_next_button_click_after', [quiz_form_id]);
1003
  }
1004
 
1005
+ function qmnPrevSlide(pagination, go_to_top, quiz_form_id) {
1006
+ jQuery(document).trigger('qsm_previous_button_click_before', [quiz_form_id]);
1007
+ var quiz_id = +jQuery(quiz_form_id).find('.qmn_quiz_id').val();
1008
+ var $container = jQuery(quiz_form_id).closest('.qmn_quiz_container');
1009
+ var slide_number = +$container.find('.slide_number_hidden').val();
1010
+ var previous = +$container.find('.previous_amount_hidden').val();
1011
+ var section_totals = +$container.find('.total_sections_hidden').val();
1012
+ var page_number = +$container.find('.current_page_hidden').val();
1013
+ var total_pages = $container.find('.total_pages_hidden').val();
1014
+ jQuery(quiz_form_id + " .qsm-auto-page-row").hide();
1015
+ jQuery(quiz_form_id + " .g-recaptcha").hide();
1016
+ var slide_original_val = parseInt(slide_number) - 1;
1017
+ if (slide_original_val == 0) {
1018
+ $container.find(".mlw_next").show();
1019
+ jQuery(quiz_form_id + " .qsm-auto-page-row.quiz_begin").show();
1020
+ $container.find('.slide_number_hidden').val(slide_original_val);
1021
+ $container.find('.current_page_hidden').val(parseInt(page_number) - 1);
1022
+ $container.find(".mlw_previous").hide();
1023
+ } else {
1024
+ $container.find('.qsm-auto-page-row.qsm-apc-' + slide_original_val).show();
1025
+ $container.find('.slide_number_hidden').val(slide_original_val);
1026
+ $container.find('.current_page_hidden').val(parseInt(page_number) - 1);
1027
+ $container.find(".mlw_next").show();
1028
+ }
1029
+ if (go_to_top == 1 && qmn_quiz_data[quiz_id].disable_scroll_next_previous_click != 1) {
1030
+ qsmScrollTo($container);
1031
+ }
1032
+ if (page_number > 0 && jQuery(quiz_form_id).closest('.qmn_quiz_container').find('.pages_count').length > 0) {
1033
+ var actual_pages = total_pages - 2;
1034
+ if (slide_original_val <= actual_pages) {
1035
+ jQuery(quiz_form_id).closest('.qmn_quiz_container').find('.pages_count').text('').text(slide_original_val + qmn_ajax_object.out_of_text + actual_pages);
1036
+ if (slide_original_val == 0) {
1037
+ jQuery(quiz_form_id).closest('.qmn_quiz_container').find('.pages_count').hide();
1038
+ } else {
1039
+ jQuery(quiz_form_id).closest('.qmn_quiz_container').find('.pages_count').show();
1040
+ }
1041
+ } else {
1042
+ jQuery(quiz_form_id).closest('.qmn_quiz_container').find('.pages_count').hide();
1043
+ }
1044
  }
1045
+ jQuery(quiz_form_id).parent().find('.qmn_pagination').css('width', '100%');
1046
+ qmnInitProgressbarOnClick(quiz_id, slide_original_val, total_pages);
1047
+ jQuery(document).trigger('qsm_auto_previous_button_click_after', [quiz_form_id]);
 
 
 
 
 
 
 
 
 
 
 
 
 
1048
  }
1049
 
1050
  /**
1054
  * @param {int} total_page_number
1055
  * @returns Change progress bar on next and previous button click
1056
  */
1057
+ function qmnInitProgressbarOnClick(quiz_id, page_number, total_page_number) {
1058
+ if ('1' == qmn_quiz_data[quiz_id].progress_bar) {
1059
+ var qmn_total_questions = qmn_quiz_data[quiz_id].pagination.total_questions;
1060
+ var pagination = qmn_quiz_data[quiz_id].pagination.amount;
1061
+ total_page_number = Math.ceil(qmn_total_questions / pagination);
1062
+ total_page_number = total_page_number + 1; //Increase for quiz end section
1063
+ var animate_value = page_number / total_page_number;
1064
+ if (animate_value <= 1) {
1065
+ qmn_quiz_data[quiz_id].bar.animate(animate_value);
1066
+ var old_text = jQuery('#qsm_progress_bar_' + quiz_id).find('.progressbar-text').text().replace(' %', '');
1067
+ var new_text = Math.round(animate_value * 100);
1068
+ jQuery({
1069
+ Counter: old_text
1070
+ }).animate({
1071
+ Counter: new_text
1072
+ }, {
1073
+ duration: 1000,
1074
+ easing: 'swing',
1075
+ step: function () {
1076
+ jQuery('#qsm_progress_bar_' + quiz_id).find('.progressbar-text').text(Math.round(this.Counter) + ' %');
1077
+ }
1078
+ });
1079
+ }
1080
+ }
1081
  }
1082
 
1083
+ function qmnUpdatePageNumber(amount, quiz_form_id) {
1084
+ var current_page = +jQuery(quiz_form_id).closest('.qmn_quiz_container').find('.current_page_hidden').val();
1085
+ var total_pages = jQuery(quiz_form_id).closest('.qmn_quiz_container').find('.total_pages_hidden').val();
1086
  current_page += amount;
1087
  //jQuery( quiz_form_id ).siblings( '.qmn_pagination' ).find( " .qmn_page_counter_message" ).text( current_page + "/" + total_pages );
1088
  }
1089
 
1090
+ function qmnInitPagination(quiz_id) {
1091
+ var qmn_section_total = +qmn_quiz_data[quiz_id].pagination.total_questions;
1092
+ var qmn_total_pages = Math.ceil(qmn_section_total / +qmn_quiz_data[quiz_id].pagination.amount);
1093
+
1094
+ qmn_total_pages = qmn_total_pages + 1; //quiz begin
1095
+ qmn_total_pages = qmn_total_pages + 1; //quiz end
1096
+
1097
+ jQuery('#quizForm' + quiz_id).closest('.qmn_quiz_container').append('<div class="qmn_pagination border margin-bottom"></div>');
1098
+ jQuery('#quizForm' + quiz_id).closest('.qmn_quiz_container').find('.qmn_pagination').append('<input type="hidden" value="0" name="slide_number" class="slide_number_hidden" />')
1099
+ .append('<input type="hidden" value="0" name="current_page" class="current_page_hidden" />')
1100
+ .append('<input type="hidden" value="' + qmn_total_pages + '" name="total_pages" class="total_pages_hidden" />')
1101
+ .append('<input type="hidden" value="' + qmn_section_total + '" name="total_sections" class="total_sections_hidden" />')
1102
+ .append('<input type="hidden" value="0" name="previous_amount" class="previous_amount_hidden" />')
1103
+ .append('<a class="qmn_btn mlw_qmn_quiz_link mlw_previous" href="#">' + qmn_quiz_data[quiz_id].pagination.previous_text + '</a>')
1104
+ .append('<span class="qmn_page_message"></span>')
1105
+ .append('<div class="qmn_page_counter_message"></div>')
1106
+ .append('<div class="qsm-progress-bar" id="qsm_progress_bar_' + quiz_id + '" style="display:none;"><div class="progressbar-text"></div></div>')
1107
+ .append('<a class="qmn_btn mlw_qmn_quiz_link mlw_next" href="#">' + qmn_quiz_data[quiz_id].pagination.next_text + '</a>');
1108
+
1109
+ if ('1' == qmn_quiz_data[quiz_id].progress_bar) {
1110
+ jQuery(document).trigger('qsm_init_progressbar_before', [quiz_id, qmn_quiz_data]);
1111
+ jQuery('#quizForm' + quiz_id).closest('.qmn_quiz_container').find('.qsm-progress-bar').show();
1112
+ qmn_quiz_data[quiz_id].bar = new ProgressBar.Line('#qsm_progress_bar_' + quiz_id, {
1113
+ strokeWidth: 2,
1114
+ easing: 'easeInOut',
1115
+ duration: 500,
1116
+ color: '#3498db',
1117
+ trailColor: '#eee',
1118
+ trailWidth: 1,
1119
+ svgStyle: { width: '100%', height: '100%' },
1120
+ text: {
1121
+ style: {
1122
+ // color: '#999',
1123
+ position: 'absolute',
1124
+ padding: 0,
1125
+ margin: 0,
1126
+ top: 0,
1127
+ right: '10px',
1128
+ 'font-size': '13px',
1129
+ 'font-weight': 'bold',
1130
+ transform: null
1131
+ },
1132
+ autoStyleContainer: false
1133
+ },
1134
+ from: { color: '#3498db' },
1135
+ to: { color: '#ED6A5A' },
1136
+ step: function (state, bar) {
1137
+ }
1138
+ });
1139
+ jQuery(document).trigger('qsm_init_progressbar_after', [quiz_id, qmn_quiz_data]);
1140
+ }
1141
+
1142
+ jQuery(".mlw_next").click(function (event) {
1143
+ event.preventDefault();
1144
+ var quiz_id = +jQuery(this).closest('.qmn_quiz_container').find('.qmn_quiz_id').val();
1145
+ jQuery(document).trigger('qsm_auto_next_button_click_before', [quiz_id]);
1146
+ if (qmnValidatePage('quizForm' + quiz_id)) {
1147
+ qmnNextSlide(qmn_quiz_data[quiz_id].pagination.amount, 1, '#quizForm' + quiz_id);
1148
  }
1149
  });
1150
 
1151
+ jQuery(".mlw_previous").click(function (event) {
1152
  event.preventDefault();
1153
+ var quiz_id = +jQuery(this).closest('.qmn_quiz_container').find('.qmn_quiz_id').val();
1154
+ qmnPrevSlide(qmn_quiz_data[quiz_id].pagination.amount, 1, '#quizForm' + quiz_id);
1155
  });
1156
 
1157
+ if (qmn_quiz_data[quiz_id].first_page) {
1158
+ qmnNextSlide(1, 0, '#quizForm' + quiz_id);
1159
  } else {
1160
+ qmnNextSlide(qmn_quiz_data[quiz_id].pagination.amount, 0, '#quizForm' + quiz_id);
1161
  }
1162
 
1163
  }
1164
 
1165
+ function qmnSocialShare(network, mlw_qmn_social_text, mlw_qmn_title, facebook_id, share_url) {
1166
+ var sTop = window.screen.height / 2 - (218);
1167
+ var sLeft = window.screen.width / 2 - (313);
1168
  var sqShareOptions = "height=400,width=580,toolbar=0,status=0,location=0,menubar=0,directories=0,scrollbars=0,top=" + sTop + ",left=" + sLeft;
1169
  var pageUrl = window.location.href;
1170
+ var pageUrlEncoded = encodeURIComponent(share_url);
1171
  var url = '';
1172
+ if (network == 'facebook') {
1173
+ url = "https://www.facebook.com/dialog/feed?" + "display=popup&" + "app_id=" + facebook_id +
1174
  "&" + "link=" + pageUrlEncoded + "&" + "name=" + encodeURIComponent(mlw_qmn_social_text) +
1175
  "&" + "description=";
1176
  }
1177
+ if (network == 'twitter') {
1178
  url = "https://twitter.com/intent/tweet?text=" + encodeURIComponent(mlw_qmn_social_text);
1179
  }
1180
+ window.open(url, "Share", sqShareOptions);
1181
  return false;
1182
  }
1183
 
1184
+ jQuery(function () {
1185
+ jQuery('.qmn_quiz_container').tooltip();
1186
 
1187
+ jQuery('.qmn_quiz_container input').on('keypress', function (e) {
1188
+ if (e.which === 13) {
1189
  e.preventDefault();
1190
  }
1191
  });
1192
 
1193
+ jQuery(document).on('click', ".qsm-submit-btn", function (event) {
1194
  event.preventDefault();
1195
  var form = jQuery(this).closest('form')[0];
1196
+ qmnFormSubmit(form.id);
1197
  });
1198
 
1199
  jQuery(document).on('click', '.btn-reload-quiz', function (e) {
1220
  });
1221
  setInterval(qmnTimeTakenTimer, 1000);
1222
  MathJax.Hub.queue.Push(["Typeset", MathJax.Hub]);
1223
+
1224
+ // trigger fired on successfull retake quiz
1225
+ jQuery(document).trigger('qsm_retake_quiz', [quiz_id]);
1226
  },
1227
  error: function (errorThrown) {
1228
  console.log('error');
1230
  });
1231
  });
1232
 
1233
+ jQuery(document).on('change', '.qmn_radio_answers input', function (e) {
1234
  var quizID = jQuery(this).parents('.qsm-quiz-container').find('.qmn_quiz_id').val();
1235
+ if (qmn_quiz_data[quizID].enable_quick_result_mc == 1) {
1236
  var question_id = jQuery(this).attr('name').split('question')[1],
1237
+ value = jQuery(this).val(),
1238
+ $this = jQuery(this).parents('.quiz_section');
1239
  jQuery.ajax({
1240
  type: 'POST',
1241
  url: qmn_ajax_object.ajaxurl,
1243
  action: "qsm_get_question_quick_result",
1244
  question_id: question_id,
1245
  answer: value,
1246
+ show_correct_info: qmn_quiz_data[quizID].enable_quick_correct_answer_info
1247
  },
1248
  success: function (response) {
1249
  var data = jQuery.parseJSON(response);
1250
  $this.find('.quick-question-res-p').remove();
1251
  $this.find('.qsm-inline-correct-info').remove();
1252
  if (data.success == 'correct') {
1253
+ $this.append('<div style="color: green" class="quick-question-res-p">' + qmn_quiz_data[quizID].quick_result_correct_answer_text + '</div>')
1254
  $this.append('<div class="qsm-inline-correct-info">' + data.message + '</div>');
1255
  } else if (data.success == 'incorrect') {
1256
+ $this.append('<div style="color: red" class="quick-question-res-p">' + qmn_quiz_data[quizID].quick_result_wrong_answer_text + '</div>')
1257
  $this.append('<div class="qsm-inline-correct-info">' + data.message + '</div>');
1258
  }
1259
  MathJax.Hub.queue.Push(["Typeset", MathJax.Hub]);
1265
  }
1266
  });
1267
 
1268
+ // Autocomplete off
1269
+
1270
+ var quizID = jQuery('.qsm-quiz-container').find('.qmn_quiz_id').val();
1271
+ var $quizForm = QSM.getQuizForm(quizID);
1272
+ if (qmn_quiz_data[quizID].form_disable_autofill == 1) {
1273
+ jQuery('#quizForm' + quizID).attr('autocomplete', 'off');
1274
+ }
1275
+
1276
+
1277
 
1278
  // End Quiz If Wrong
1279
+ jQuery(document).on('change ', '.qmn_radio_answers input , .qmn_check_answers input , .qsm_select', function (e) {
1280
  var quizID = jQuery(this).parents('.qsm-quiz-container').find('.qmn_quiz_id').val();
1281
+ var $quizForm = QSM.getQuizForm(quizID);
1282
+ if (qmn_quiz_data[quizID].end_quiz_if_wrong == 1) {
1283
  var question_id = jQuery(this).attr('name').split('question')[1],
1284
+ value = jQuery(this).val(),
1285
+ $this = jQuery(this).parents('.quiz_section');
1286
  jQuery.ajax({
1287
  type: 'POST',
1288
  url: qmn_ajax_object.ajaxurl,
1290
  action: "qsm_get_question_quick_result",
1291
  question_id: question_id,
1292
  answer: value,
1293
+ show_correct_info: qmn_quiz_data[quizID].enable_quick_correct_answer_info
1294
  },
1295
  success: function (response) {
1296
  var data = jQuery.parseJSON(response);
1297
  $this.find('.quick-question-res-p').remove();
1298
  $this.find('.qsm-inline-correct-info').remove();
1299
  if (data.success == 'correct') {
1300
+
1301
  } else if (data.success == 'incorrect') {
 
 
1302
 
1303
+
1304
+
1305
+ $this.append('<div style="color: red" class="quick-question-res-p">' + qmn_quiz_data[quizID].quick_result_wrong_answer_text + '</div>')
1306
  $this.append('<div class="qsm-inline-correct-info">' + data.message + '</div>');
1307
 
1308
+ setTimeout(function () {
1309
+ $quizForm.closest('.qmn_quiz_container').find('.qsm-submit-btn').trigger('click');
1310
+ }, 1000);
1311
+
1312
 
 
1313
  }
1314
  MathJax.Hub.queue.Push(["Typeset", MathJax.Hub]);
1315
  },
1321
  });
1322
 
1323
  //Ajax upload file code
1324
+ jQuery('.quiz_section .mlw_answer_file_upload').on('change', function () {
1325
  var $this = jQuery(this);
1326
  var hidden_val = jQuery(this).parent('.quiz_section').find('.mlw_file_upload_hidden_path').val();
1327
  var file_data = jQuery(this).prop('files')[0];
1328
  var form_data = new FormData();
1329
  form_data.append('file', file_data);
1330
  form_data.append('action', 'qsm_upload_image_fd_question');
1331
+ var question_id = $this.parent('.quiz_section').find('.mlw_file_upload_hidden_value').attr("name").replace('question', '');
1332
  form_data.append('question_id', question_id);
1333
  $this.next('.loading-uploaded-file').show();
1334
  jQuery.ajax({
1341
  success: function (response) {
1342
  var obj = jQuery.parseJSON(response);
1343
  $this.next('.loading-uploaded-file').hide();
1344
+ if (obj.type == 'success') {
1345
  $this.next().next('.remove-uploaded-file').show();
1346
  $this.next().next().next('.mlw_file_upload_hidden_value').val(obj.file_url);
1347
  $this.parent('.quiz_section').find('.mlw_file_upload_hidden_path').val(obj.file_path);
1348
  $this.parent('.quiz_section').find('.mlw-file-upload-error-msg').hide();
1349
+ } else {
1350
  $this.parent('.quiz_section').find('.mlw-file-upload-error-msg').text('').text(obj.message);
1351
  $this.parent('.quiz_section').find('.mlw-file-upload-error-msg').show();
1352
  $this.parent('.quiz_section').find('.mlw_answer_file_upload').val('');
1353
  }
1354
+ // triggers after file uploads
1355
+ jQuery(document).trigger('qsm_after_file_upload', [$this.parent(), obj]);
1356
  }
1357
  });
1358
  return false;
1359
  });
1360
 
1361
  //Ajax remove file code
1362
+ jQuery('.quiz_section .remove-uploaded-file').on('click', function () {
1363
  var $this = jQuery(this);
1364
  var file_data = jQuery(this).parent('.quiz_section').find('.mlw_file_upload_hidden_path').val();
1365
  var form_data = new FormData();
1374
  processData: false,
1375
  success: function (response) {
1376
  var obj = jQuery.parseJSON(response);
1377
+ if (obj.type == 'success') {
1378
  $this.hide();
1379
  $this.parent('.quiz_section').find('.mlw_file_upload_hidden_value').val('');
1380
  $this.parent('.quiz_section').find('.mlw_file_upload_hidden_path').val('');
1381
  $this.parent('.quiz_section').find('.mlw_answer_file_upload').val('');
1382
  $this.parent('.quiz_section').find('.mlw-file-upload-error-msg').hide();
1383
+ } else {
1384
  $this.parent('.quiz_section').find('.mlw-file-upload-error-msg').text('').text(obj.message);
1385
  $this.parent('.quiz_section').find('.mlw-file-upload-error-msg').show();
1386
  }
1390
  });
1391
 
1392
  //Deselect all answer on select
1393
+ jQuery('.qsm-deselect-answer').click(function (e) {
1394
  e.preventDefault();
1395
  jQuery(this).parents('.quiz_section').find('input[type="radio"]').prop('checked', false);
1396
  jQuery(this).parents('.quiz_section').find('input[type="radio"][value="No Answer Provided"]').prop('checked', true);
1398
  });
1399
 
1400
  //Submit the form on popup click
1401
+ jQuery(document).on('click', '.submit-the-form', function (e) {
1402
  e.preventDefault();
1403
  // Triggger the click event on the quiz form's submit button.
1404
+ jQuery('.qsm-submit-btn').trigger('click');
1405
  jQuery('#modal-3').removeClass('is-open');
1406
  });
1407
 
1412
  var $container = jQuery('#quizForm' + quiz_id).closest('.qmn_quiz_container');
1413
  qsmScrollTo($container);
1414
  });
1415
+
1416
+ jQuery(document).on('keyup', '.mlwPhoneNumber', function (e) {
1417
+ this.value = this.value.replace(/[^- +()0-9\.]/g, '');
1418
+ });
1419
 
1420
  jQuery(document).on('click', '.qsm_social_share_link', function (e) {
1421
  e.preventDefault();
1426
  var url = '';
1427
  if (network == 'facebook') {
1428
  url = "https://www.facebook.com/dialog/feed?" + "display=popup&" + "app_id=" + social_id +
1429
+ "&" + "link=" + encodeURIComponent(share_url) + "&" + "name=" + social_text;
1430
  }
1431
  if (network == 'twitter') {
1432
  url = "https://twitter.com/intent/tweet?text=" + social_text;
1439
  });
1440
  });
1441
 
1442
+ var qsmTimerInterval = setInterval(qmnTimeTakenTimer, 1000);
1443
  var quizType = 'default';
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.1.16
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.1.16
13
  * @package QSM
14
  */
15
 
@@ -18,9 +18,9 @@ if ( ! defined( 'ABSPATH' ) ) {
18
  }
19
 
20
  define( 'QSM_PLUGIN_BASENAME', plugin_basename( __FILE__ ) );
21
- define( 'QSM_SUBMENU', __FILE__);
22
- define('QSM_PLUGIN_URL', plugin_dir_url( __FILE__ ));
23
- define( 'hide_qsm_adv', true);
24
 
25
  /**
26
  * This class is the main class of the plugin
@@ -31,13 +31,14 @@ define( 'hide_qsm_adv', true);
31
  */
32
  class MLWQuizMasterNext {
33
 
 
34
  /**
35
  * QSM Version Number
36
  *
37
  * @var string
38
  * @since 4.0.0
39
  */
40
- public $version = '7.1.16';
41
 
42
  /**
43
  * QSM Alert Manager Object
@@ -187,25 +188,25 @@ class MLWQuizMasterNext {
187
  add_action( 'admin_menu', array( $this, 'setup_admin_menu' ) );
188
  add_action( 'admin_head', array( $this, 'admin_head' ), 900 );
189
  add_action( 'init', array( $this, 'register_quiz_post_types' ) );
190
- add_action('plugins_loaded', array(&$this, 'qsm_load_textdomain'));
191
- add_action('admin_enqueue_scripts', array($this, 'qsm_admin_scripts_style'));
192
- add_action('admin_init', array($this, 'qsm_overide_old_setting_options'));
 
 
 
 
 
 
 
193
  }
194
-
195
- /**
196
- * @since 7.1.4
197
- */
198
- public function qsm_load_textdomain(){
199
- load_plugin_textdomain( 'quiz-master-next', false, dirname(plugin_basename(__FILE__)) . '/lang/');
200
- }
201
 
202
  /**
203
  * Loads admin scripts and style
204
- *
205
  * @since 7.1.16
206
  */
207
- public function qsm_admin_scripts_style($hook_prefix){
208
- if($hook_prefix == 'admin_page_mlw_quiz_options'){
209
  wp_enqueue_script( 'wp-tinymce' );
210
  }
211
  }
@@ -275,7 +276,7 @@ class MLWQuizMasterNext {
275
  'label' => $plural_name,
276
  'rewrite' => array( 'slug' => $cpt_slug ),
277
  'has_archive' => $has_archive,
278
- 'supports' => array( 'title', 'author', 'comments', 'thumbnail' )
279
  );
280
 
281
  // Registers post type.
@@ -292,25 +293,25 @@ class MLWQuizMasterNext {
292
  */
293
  public function setup_admin_menu() {
294
  if ( function_exists( 'add_menu_page' ) ) {
295
- global $qsm_quiz_list_page;
296
  $qsm_dashboard_page = add_menu_page( 'Quiz And Survey Master', __( 'QSM', 'quiz-master-next' ), 'edit_posts', 'qsm_dashboard', 'qsm_generate_dashboard_page', 'dashicons-feedback' );
297
- add_submenu_page( 'qsm_dashboard', __( 'Dashboard', 'quiz-master-next' ), __( 'Dashboard', 'quiz-master-next' ), 'edit_posts', 'qsm_dashboard', 'qsm_generate_dashboard_page' );
298
- $qsm_quiz_list_page = add_submenu_page( 'qsm_dashboard', __( 'Quizzes/Surveys', 'quiz-master-next' ), __( 'Quizzes/Surveys', 'quiz-master-next' ), 'edit_posts', 'mlw_quiz_list', 'qsm_generate_quizzes_surveys_page' );
299
- add_action("load-$qsm_quiz_list_page", 'qsm_generate_quizzes_surveys_page_screen_options');
300
- add_submenu_page( NULL, __( 'Settings', 'quiz-master-next' ), __( 'Settings', 'quiz-master-next' ), 'edit_posts', 'mlw_quiz_options', 'qsm_generate_quiz_options' );
301
  add_submenu_page( 'qsm_dashboard', __( 'Results', 'quiz-master-next' ), __( 'Results', 'quiz-master-next' ), 'moderate_comments', 'mlw_quiz_results', 'qsm_generate_admin_results_page' );
302
- add_submenu_page( NULL, __( 'Result Details', 'quiz-master-next' ), __( 'Result Details', 'quiz-master-next' ), 'moderate_comments', 'qsm_quiz_result_details', 'qsm_generate_result_details' );
303
  add_submenu_page( 'qsm_dashboard', __( 'Settings', 'quiz-master-next' ), __( 'Settings', 'quiz-master-next' ), 'manage_options', 'qmn_global_settings', array( 'QMNGlobalSettingsPage', 'display_page' ) );
304
  add_submenu_page( 'qsm_dashboard', __( 'Tools', 'quiz-master-next' ), __( 'Tools', 'quiz-master-next' ), 'manage_options', 'qsm_quiz_tools', 'qsm_generate_quiz_tools' );
305
  add_submenu_page( 'qsm_dashboard', __( 'Stats', 'quiz-master-next' ), __( 'Stats', 'quiz-master-next' ), 'moderate_comments', 'qmn_stats', 'qmn_generate_stats_page' );
306
  add_submenu_page( 'qsm_dashboard', __( 'Addon Settings', 'quiz-master-next' ), '<span style="color:#f39c12;">' . __( 'Addon Settings', 'quiz-master-next' ) . '</span>', 'moderate_comments', 'qmn_addons', 'qmn_addons_page' );
307
- add_submenu_page( 'qsm_dashboard', __( 'Get a Free Addon', 'quiz-master-next' ), '<span style="color:#f39c12;">' . esc_html__( 'Get a Free Addon!', 'quiz-master-next' ) . '</span>', 'moderate_comments', 'qsm-free-addon', 'qsm_display_optin_page' );
308
- add_submenu_page( 'qsm_dashboard', __( 'Roadmap', 'quiz-master-next' ), __( 'Roadmap', 'quiz-master-next' ), 'moderate_comments', 'qsm_roadmap_page', 'qsm_generate_roadmap_page' );
309
- // Merging Help page in About page
310
- // add_submenu_page( 'qsm_dashboard', __( 'About', 'quiz-master-next' ), __( 'About', 'quiz-master-next' ), 'moderate_comments', 'qsm_about_page', 'qsm_generate_about_page' );
311
- add_submenu_page( 'qsm_dashboard', __( 'About', 'quiz-master-next' ), __( 'About', 'quiz-master-next' ), 'moderate_comments', 'qsm_quiz_about', 'qsm_generate_about_page' );
312
- //Register screen option for dashboard page
313
- add_action("screen_settings", "qsm_dashboard_screen_options", 10, 2);
314
  }
315
  }
316
 
@@ -328,22 +329,23 @@ class MLWQuizMasterNext {
328
  }
329
  /**
330
  * Overide Old Quiz Settings Options
 
331
  * @since 7.1.16
332
  * @return void
333
  */
334
- public function qsm_overide_old_setting_options()
335
- {
336
  $settings = (array) get_option( 'qmn-settings' );
337
- $facebook_app_id = $settings['facebook_app_id'];
338
- if($facebook_app_id == '483815031724529')
339
- {
340
- $settings['facebook_app_id'] = '594986844960937';
341
- update_option( 'qmn-settings', $settings );
 
342
  }
 
343
  }
344
  }
345
 
346
  global $mlwQuizMasterNext;
347
  $mlwQuizMasterNext = new MLWQuizMasterNext();
348
- register_activation_hook( __FILE__, array( 'QSM_Install', 'install' ) );
349
- ?>
2
  /**
3
  * Plugin Name: Quiz And Survey Master
4
  * Description: Easily and quickly add quizzes and surveys to your website.
5
+ * Version: 7.1.17
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.1.17
13
  * @package QSM
14
  */
15
 
18
  }
19
 
20
  define( 'QSM_PLUGIN_BASENAME', plugin_basename( __FILE__ ) );
21
+ define( 'QSM_SUBMENU', __FILE__ );
22
+ define( 'QSM_PLUGIN_URL', plugin_dir_url( __FILE__ ) );
23
+ define( 'hide_qsm_adv', true );
24
 
25
  /**
26
  * This class is the main class of the plugin
31
  */
32
  class MLWQuizMasterNext {
33
 
34
+
35
  /**
36
  * QSM Version Number
37
  *
38
  * @var string
39
  * @since 4.0.0
40
  */
41
+ public $version = '7.1.17';
42
 
43
  /**
44
  * QSM Alert Manager Object
188
  add_action( 'admin_menu', array( $this, 'setup_admin_menu' ) );
189
  add_action( 'admin_head', array( $this, 'admin_head' ), 900 );
190
  add_action( 'init', array( $this, 'register_quiz_post_types' ) );
191
+ add_action( 'plugins_loaded', array( &$this, 'qsm_load_textdomain' ) );
192
+ add_action( 'admin_enqueue_scripts', array( $this, 'qsm_admin_scripts_style' ) );
193
+ add_action( 'admin_init', array( $this, 'qsm_overide_old_setting_options' ) );
194
+ }
195
+
196
+ /**
197
+ * @since 7.1.4
198
+ */
199
+ public function qsm_load_textdomain() {
200
+ load_plugin_textdomain( 'quiz-master-next', false, dirname( plugin_basename( __FILE__ ) ) . '/lang/' );
201
  }
 
 
 
 
 
 
 
202
 
203
  /**
204
  * Loads admin scripts and style
205
+ *
206
  * @since 7.1.16
207
  */
208
+ public function qsm_admin_scripts_style( $hook_prefix ) {
209
+ if ( $hook_prefix == 'admin_page_mlw_quiz_options' ) {
210
  wp_enqueue_script( 'wp-tinymce' );
211
  }
212
  }
276
  'label' => $plural_name,
277
  'rewrite' => array( 'slug' => $cpt_slug ),
278
  'has_archive' => $has_archive,
279
+ 'supports' => array( 'title', 'author', 'comments', 'thumbnail' ),
280
  );
281
 
282
  // Registers post type.
293
  */
294
  public function setup_admin_menu() {
295
  if ( function_exists( 'add_menu_page' ) ) {
296
+ global $qsm_quiz_list_page;
297
  $qsm_dashboard_page = add_menu_page( 'Quiz And Survey Master', __( 'QSM', 'quiz-master-next' ), 'edit_posts', 'qsm_dashboard', 'qsm_generate_dashboard_page', 'dashicons-feedback' );
298
+ add_submenu_page( 'qsm_dashboard', __( 'Dashboard', 'quiz-master-next' ), __( 'Dashboard', 'quiz-master-next' ), 'edit_posts', 'qsm_dashboard', 'qsm_generate_dashboard_page' );
299
+ $qsm_quiz_list_page = add_submenu_page( 'qsm_dashboard', __( 'Quizzes/Surveys', 'quiz-master-next' ), __( 'Quizzes/Surveys', 'quiz-master-next' ), 'edit_posts', 'mlw_quiz_list', 'qsm_generate_quizzes_surveys_page' );
300
+ add_action( "load-$qsm_quiz_list_page", 'qsm_generate_quizzes_surveys_page_screen_options' );
301
+ add_submenu_page( null, __( 'Settings', 'quiz-master-next' ), __( 'Settings', 'quiz-master-next' ), 'edit_posts', 'mlw_quiz_options', 'qsm_generate_quiz_options' );
302
  add_submenu_page( 'qsm_dashboard', __( 'Results', 'quiz-master-next' ), __( 'Results', 'quiz-master-next' ), 'moderate_comments', 'mlw_quiz_results', 'qsm_generate_admin_results_page' );
303
+ add_submenu_page( null, __( 'Result Details', 'quiz-master-next' ), __( 'Result Details', 'quiz-master-next' ), 'moderate_comments', 'qsm_quiz_result_details', 'qsm_generate_result_details' );
304
  add_submenu_page( 'qsm_dashboard', __( 'Settings', 'quiz-master-next' ), __( 'Settings', 'quiz-master-next' ), 'manage_options', 'qmn_global_settings', array( 'QMNGlobalSettingsPage', 'display_page' ) );
305
  add_submenu_page( 'qsm_dashboard', __( 'Tools', 'quiz-master-next' ), __( 'Tools', 'quiz-master-next' ), 'manage_options', 'qsm_quiz_tools', 'qsm_generate_quiz_tools' );
306
  add_submenu_page( 'qsm_dashboard', __( 'Stats', 'quiz-master-next' ), __( 'Stats', 'quiz-master-next' ), 'moderate_comments', 'qmn_stats', 'qmn_generate_stats_page' );
307
  add_submenu_page( 'qsm_dashboard', __( 'Addon Settings', 'quiz-master-next' ), '<span style="color:#f39c12;">' . __( 'Addon Settings', 'quiz-master-next' ) . '</span>', 'moderate_comments', 'qmn_addons', 'qmn_addons_page' );
308
+ add_submenu_page( 'qsm_dashboard', __( 'Get a Free Addon', 'quiz-master-next' ), '<span style="color:#f39c12;">' . esc_html__( 'Get a Free Addon!', 'quiz-master-next' ) . '</span>', 'moderate_comments', 'qsm-free-addon', 'qsm_display_optin_page' );
309
+ add_submenu_page( 'qsm_dashboard', __( 'Roadmap', 'quiz-master-next' ), __( 'Roadmap', 'quiz-master-next' ), 'moderate_comments', 'qsm_roadmap_page', 'qsm_generate_roadmap_page' );
310
+ // Merging Help page in About page
311
+ // add_submenu_page( 'qsm_dashboard', __( 'About', 'quiz-master-next' ), __( 'About', 'quiz-master-next' ), 'moderate_comments', 'qsm_about_page', 'qsm_generate_about_page' );
312
+ add_submenu_page( 'qsm_dashboard', __( 'About', 'quiz-master-next' ), __( 'About', 'quiz-master-next' ), 'moderate_comments', 'qsm_quiz_about', 'qsm_generate_about_page' );
313
+ // Register screen option for dashboard page
314
+ add_action( 'screen_settings', 'qsm_dashboard_screen_options', 10, 2 );
315
  }
316
  }
317
 
329
  }
330
  /**
331
  * Overide Old Quiz Settings Options
332
+ *
333
  * @since 7.1.16
334
  * @return void
335
  */
336
+ public function qsm_overide_old_setting_options() {
 
337
  $settings = (array) get_option( 'qmn-settings' );
338
+ if ( isset( $settings['facebook_app_id'] ) ) {
339
+ $facebook_app_id = $settings['facebook_app_id'];
340
+ if ( $facebook_app_id == '483815031724529' ) {
341
+ $settings['facebook_app_id'] = '594986844960937';
342
+ update_option( 'qmn-settings', $settings );
343
+ }
344
  }
345
+
346
  }
347
  }
348
 
349
  global $mlwQuizMasterNext;
350
  $mlwQuizMasterNext = new MLWQuizMasterNext();
351
+ register_activation_hook( __FILE__, array( 'QSM_Install', 'install' ) );
 
php/admin/options-page-text-tab.php CHANGED
@@ -164,7 +164,11 @@ function qsm_get_question_text_message(){
164
  $allowed_text = '';
165
  if( isset( $quiz_text_arr[$key] ) ){
166
  $variable_list = qsm_text_template_variable_list();
167
- foreach ( $quiz_text_arr[$key]['variables'] as $variable ) {
 
 
 
 
168
  $allowed_text .= '<span class="qsm-text-template-span">';
169
  $allowed_text .= '<button class="button button-default">'. $variable .'</button>';
170
  if( isset( $variable_list[ $variable ] ) ){
164
  $allowed_text = '';
165
  if( isset( $quiz_text_arr[$key] ) ){
166
  $variable_list = qsm_text_template_variable_list();
167
+ /**
168
+ * Filter allowed variables for Text Tab options.
169
+ */
170
+ $quiz_text_allowed_variables = apply_filters('qsm_text_allowed_variables', $quiz_text_arr[$key]['variables'], $key);
171
+ foreach ($quiz_text_allowed_variables as $variable ) {
172
  $allowed_text .= '<span class="qsm-text-template-span">';
173
  $allowed_text .= '<button class="button button-default">'. $variable .'</button>';
174
  if( isset( $variable_list[ $variable ] ) ){
php/classes/class-qmn-plugin-helper.php CHANGED
@@ -1,15 +1,18 @@
1
  <?php
2
- if ( ! defined( 'ABSPATH' ) ) exit;
 
 
3
 
4
  /**
5
- * This class is a helper class to be used for extending the plugin
6
- *
7
- * This class contains many functions for extending the plugin
8
- *
9
- * @since 4.0.0
10
- */
11
  class QMNPluginHelper {
12
 
 
13
  /**
14
  * Addon Page tabs array
15
  *
@@ -67,13 +70,13 @@ class QMNPluginHelper {
67
  public $quiz_templates = array();
68
 
69
  /**
70
- * Main Construct Function
71
- *
72
- * Call functions within class
73
- *
74
- * @since 4.0.0
75
- * @return void
76
- */
77
  public function __construct() {
78
  add_action( 'wp_ajax_qmn_question_type_change', array( $this, 'get_question_type_edit_content' ) );
79
  }
@@ -98,17 +101,17 @@ class QMNPluginHelper {
98
  $mlwQuizMasterNext->quizCreator->set_id( $quiz_id );
99
  $mlwQuizMasterNext->quiz_settings->prepare_quiz( $quiz_id );
100
 
101
- return True;
102
  }
103
 
104
  /**
105
  * Retrieves all quizzes.
106
  *
107
- * @param bool $include_deleted If set to true, returned array will include all deleted quizzes
108
  * @param string $order_by The column the quizzes should be ordered by
109
  * @param string $order whether the $order_by should be ordered as ascending or decending. Can be "ASC" or "DESC"
110
- * @param arr $user_role role of current user
111
- * @param int $user_id Get the quiz based on user id
112
  * @return array All of the quizzes as a numerical array of objects
113
  */
114
  public function get_quizzes( $include_deleted = false, $order_by = 'quiz_id', $order = 'DESC', $user_role = array(), $user_id = '', $limit = '', $offset = '', $where = '' ) {
@@ -133,42 +136,42 @@ class QMNPluginHelper {
133
  case 'quiz_taken':
134
  $order_field = 'quiz_taken';
135
  break;
136
-
137
  case 'title':
138
  $order_field = 'quiz_name';
139
  break;
140
-
141
  default:
142
  $order_field = 'quiz_id';
143
  break;
144
  }
145
 
146
  // Should we include deleted?
147
- $delete = "WHERE deleted=0";
148
- if( $where != '' ){
149
- $delete = $delete . ' AND ' . $where;
150
- }
151
  if ( $include_deleted ) {
152
  $delete = '';
153
  }
154
- $user_str = '';
155
- if ( in_array( 'author', (array) $user_role ) ) {
156
- if( $user_id && $delete == '' ){
157
- $user_str = "WHERE quiz_author_id = '$user_id'";
158
- }else if( $user_id && $delete !== '' ){
159
- $user_str = " AND quiz_author_id = '$user_id'";
160
- }
161
- }
162
- if( $where != '' && $user_str != '' ){
163
- $user_str = $user_str . ' AND ' . $where;
164
- }
165
- $where_str = '';
166
- if( $user_str == '' && $delete === '' && $where != '' ){
167
- $where_str = "WHERE $where";
168
- }
169
- if($limit != ''){
170
- $limit = ' limit ' . $offset . ', ' . $limit;
171
- }
172
  // Get quizzes and return them
173
  $quizzes = $wpdb->get_results( stripslashes( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}mlw_quizzes %1s %2s %3s ORDER BY %4s %5s %6s", $delete, $user_str, $where_str, $order_field, $order_direction, $limit ) ) );
174
  return $quizzes;
@@ -186,60 +189,59 @@ class QMNPluginHelper {
186
  }
187
 
188
  /**
189
- * Retrieves a setting value from a section based on name of section and setting
190
- *
191
- * @since 5.0.0
192
- * @param string $section The name of the section the setting is registered in
193
- * @param string $setting The name of the setting whose value we need to retrieve
194
- * @param mixed $default What we need to return if no setting exists with given $setting
195
- * @return $mixed Value set for $setting or $default if setting does not exist
196
- */
197
- public function get_section_setting( $section, $setting, $default = false ) {
198
  global $mlwQuizMasterNext;
199
- return apply_filters('qsm_section_setting_text', $mlwQuizMasterNext->quiz_settings->get_section_setting( $section, $setting, $default ));
200
  }
201
 
202
  /**
203
- * Retrieves setting value based on name of setting
204
- *
205
- * @since 4.0.0
206
- * @param string $setting The name of the setting whose value we need to retrieve
207
- * @param mixed $default What we need to return if no setting exists with given $setting
208
- * @return $mixed Value set for $setting or $default if setting does not exist
209
- */
210
  public function get_quiz_setting( $setting, $default = false ) {
211
  global $mlwQuizMasterNext;
212
  return $mlwQuizMasterNext->quiz_settings->get_setting( $setting, $default );
213
  }
214
 
215
-
216
  /**
217
- * Updates a settings value, adding it if it didn't already exist
218
- *
219
- * @since 4.0.0
220
- * @param string $setting The name of the setting whose value we need to retrieve
221
- * @param mixed $value The value that needs to be stored for the setting
222
- * @return bool True if successful or false if fails
223
- */
224
  public function update_quiz_setting( $setting, $value ) {
225
  global $mlwQuizMasterNext;
226
  return $mlwQuizMasterNext->quiz_settings->update_setting( $setting, $value );
227
  }
228
 
229
  /**
230
- * Outputs the section of input fields
231
- *
232
- * @since 5.0.0
233
- * @since 7.0 Added new parameter settings_fields for default setting
234
- * @param string $section The section that the settings were registered with
235
- */
236
- public function generate_settings_section( $section = 'quiz_options', $settings_fields = array() ) {
237
- global $mlwQuizMasterNext;
238
- if( empty( $settings_fields ) ){
239
- $settings_fields = $mlwQuizMasterNext->quiz_settings->load_setting_fields( $section );
240
- }
241
- QSM_Fields::generate_section( $settings_fields, $section );
242
- }
243
 
244
  /**
245
  * Registers Quiz Templates
@@ -249,10 +251,10 @@ class QMNPluginHelper {
249
  * @param $file_path String of the path to the css file
250
  */
251
  public function register_quiz_template( $name, $file_path ) {
252
- $slug = strtolower(str_replace( " ", "-", $name));
253
- $this->quiz_templates[$slug] = array(
254
- "name" => $name,
255
- "path" => $file_path
256
  );
257
  }
258
 
@@ -266,87 +268,84 @@ class QMNPluginHelper {
266
  public function get_quiz_templates( $slug = null ) {
267
  if ( is_null( $slug ) ) {
268
  return $this->quiz_templates;
269
- } elseif ( isset( $this->quiz_templates[$slug] ) ) {
270
- return $this->quiz_templates[$slug];
271
  } else {
272
  return false;
273
  }
274
  }
275
 
276
  /**
277
- * Register Question Types
278
- *
279
- * Adds a question type to the question type array using the parameters given
280
- *
281
- * @since 4.0.0
282
- * @param string $name The name of the Question Type which will be shown when selecting type
283
- * @param string $display_function The name of the function to call when displaying the question
284
- * @param bool $graded Tells the plugin if this question is graded or not. This will affect scoring.
285
- * @param string $review_function The name of the function to call when scoring the question
286
- * @param string $slug The slug of the question type to be stored with question in database
287
- * @return void
288
- */
289
- public function register_question_type($name, $display_function, $graded, $review_function = null, $edit_args = null, $save_edit_function = null, $slug = null)
290
- {
291
- if (is_null($slug)) {
292
- $slug = strtolower(str_replace( " ", "-", $name));
293
  } else {
294
- $slug = strtolower(str_replace( " ", "-", $slug));
295
  }
296
- if ( is_null( $edit_args ) || !is_array( $edit_args ) ) {
297
  $validated_edit_function = array(
298
- 'inputs' => array(
299
  'question',
300
  'answer',
301
  'hint',
302
  'correct_info',
303
  'comments',
304
  'category',
305
- 'required'
306
  ),
307
- 'information' => '',
308
  'extra_inputs' => array(),
309
- 'function' => ''
310
  );
311
  } else {
312
  $validated_edit_function = array(
313
- 'inputs' => $edit_args['inputs'],
314
- 'information' => $edit_args['information'],
315
  'extra_inputs' => $edit_args['extra_inputs'],
316
- 'function' => $edit_args['function']
317
  );
318
  }
319
  if ( is_null( $save_edit_function ) ) {
320
  $save_edit_function = '';
321
  }
322
- $new_type = array(
323
- 'name' => $name,
324
  'display' => $display_function,
325
- 'review' => $review_function,
326
- 'graded' => $graded,
327
- 'edit' => $validated_edit_function,
328
- 'save' => $save_edit_function,
329
- 'slug' => $slug
330
  );
331
  $this->question_types[] = $new_type;
332
  }
333
 
334
  /**
335
- * Retrieves List Of Question Types
336
- *
337
- * retrieves a list of the slugs and names of the question types
338
- *
339
- * @since 4.0.0
340
- * @return array An array which contains the slug and name of question types that have been registered
341
- */
342
- public function get_question_type_options()
343
- {
344
  $type_array = array();
345
- foreach($this->question_types as $type)
346
- {
347
  $type_array[] = array(
348
- 'slug' => $type["slug"],
349
- 'name' => $type["name"]
350
  );
351
  }
352
  return $type_array;
@@ -354,114 +353,98 @@ class QMNPluginHelper {
354
 
355
  public function get_question_type_edit_fields() {
356
  $type_array = array();
357
- foreach($this->question_types as $type)
358
- {
359
- $type_array[$type["slug"]] = $type["edit"];
360
  }
361
  return $type_array;
362
  }
363
 
364
  /**
365
- * Displays A Question
366
- *
367
- * Retrieves the question types display function and creates the HTML for the question
368
- *
369
- * @since 4.0.0
370
- * @param string $slug The slug of the question type that the question is
371
- * @param int $question_id The id of the question
372
- * @param array $quiz_options An array of the columns of the quiz row from the database
373
- * @return string The HTML for the question
374
- */
375
- public function display_question($slug, $question_id, $quiz_options)
376
- {
377
  $display = '';
378
  global $wpdb;
379
  global $qmn_total_questions;
380
- $question = $wpdb->get_row($wpdb->prepare("SELECT * FROM ".$wpdb->prefix."mlw_questions WHERE question_id=%d", intval($question_id)));
381
- $answers = array();
382
- if (is_serialized($question->answer_array) && is_array(@unserialize($question->answer_array)))
383
- {
384
- $answers = @unserialize($question->answer_array);
385
- }
386
- else
387
- {
388
- $mlw_answer_array_correct = array(0, 0, 0, 0, 0, 0);
389
- $mlw_answer_array_correct[$question->correct_answer-1] = 1;
390
  $answers = array(
391
- array($question->answer_one, $question->answer_one_points, $mlw_answer_array_correct[0]),
392
- array($question->answer_two, $question->answer_two_points, $mlw_answer_array_correct[1]),
393
- array($question->answer_three, $question->answer_three_points, $mlw_answer_array_correct[2]),
394
- array($question->answer_four, $question->answer_four_points, $mlw_answer_array_correct[3]),
395
- array($question->answer_five, $question->answer_five_points, $mlw_answer_array_correct[4]),
396
- array($question->answer_six, $question->answer_six_points, $mlw_answer_array_correct[5]));
 
397
  }
398
  if ( 2 == $quiz_options->randomness_order || 3 == $quiz_options->randomness_order ) {
399
  shuffle( $answers );
400
- }
401
- foreach($this->question_types as $type)
402
- {
403
- if ($type["slug"] == strtolower(str_replace( " ", "-", $slug)))
404
- {
405
- if ($type["graded"])
406
- {
407
  $qmn_total_questions += 1;
408
- if ($quiz_options->question_numbering == 1)
409
- {
410
  $display .= "<span class='mlw_qmn_question_number'>$qmn_total_questions. </span>";
411
  }
412
  }
413
- if($quiz_options->show_category_on_front && $question->category != ''){
414
- $display .= '<div class="quiz-cat">[ ' . $question->category .' ]</div>';
415
- }
416
- $display .= call_user_func($type['display'], intval($question_id), $question->question_name, $answers);
417
  }
418
  }
419
  return $display;
420
  }
421
 
422
  /**
423
- * Calculates Score For Question
424
- *
425
- * Calculates the score for the question based on the question type
426
- *
427
- * @since 4.0.0
428
- * @param string $slug The slug of the question type that the question is
429
- * @param int $question_id The id of the question
430
- * @return array An array of the user's score from the question
431
- */
432
- public function display_review($slug, $question_id)
433
- {
434
  $results_array = array();
435
  global $wpdb;
436
- $question = $wpdb->get_row($wpdb->prepare("SELECT * FROM ".$wpdb->prefix."mlw_questions WHERE question_id=%d", intval($question_id)));
437
- $answers = array();
438
- if (is_serialized($question->answer_array) && is_array(@unserialize($question->answer_array)))
439
- {
440
- $answers = @unserialize($question->answer_array);
441
- }
442
- else
443
- {
444
- $mlw_answer_array_correct = array(0, 0, 0, 0, 0, 0);
445
- $mlw_answer_array_correct[$question->correct_answer-1] = 1;
446
  $answers = array(
447
- array($question->answer_one, $question->answer_one_points, $mlw_answer_array_correct[0]),
448
- array($question->answer_two, $question->answer_two_points, $mlw_answer_array_correct[1]),
449
- array($question->answer_three, $question->answer_three_points, $mlw_answer_array_correct[2]),
450
- array($question->answer_four, $question->answer_four_points, $mlw_answer_array_correct[3]),
451
- array($question->answer_five, $question->answer_five_points, $mlw_answer_array_correct[4]),
452
- array($question->answer_six, $question->answer_six_points, $mlw_answer_array_correct[5]));
 
453
  }
454
- foreach($this->question_types as $type)
455
- {
456
- if ($type["slug"] == strtolower(str_replace( " ", "-", $slug)))
457
- {
458
- if (!is_null($type["review"]))
459
- {
460
- $results_array = call_user_func($type['review'], intval($question_id), $question->question_name, $answers);
461
- }
462
- else
463
- {
464
- $results_array = array('null_review' => true);
465
  }
466
  }
467
  }
@@ -469,99 +452,90 @@ class QMNPluginHelper {
469
  }
470
 
471
  /**
472
- * Retrieves A Question Setting
473
- *
474
- * Retrieves a setting stored in the question settings array
475
- *
476
- * @since 4.0.0
477
- * @param int $question_id The id of the question
478
- * @param string $setting The name of the setting
479
- * @return string The value stored for the setting
480
- */
481
- public function get_question_setting($question_id, $setting)
482
- {
483
  global $wpdb;
484
  $qmn_settings_array = '';
485
- $settings = $wpdb->get_var( $wpdb->prepare( "SELECT question_settings FROM " . $wpdb->prefix . "mlw_questions WHERE question_id=%d", $question_id ) );
486
- if (is_serialized($settings) && is_array(@unserialize($settings)))
487
- {
488
- $qmn_settings_array = @unserialize($settings);
489
  }
490
- if (is_array($qmn_settings_array) && isset($qmn_settings_array[$setting]))
491
- {
492
- return $qmn_settings_array[$setting];
493
- }
494
- else
495
- {
496
  return '';
497
  }
498
  }
499
 
500
  /**
501
- * Registers Addon Settings Tab
502
- *
503
- * Registers a new tab on the addon settings page
504
- *
505
- * @since 4.0.0
506
- * @param string $title The name of the tab
507
- * @param string $function The function that displays the tab's content
508
- * @return void
509
- */
510
- public function register_addon_settings_tab($title, $function)
511
- {
512
- $slug = strtolower(str_replace( " ", "-", $title));
513
- $new_tab = array(
514
- 'title' => $title,
515
  'function' => $function,
516
- 'slug' => $slug
517
  );
518
  $this->addon_tabs[] = $new_tab;
519
  }
520
 
521
  /**
522
- * Retrieves Addon Settings Tab Array
523
- *
524
- * Retrieves the array of titles and functions of the registered tabs
525
- *
526
- * @since 4.0.0
527
- * @return array The array of registered tabs
528
- */
529
- public function get_addon_tabs()
530
- {
531
  return $this->addon_tabs;
532
  }
533
 
534
  /**
535
- * Registers Stats Tab
536
- *
537
- * Registers a new tab on the stats page
538
- *
539
- * @since 4.3.0
540
- * @param string $title The name of the tab
541
- * @param string $function The function that displays the tab's content
542
- * @return void
543
- */
544
- public function register_stats_settings_tab($title, $function)
545
- {
546
- $slug = strtolower(str_replace( " ", "-", $title));
547
- $new_tab = array(
548
- 'title' => $title,
549
  'function' => $function,
550
- 'slug' => $slug
551
  );
552
  $this->stats_tabs[] = $new_tab;
553
  }
554
 
555
  /**
556
- * Retrieves Stats Tab Array
557
- *
558
- * Retrieves the array of titles and functions of the registered tabs
559
- *
560
- * @since 4.3.0
561
- * @return array The array of registered tabs
562
- */
563
- public function get_stats_tabs()
564
- {
565
  return $this->stats_tabs;
566
  }
567
 
@@ -575,12 +549,12 @@ class QMNPluginHelper {
575
  * @param string $function The function that displays the tab's content
576
  * @return void
577
  */
578
- public function register_admin_results_tab( $title, $function) {
579
- $slug = strtolower( str_replace( " ", "-", $title ) );
580
- $new_tab = array(
581
- 'title' => $title,
582
  'function' => $function,
583
- 'slug' => $slug
584
  );
585
  $this->admin_results_tabs[] = $new_tab;
586
  }
@@ -598,71 +572,66 @@ class QMNPluginHelper {
598
  }
599
 
600
  /**
601
- * Registers Results Tab
602
- *
603
- * Registers a new tab on the results page
604
- *
605
- * @since 4.1.0
606
- * @param string $title The name of the tab
607
- * @param string $function The function that displays the tab's content
608
- * @return void
609
- */
610
- public function register_results_settings_tab($title, $function)
611
- {
612
- $slug = strtolower(str_replace( " ", "-", $title));
613
- $new_tab = array(
614
- 'title' => $title,
615
  'function' => $function,
616
- 'slug' => $slug
617
  );
618
  $this->results_tabs[] = $new_tab;
619
  }
620
 
621
  /**
622
- * Retrieves Results Tab Array
623
- *
624
- * Retrieves the array of titles and functions of the registered tabs
625
- *
626
- * @since 4.1.0
627
- * @return array The array of registered tabs
628
- */
629
- public function get_results_tabs()
630
- {
631
  return $this->results_tabs;
632
  }
633
 
634
  /**
635
- * Registers Quiz Settings Tab
636
- *
637
- * Registers a new tab on the quiz settings page
638
- *
639
- * @since 4.0.0
640
- * @param string $title The name of the tab
641
- * @param string $function The function that displays the tab's content
642
- * @return void
643
- */
644
- public function register_quiz_settings_tabs($title, $function)
645
- {
646
- $slug = strtolower(str_replace( " ", "-", $title));
647
- $new_tab = array(
648
- 'title' => $title,
649
  'function' => $function,
650
- 'slug' => $slug
651
  );
652
  $this->settings_tabs[] = $new_tab;
653
  }
654
 
655
  /**
656
- * Echos Registered Tabs Title Link
657
- *
658
- * Echos the title link of the registered tabs
659
- *
660
- * @since 4.0.0
661
- * @return array The array of registered tabs
662
- */
663
- public function get_settings_tabs()
664
- {
665
  return $this->settings_tabs;
666
  }
667
- }
668
- ?>
1
  <?php
2
+ if ( ! defined( 'ABSPATH' ) ) {
3
+ exit;
4
+ }
5
 
6
  /**
7
+ * This class is a helper class to be used for extending the plugin
8
+ *
9
+ * This class contains many functions for extending the plugin
10
+ *
11
+ * @since 4.0.0
12
+ */
13
  class QMNPluginHelper {
14
 
15
+
16
  /**
17
  * Addon Page tabs array
18
  *
70
  public $quiz_templates = array();
71
 
72
  /**
73
+ * Main Construct Function
74
+ *
75
+ * Call functions within class
76
+ *
77
+ * @since 4.0.0
78
+ * @return void
79
+ */
80
  public function __construct() {
81
  add_action( 'wp_ajax_qmn_question_type_change', array( $this, 'get_question_type_edit_content' ) );
82
  }
101
  $mlwQuizMasterNext->quizCreator->set_id( $quiz_id );
102
  $mlwQuizMasterNext->quiz_settings->prepare_quiz( $quiz_id );
103
 
104
+ return true;
105
  }
106
 
107
  /**
108
  * Retrieves all quizzes.
109
  *
110
+ * @param bool $include_deleted If set to true, returned array will include all deleted quizzes
111
  * @param string $order_by The column the quizzes should be ordered by
112
  * @param string $order whether the $order_by should be ordered as ascending or decending. Can be "ASC" or "DESC"
113
+ * @param arr $user_role role of current user
114
+ * @param int $user_id Get the quiz based on user id
115
  * @return array All of the quizzes as a numerical array of objects
116
  */
117
  public function get_quizzes( $include_deleted = false, $order_by = 'quiz_id', $order = 'DESC', $user_role = array(), $user_id = '', $limit = '', $offset = '', $where = '' ) {
136
  case 'quiz_taken':
137
  $order_field = 'quiz_taken';
138
  break;
139
+
140
  case 'title':
141
  $order_field = 'quiz_name';
142
  break;
143
+
144
  default:
145
  $order_field = 'quiz_id';
146
  break;
147
  }
148
 
149
  // Should we include deleted?
150
+ $delete = 'WHERE deleted=0';
151
+ if ( $where != '' ) {
152
+ $delete = $delete . ' AND ' . $where;
153
+ }
154
  if ( $include_deleted ) {
155
  $delete = '';
156
  }
157
+ $user_str = '';
158
+ if ( in_array( 'author', (array) $user_role ) ) {
159
+ if ( $user_id && $delete == '' ) {
160
+ $user_str = "WHERE quiz_author_id = '$user_id'";
161
+ } elseif ( $user_id && $delete !== '' ) {
162
+ $user_str = " AND quiz_author_id = '$user_id'";
163
+ }
164
+ }
165
+ if ( $where != '' && $user_str != '' ) {
166
+ $user_str = $user_str . ' AND ' . $where;
167
+ }
168
+ $where_str = '';
169
+ if ( $user_str == '' && $delete === '' && $where != '' ) {
170
+ $where_str = "WHERE $where";
171
+ }
172
+ if ( $limit != '' ) {
173
+ $limit = ' limit ' . $offset . ', ' . $limit;
174
+ }
175
  // Get quizzes and return them
176
  $quizzes = $wpdb->get_results( stripslashes( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}mlw_quizzes %1s %2s %3s ORDER BY %4s %5s %6s", $delete, $user_str, $where_str, $order_field, $order_direction, $limit ) ) );
177
  return $quizzes;
189
  }
190
 
191
  /**
192
+ * Retrieves a setting value from a section based on name of section and setting
193
+ *
194
+ * @since 5.0.0
195
+ * @param string $section The name of the section the setting is registered in
196
+ * @param string $setting The name of the setting whose value we need to retrieve
197
+ * @param mixed $default What we need to return if no setting exists with given $setting
198
+ * @return $mixed Value set for $setting or $default if setting does not exist
199
+ */
200
+ public function get_section_setting( $section, $setting, $default = false ) {
201
  global $mlwQuizMasterNext;
202
+ return apply_filters( 'qsm_section_setting_text', $mlwQuizMasterNext->quiz_settings->get_section_setting( $section, $setting, $default ) );
203
  }
204
 
205
  /**
206
+ * Retrieves setting value based on name of setting
207
+ *
208
+ * @since 4.0.0
209
+ * @param string $setting The name of the setting whose value we need to retrieve
210
+ * @param mixed $default What we need to return if no setting exists with given $setting
211
+ * @return $mixed Value set for $setting or $default if setting does not exist
212
+ */
213
  public function get_quiz_setting( $setting, $default = false ) {
214
  global $mlwQuizMasterNext;
215
  return $mlwQuizMasterNext->quiz_settings->get_setting( $setting, $default );
216
  }
217
 
 
218
  /**
219
+ * Updates a settings value, adding it if it didn't already exist
220
+ *
221
+ * @since 4.0.0
222
+ * @param string $setting The name of the setting whose value we need to retrieve
223
+ * @param mixed $value The value that needs to be stored for the setting
224
+ * @return bool True if successful or false if fails
225
+ */
226
  public function update_quiz_setting( $setting, $value ) {
227
  global $mlwQuizMasterNext;
228
  return $mlwQuizMasterNext->quiz_settings->update_setting( $setting, $value );
229
  }
230
 
231
  /**
232
+ * Outputs the section of input fields
233
+ *
234
+ * @since 5.0.0
235
+ * @since 7.0 Added new parameter settings_fields for default setting
236
+ * @param string $section The section that the settings were registered with
237
+ */
238
+ public function generate_settings_section( $section = 'quiz_options', $settings_fields = array() ) {
239
+ global $mlwQuizMasterNext;
240
+ if ( empty( $settings_fields ) ) {
241
+ $settings_fields = $mlwQuizMasterNext->quiz_settings->load_setting_fields( $section );
242
+ }
243
+ QSM_Fields::generate_section( $settings_fields, $section );
244
+ }
245
 
246
  /**
247
  * Registers Quiz Templates
251
  * @param $file_path String of the path to the css file
252
  */
253
  public function register_quiz_template( $name, $file_path ) {
254
+ $slug = strtolower( str_replace( ' ', '-', $name ) );
255
+ $this->quiz_templates[ $slug ] = array(
256
+ 'name' => $name,
257
+ 'path' => $file_path,
258
  );
259
  }
260
 
268
  public function get_quiz_templates( $slug = null ) {
269
  if ( is_null( $slug ) ) {
270
  return $this->quiz_templates;
271
+ } elseif ( isset( $this->quiz_templates[ $slug ] ) ) {
272
+ return $this->quiz_templates[ $slug ];
273
  } else {
274
  return false;
275
  }
276
  }
277
 
278
  /**
279
+ * Register Question Types
280
+ *
281
+ * Adds a question type to the question type array using the parameters given
282
+ *
283
+ * @since 4.0.0
284
+ * @param string $name The name of the Question Type which will be shown when selecting type
285
+ * @param string $display_function The name of the function to call when displaying the question
286
+ * @param bool $graded Tells the plugin if this question is graded or not. This will affect scoring.
287
+ * @param string $review_function The name of the function to call when scoring the question
288
+ * @param string $slug The slug of the question type to be stored with question in database
289
+ * @return void
290
+ */
291
+ public function register_question_type( $name, $display_function, $graded, $review_function = null, $edit_args = null, $save_edit_function = null, $slug = null ) {
292
+ if ( is_null( $slug ) ) {
293
+ $slug = strtolower( str_replace( ' ', '-', $name ) );
 
294
  } else {
295
+ $slug = strtolower( str_replace( ' ', '-', $slug ) );
296
  }
297
+ if ( is_null( $edit_args ) || ! is_array( $edit_args ) ) {
298
  $validated_edit_function = array(
299
+ 'inputs' => array(
300
  'question',
301
  'answer',
302
  'hint',
303
  'correct_info',
304
  'comments',
305
  'category',
306
+ 'required',
307
  ),
308
+ 'information' => '',
309
  'extra_inputs' => array(),
310
+ 'function' => '',
311
  );
312
  } else {
313
  $validated_edit_function = array(
314
+ 'inputs' => $edit_args['inputs'],
315
+ 'information' => $edit_args['information'],
316
  'extra_inputs' => $edit_args['extra_inputs'],
317
+ 'function' => $edit_args['function'],
318
  );
319
  }
320
  if ( is_null( $save_edit_function ) ) {
321
  $save_edit_function = '';
322
  }
323
+ $new_type = array(
324
+ 'name' => $name,
325
  'display' => $display_function,
326
+ 'review' => $review_function,
327
+ 'graded' => $graded,
328
+ 'edit' => $validated_edit_function,
329
+ 'save' => $save_edit_function,
330
+ 'slug' => $slug,
331
  );
332
  $this->question_types[] = $new_type;
333
  }
334
 
335
  /**
336
+ * Retrieves List Of Question Types
337
+ *
338
+ * retrieves a list of the slugs and names of the question types
339
+ *
340
+ * @since 4.0.0
341
+ * @return array An array which contains the slug and name of question types that have been registered
342
+ */
343
+ public function get_question_type_options() {
 
344
  $type_array = array();
345
+ foreach ( $this->question_types as $type ) {
 
346
  $type_array[] = array(
347
+ 'slug' => $type['slug'],
348
+ 'name' => $type['name'],
349
  );
350
  }
351
  return $type_array;
353
 
354
  public function get_question_type_edit_fields() {
355
  $type_array = array();
356
+ foreach ( $this->question_types as $type ) {
357
+ $type_array[ $type['slug'] ] = $type['edit'];
 
358
  }
359
  return $type_array;
360
  }
361
 
362
  /**
363
+ * Displays A Question
364
+ *
365
+ * Retrieves the question types display function and creates the HTML for the question
366
+ *
367
+ * @since 4.0.0
368
+ * @param string $slug The slug of the question type that the question is
369
+ * @param int $question_id The id of the question
370
+ * @param array $quiz_options An array of the columns of the quiz row from the database
371
+ * @return string The HTML for the question
372
+ */
373
+ public function display_question( $slug, $question_id, $quiz_options ) {
 
374
  $display = '';
375
  global $wpdb;
376
  global $qmn_total_questions;
377
+ $question = $wpdb->get_row( $wpdb->prepare( 'SELECT * FROM ' . $wpdb->prefix . 'mlw_questions WHERE question_id=%d', intval( $question_id ) ) );
378
+ $answers = array();
379
+ if ( is_serialized( $question->answer_array ) && is_array( @unserialize( $question->answer_array ) ) ) {
380
+ $answers = @unserialize( $question->answer_array );
381
+ } else {
382
+ $mlw_answer_array_correct = array( 0, 0, 0, 0, 0, 0 );
383
+ $mlw_answer_array_correct[ $question->correct_answer - 1 ] = 1;
 
 
 
384
  $answers = array(
385
+ array( $question->answer_one, $question->answer_one_points, $mlw_answer_array_correct[0] ),
386
+ array( $question->answer_two, $question->answer_two_points, $mlw_answer_array_correct[1] ),
387
+ array( $question->answer_three, $question->answer_three_points, $mlw_answer_array_correct[2] ),
388
+ array( $question->answer_four, $question->answer_four_points, $mlw_answer_array_correct[3] ),
389
+ array( $question->answer_five, $question->answer_five_points, $mlw_answer_array_correct[4] ),
390
+ array( $question->answer_six, $question->answer_six_points, $mlw_answer_array_correct[5] ),
391
+ );
392
  }
393
  if ( 2 == $quiz_options->randomness_order || 3 == $quiz_options->randomness_order ) {
394
  shuffle( $answers );
395
+ }
396
+ foreach ( $this->question_types as $type ) {
397
+ if ( $type['slug'] == strtolower( str_replace( ' ', '-', $slug ) ) ) {
398
+ if ( $type['graded'] ) {
 
 
 
399
  $qmn_total_questions += 1;
400
+ if ( $quiz_options->question_numbering == 1 ) {
 
401
  $display .= "<span class='mlw_qmn_question_number'>$qmn_total_questions. </span>";
402
  }
403
  }
404
+ if ( $quiz_options->show_category_on_front && $question->category != '' ) {
405
+ $display .= '<div class="quiz-cat">[ ' . $question->category . ' ]</div>';
406
+ }
407
+ $display .= call_user_func( $type['display'], intval( $question_id ), $question->question_name, $answers );
408
  }
409
  }
410
  return $display;
411
  }
412
 
413
  /**
414
+ * Calculates Score For Question
415
+ *
416
+ * Calculates the score for the question based on the question type
417
+ *
418
+ * @since 4.0.0
419
+ * @param string $slug The slug of the question type that the question is
420
+ * @param int $question_id The id of the question
421
+ * @return array An array of the user's score from the question
422
+ */
423
+ public function display_review( $slug, $question_id ) {
 
424
  $results_array = array();
425
  global $wpdb;
426
+ $question = $wpdb->get_row( $wpdb->prepare( 'SELECT * FROM ' . $wpdb->prefix . 'mlw_questions WHERE question_id=%d', intval( $question_id ) ) );
427
+ $answers = array();
428
+ if ( is_serialized( $question->answer_array ) && is_array( @unserialize( $question->answer_array ) ) ) {
429
+ $answers = @unserialize( $question->answer_array );
430
+ } else {
431
+ $mlw_answer_array_correct = array( 0, 0, 0, 0, 0, 0 );
432
+ $mlw_answer_array_correct[ $question->correct_answer - 1 ] = 1;
 
 
 
433
  $answers = array(
434
+ array( $question->answer_one, $question->answer_one_points, $mlw_answer_array_correct[0] ),
435
+ array( $question->answer_two, $question->answer_two_points, $mlw_answer_array_correct[1] ),
436
+ array( $question->answer_three, $question->answer_three_points, $mlw_answer_array_correct[2] ),
437
+ array( $question->answer_four, $question->answer_four_points, $mlw_answer_array_correct[3] ),
438
+ array( $question->answer_five, $question->answer_five_points, $mlw_answer_array_correct[4] ),
439
+ array( $question->answer_six, $question->answer_six_points, $mlw_answer_array_correct[5] ),
440
+ );
441
  }
442
+ foreach ( $this->question_types as $type ) {
443
+ if ( $type['slug'] == strtolower( str_replace( ' ', '-', $slug ) ) ) {
444
+ if ( ! is_null( $type['review'] ) ) {
445
+ $results_array = call_user_func( $type['review'], intval( $question_id ), $question->question_name, $answers );
446
+ } else {
447
+ $results_array = array( 'null_review' => true );
 
 
 
 
 
448
  }
449
  }
450
  }
452
  }
453
 
454
  /**
455
+ * Retrieves A Question Setting
456
+ *
457
+ * Retrieves a setting stored in the question settings array
458
+ *
459
+ * @since 4.0.0
460
+ * @param int $question_id The id of the question
461
+ * @param string $setting The name of the setting
462
+ * @return string The value stored for the setting
463
+ */
464
+ public function get_question_setting( $question_id, $setting ) {
 
465
  global $wpdb;
466
  $qmn_settings_array = '';
467
+ $settings = $wpdb->get_var( $wpdb->prepare( 'SELECT question_settings FROM ' . $wpdb->prefix . 'mlw_questions WHERE question_id=%d', $question_id ) );
468
+ if ( is_serialized( $settings ) && is_array( @unserialize( $settings ) ) ) {
469
+ $qmn_settings_array = @unserialize( $settings );
 
470
  }
471
+ if ( is_array( $qmn_settings_array ) && isset( $qmn_settings_array[ $setting ] ) ) {
472
+ return $qmn_settings_array[ $setting ];
473
+ } else {
 
 
 
474
  return '';
475
  }
476
  }
477
 
478
  /**
479
+ * Registers Addon Settings Tab
480
+ *
481
+ * Registers a new tab on the addon settings page
482
+ *
483
+ * @since 4.0.0
484
+ * @param string $title The name of the tab
485
+ * @param string $function The function that displays the tab's content
486
+ * @return void
487
+ */
488
+ public function register_addon_settings_tab( $title, $function ) {
489
+ $slug = strtolower( str_replace( ' ', '-', $title ) );
490
+ $new_tab = array(
491
+ 'title' => $title,
 
492
  'function' => $function,
493
+ 'slug' => $slug,
494
  );
495
  $this->addon_tabs[] = $new_tab;
496
  }
497
 
498
  /**
499
+ * Retrieves Addon Settings Tab Array
500
+ *
501
+ * Retrieves the array of titles and functions of the registered tabs
502
+ *
503
+ * @since 4.0.0
504
+ * @return array The array of registered tabs
505
+ */
506
+ public function get_addon_tabs() {
 
507
  return $this->addon_tabs;
508
  }
509
 
510
  /**
511
+ * Registers Stats Tab
512
+ *
513
+ * Registers a new tab on the stats page
514
+ *
515
+ * @since 4.3.0
516
+ * @param string $title The name of the tab
517
+ * @param string $function The function that displays the tab's content
518
+ * @return void
519
+ */
520
+ public function register_stats_settings_tab( $title, $function ) {
521
+ $slug = strtolower( str_replace( ' ', '-', $title ) );
522
+ $new_tab = array(
523
+ 'title' => $title,
 
524
  'function' => $function,
525
+ 'slug' => $slug,
526
  );
527
  $this->stats_tabs[] = $new_tab;
528
  }
529
 
530
  /**
531
+ * Retrieves Stats Tab Array
532
+ *
533
+ * Retrieves the array of titles and functions of the registered tabs
534
+ *
535
+ * @since 4.3.0
536
+ * @return array The array of registered tabs
537
+ */
538
+ public function get_stats_tabs() {
 
539
  return $this->stats_tabs;
540
  }
541
 
549
  * @param string $function The function that displays the tab's content
550
  * @return void
551
  */
552
+ public function register_admin_results_tab( $title, $function ) {
553
+ $slug = strtolower( str_replace( ' ', '-', $title ) );
554
+ $new_tab = array(
555
+ 'title' => $title,
556
  'function' => $function,
557
+ 'slug' => $slug,
558
  );
559
  $this->admin_results_tabs[] = $new_tab;
560
  }
572
  }
573
 
574
  /**
575
+ * Registers Results Tab
576
+ *
577
+ * Registers a new tab on the results page
578
+ *
579
+ * @since 4.1.0
580
+ * @param string $title The name of the tab
581
+ * @param string $function The function that displays the tab's content
582
+ * @return void
583
+ */
584
+ public function register_results_settings_tab( $title, $function ) {
585
+ $slug = strtolower( str_replace( ' ', '-', $title ) );
586
+ $new_tab = array(
587
+ 'title' => $title,
 
588
  'function' => $function,
589
+ 'slug' => $slug,
590
  );
591
  $this->results_tabs[] = $new_tab;
592
  }
593
 
594
  /**
595
+ * Retrieves Results Tab Array
596
+ *
597
+ * Retrieves the array of titles and functions of the registered tabs
598
+ *
599
+ * @since 4.1.0
600
+ * @return array The array of registered tabs
601
+ */
602
+ public function get_results_tabs() {
 
603
  return $this->results_tabs;
604
  }
605
 
606
  /**
607
+ * Registers Quiz Settings Tab
608
+ *
609
+ * Registers a new tab on the quiz settings page
610
+ *
611
+ * @since 4.0.0
612
+ * @param string $title The name of the tab
613
+ * @param string $function The function that displays the tab's content
614
+ * @return void
615
+ */
616
+ public function register_quiz_settings_tabs( $title, $function ) {
617
+ $slug = strtolower( str_replace( ' ', '-', $title ) );
618
+ $new_tab = array(
619
+ 'title' => $title,
 
620
  'function' => $function,
621
+ 'slug' => $slug,
622
  );
623
  $this->settings_tabs[] = $new_tab;
624
  }
625
 
626
  /**
627
+ * Echos Registered Tabs Title Link
628
+ *
629
+ * Echos the title link of the registered tabs
630
+ *
631
+ * @since 4.0.0
632
+ * @return array The array of registered tabs
633
+ */
634
+ public function get_settings_tabs() {
 
635
  return $this->settings_tabs;
636
  }
637
+ }
 
php/classes/class-qmn-quiz-creator.php CHANGED
@@ -14,6 +14,7 @@ if ( ! defined( 'ABSPATH' ) ) {
14
  */
15
  class QMNQuizCreator {
16
 
 
17
  /**
18
  * QMN ID of quiz
19
  *
@@ -70,23 +71,23 @@ class QMNQuizCreator {
70
  public function create_quiz( $quiz_name, $quiz_settings = '' ) {
71
  global $mlwQuizMasterNext;
72
  global $wpdb;
73
- $current_user = wp_get_current_user();
74
- $results = $wpdb->insert(
75
  $wpdb->prefix . 'mlw_quizzes',
76
  array(
77
  'quiz_name' => $quiz_name,
78
- 'message_before' => __('Welcome to your %QUIZ_NAME%', 'quiz-master-next'),
79
- 'message_after' => __('Thanks for submitting your response! You can edit this message on the "Results Pages" tab. <br>%CONTACT_ALL% <br>%QUESTIONS_ANSWERS%', 'quiz-master-next'),
80
- 'message_comment' => __('Please fill in the comment box below.', 'quiz-master-next'),
81
  'message_end_template' => '',
82
  'user_email_template' => '%QUESTIONS_ANSWERS_EMAIL%',
83
  'admin_email_template' => '%QUESTIONS_ANSWERS_EMAIL%',
84
- 'submit_button_text' => __('Submit', 'quiz-master-next'),
85
- 'name_field_text' => __('Name', 'quiz-master-next'),
86
- 'business_field_text' => __('Business', 'quiz-master-next'),
87
- 'email_field_text' => __('Email', 'quiz-master-next'),
88
- 'phone_field_text' => __('Phone Number', 'quiz-master-next'),
89
- 'comment_field_text' => __('Comments', 'quiz-master-next'),
90
  'email_from_text' => 'Wordpress',
91
  'question_answer_template' => '%QUESTION%<br />%USER_ANSWERS_DEFAULT%',
92
  'leaderboard_template' => '',
@@ -105,12 +106,12 @@ class QMNQuizCreator {
105
  'comment_section' => 1,
106
  'question_from_total' => 0,
107
  'total_user_tries' => 0,
108
- 'total_user_tries_text' => __('You have utilized all of your attempts to pass this quiz.', 'quiz-master-next'),
109
  'certificate_template' => '',
110
  'social_media' => 0,
111
- 'social_media_text' => __('I just scored %CORRECT_SCORE%% on %QUIZ_NAME%!', 'quiz-master-next'),
112
  'pagination' => 0,
113
- 'pagination_text' => __('Next', 'quiz-master-next'),
114
  'timer_limit' => 0,
115
  'quiz_stye' => '',
116
  'question_numbering' => 0,
@@ -118,9 +119,9 @@ class QMNQuizCreator {
118
  'theme_selected' => 'primary',
119
  'last_activity' => current_time( 'mysql' ),
120
  'require_log_in' => 0,
121
- 'require_log_in_text' => __('This quiz is for logged in users only.', 'quiz-master-next'),
122
  'limit_total_entries' => 0,
123
- 'limit_total_entries_text' => __('Unfortunately, this quiz has a limited amount of entries it can recieve and has already reached that limit.', 'quiz-master-next'),
124
  'scheduled_timeframe' => '',
125
  'scheduled_timeframe_text' => '',
126
  'quiz_views' => 0,
@@ -185,8 +186,8 @@ class QMNQuizCreator {
185
  )
186
  );
187
  if ( false !== $results ) {
188
- $new_quiz = $wpdb->insert_id;
189
- $quiz_post = array(
190
  'post_title' => $quiz_name,
191
  'post_content' => "[mlw_quizmaster quiz=$new_quiz]",
192
  'post_status' => 'draft',
@@ -194,16 +195,16 @@ class QMNQuizCreator {
194
  'post_type' => 'qsm_quiz',
195
  );
196
  $quiz_post_id = wp_insert_post( $quiz_post );
197
- add_post_meta( $quiz_post_id, 'quiz_id', $new_quiz );
198
 
199
- $mlwQuizMasterNext->alertManager->newAlert(__('Your new quiz or survey has been created successfully. To begin editing, click the Edit link.', 'quiz-master-next'), 'success');
200
  $mlwQuizMasterNext->audit_manager->new_audit( "New Quiz/Survey Has Been Created: $quiz_name" );
201
 
202
  // Hook called after new quiz or survey has been created. Passes quiz_id to hook
203
- do_action('qmn_quiz_created', $new_quiz);
204
  } else {
205
- $mlwQuizMasterNext->alertManager->newAlert(sprintf(__('There has been an error in this action. Please share this with the developer. Error Code: %s', 'quiz-master-next'), '0001'), 'error');
206
- $mlwQuizMasterNext->log_manager->add("Error 0001", $wpdb->last_error.' from '.$wpdb->last_query, 0, 'error');
207
  }
208
  }
209
 
@@ -214,64 +215,64 @@ class QMNQuizCreator {
214
  * @since 3.7.1
215
  * @return void
216
  */
217
- public function delete_quiz($quiz_id, $quiz_name)
218
- {
219
- global $mlwQuizMasterNext;
220
  global $wpdb;
221
- $results = $wpdb->update(
222
- $wpdb->prefix . "mlw_quizzes",
223
- array(
224
- 'deleted' => 1
225
- ),
226
- array( 'quiz_id' => $quiz_id ),
227
- array(
228
- '%d'
229
- ),
230
- array( '%d' )
231
- );
232
- $deleted = 0;
233
- if( isset( $_POST['qsm_delete_question_from_qb'] ) && $_POST['qsm_delete_question_from_qb'] == 1 ){
234
- $deleted = 1;
235
- }
236
- $delete_question_results = $wpdb->update(
237
- $wpdb->prefix . "mlw_questions",
238
- array(
239
- 'deleted' => $deleted
240
- ),
241
- array( 'quiz_id' => $quiz_id ),
242
- array(
243
- '%d'
244
- ),
245
- array( '%d' )
246
- );
247
- if ($results != false)
248
- {
249
- $my_query = new WP_Query( array('post_type' => 'qsm_quiz', 'meta_key' => 'quiz_id', 'meta_value' => $quiz_id) );
250
- if( $my_query->have_posts() )
251
- {
252
- while( $my_query->have_posts() )
253
- {
254
- $my_query->the_post();
 
 
 
255
  $my_post = array(
256
- 'ID' => get_the_ID(),
257
- 'post_status' => 'trash'
258
- );
259
  wp_update_post( $my_post );
260
- }
261
  }
262
  wp_reset_postdata();
263
- $mlwQuizMasterNext->alertManager->newAlert(__('Your quiz or survey has been deleted successfully.', 'quiz-master-next'), 'success');
264
  $mlwQuizMasterNext->audit_manager->new_audit( "Quiz/Survey Has Been Deleted: $quiz_name" );
265
- }
266
- else
267
- {
268
- $mlwQuizMasterNext->alertManager->newAlert(sprintf(__('There has been an error in this action. Please share this with the developer. Error Code: %s', 'quiz-master-next'), '0002'), 'error');
269
- $mlwQuizMasterNext->log_manager->add("Error 0002", $wpdb->last_error.' from '.$wpdb->last_query, 0, 'error');
270
  }
271
 
272
  // Hook called after quiz or survey is deleted. Hook passes quiz_id to function
273
- do_action('qmn_quiz_deleted', $quiz_id);
274
- }
275
 
276
  /**
277
  * Edits the name of the quiz with the given ID
@@ -296,7 +297,7 @@ class QMNQuizCreator {
296
  ),
297
  array( '%d' )
298
  );
299
- if ( false !== $results ) {
300
  $mlwQuizMasterNext->alertManager->newAlert( __( 'The name of your quiz or survey has been updated successfully.', 'quiz-master-next' ), 'success' );
301
  $mlwQuizMasterNext->audit_manager->new_audit( "Quiz/Survey Name Has Been Edited: $quiz_name" );
302
  } else {
@@ -315,215 +316,219 @@ class QMNQuizCreator {
315
  do_action( 'qmn_quiz_name_edited', $quiz_id );
316
  }
317
 
318
- /**
319
  * Duplicates the quiz with the given ID and gives new quiz the given quiz name
320
  *
321
  * @access public
322
  * @since 3.7.1
323
  * @return void
324
  */
325
- public function duplicate_quiz($quiz_id, $quiz_name, $is_duplicating_questions)
326
- {
327
- global $mlwQuizMasterNext;
328
- global $wpdb;
329
- $current_user = wp_get_current_user();
330
- $table_name = $wpdb->prefix . "mlw_quizzes";
331
- $logic_table = $wpdb->prefix. "mlw_logic";
332
  $mlw_qmn_duplicate_data = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $table_name WHERE quiz_id=%d", $quiz_id ) );
333
- $quiz_settings = unserialize( $mlw_qmn_duplicate_data->quiz_settings );
334
- if( $is_duplicating_questions == 0 ){
335
- $quiz_settings['pages'] = '';
336
- }
337
- $qsm_create_quiz_system = 0;
338
- if( isset( $mlw_qmn_duplicate_data->system ) ){
339
- $qsm_create_quiz_system = $mlw_qmn_duplicate_data->system;
340
- } else if( isset( $mlw_qmn_duplicate_data->quiz_system ) ){
341
- $qsm_create_quiz_system = $mlw_qmn_duplicate_data->quiz_system;
342
- }
343
- $results = $wpdb->insert(
344
- $table_name,
345
- array(
346
- 'quiz_name' => $quiz_name,
347
- 'message_before' => $mlw_qmn_duplicate_data->message_before,
348
- 'message_after' => $mlw_qmn_duplicate_data->message_after,
349
- 'message_comment' => $mlw_qmn_duplicate_data->message_comment,
350
- 'message_end_template' => $mlw_qmn_duplicate_data->message_end_template,
351
- 'user_email_template' => $mlw_qmn_duplicate_data->user_email_template,
352
- 'admin_email_template' => $mlw_qmn_duplicate_data->admin_email_template,
353
- 'submit_button_text' => $mlw_qmn_duplicate_data->submit_button_text,
354
- 'name_field_text' => $mlw_qmn_duplicate_data->name_field_text,
355
- 'business_field_text' => $mlw_qmn_duplicate_data->business_field_text,
356
- 'email_field_text' => $mlw_qmn_duplicate_data->email_field_text,
357
- 'phone_field_text' => $mlw_qmn_duplicate_data->phone_field_text,
358
- 'comment_field_text' => $mlw_qmn_duplicate_data->comment_field_text,
359
- 'email_from_text' => $mlw_qmn_duplicate_data->email_from_text,
360
- 'question_answer_template' => $mlw_qmn_duplicate_data->question_answer_template,
361
- 'leaderboard_template' => $mlw_qmn_duplicate_data->leaderboard_template,
362
- 'quiz_system' => $qsm_create_quiz_system,
363
- 'randomness_order' => $mlw_qmn_duplicate_data->randomness_order,
364
- 'loggedin_user_contact' => $mlw_qmn_duplicate_data->loggedin_user_contact,
365
- 'show_score' => $mlw_qmn_duplicate_data->show_score,
366
- 'send_user_email' => $mlw_qmn_duplicate_data->send_user_email,
367
- 'send_admin_email' => $mlw_qmn_duplicate_data->send_admin_email,
368
- 'contact_info_location' => $mlw_qmn_duplicate_data->contact_info_location,
369
- 'user_name' => $mlw_qmn_duplicate_data->user_name,
370
- 'user_comp' => $mlw_qmn_duplicate_data->user_comp,
371
- 'user_email' => $mlw_qmn_duplicate_data->user_email,
372
- 'user_phone' => $mlw_qmn_duplicate_data->user_phone,
373
- 'admin_email' => get_option( 'admin_email', 'Enter email' ),
374
- 'comment_section' => $mlw_qmn_duplicate_data->comment_section,
375
- 'question_from_total' => $mlw_qmn_duplicate_data->question_from_total,
376
- 'total_user_tries' => $mlw_qmn_duplicate_data->total_user_tries,
377
- 'total_user_tries_text' => $mlw_qmn_duplicate_data->total_user_tries_text,
378
- 'certificate_template' => $mlw_qmn_duplicate_data->certificate_template,
379
- 'social_media' => $mlw_qmn_duplicate_data->social_media,
380
- 'social_media_text' => $mlw_qmn_duplicate_data->social_media_text,
381
- 'pagination' => $mlw_qmn_duplicate_data->pagination,
382
- 'pagination_text' => $mlw_qmn_duplicate_data->pagination_text,
383
- 'timer_limit' => $mlw_qmn_duplicate_data->timer_limit,
384
- 'quiz_stye' => $mlw_qmn_duplicate_data->quiz_stye,
385
- 'question_numbering' => $mlw_qmn_duplicate_data->question_numbering,
386
- 'quiz_settings' => serialize( $quiz_settings ),
387
- 'theme_selected' => $mlw_qmn_duplicate_data->theme_selected,
388
- 'last_activity' => date("Y-m-d H:i:s"),
389
- 'require_log_in' => $mlw_qmn_duplicate_data->require_log_in,
390
- 'require_log_in_text' => $mlw_qmn_duplicate_data->require_log_in_text,
391
- 'limit_total_entries' => $mlw_qmn_duplicate_data->limit_total_entries,
392
- 'limit_total_entries_text' => $mlw_qmn_duplicate_data->limit_total_entries_text,
393
- 'scheduled_timeframe' => $mlw_qmn_duplicate_data->scheduled_timeframe,
394
- 'scheduled_timeframe_text' => $mlw_qmn_duplicate_data->scheduled_timeframe_text,
395
- 'quiz_views' => 0,
396
- 'quiz_taken' => 0,
397
- 'deleted' => 0,
398
- 'quiz_author_id' => $current_user->ID,
399
- ),
400
- array(
401
- '%s',
402
- '%s',
403
- '%s',
404
- '%s',
405
- '%s',
406
- '%s',
407
- '%s',
408
- '%s',
409
- '%s',
410
- '%s',
411
- '%s',
412
- '%s',
413
- '%s',
414
- '%s',
415
- '%s',
416
- '%s',
417
- '%d',
418
- '%d',
419
- '%d',
420
- '%d',
421
- '%d',
422
- '%d',
423
- '%d',
424
- '%d',
425
- '%d',
426
- '%d',
427
- '%d',
428
- '%s',
429
- '%d',
430
- '%d',
431
- '%d',
432
- '%s',
433
- '%s',
434
- '%d',
435
- '%s',
436
- '%d',
437
- '%s',
438
- '%d',
439
- '%s',
440
- '%d',
441
- '%s',
442
- '%s',
443
- '%s',
444
- '%d',
445
- '%s',
446
- '%d',
447
- '%s',
448
- '%s',
449
- '%s',
450
- '%d',
451
- '%d',
452
- '%d',
453
- '%d',
454
- )
455
- );
456
  $mlw_new_id = $wpdb->insert_id;
457
-
458
- //Update quiz settings
459
- $update_quiz_settings = unserialize($mlw_qmn_duplicate_data->quiz_settings);
460
- $update_pages = unserialize($update_quiz_settings['pages']);
461
- //get logic data from logic table first or else from quiz_settings
462
- $query = $wpdb->prepare("SELECT * FROM $logic_table WHERE quiz_id = %d", $quiz_id);
463
- $logic_data = $wpdb->get_results($query);
464
- $logic_rules = [];
465
- if(sizeof($logic_data) > 0){
466
- foreach ($logic_data as $data) {
467
- $logic_rules[] = unserialize($data->logic);
468
- }
469
- } else {
470
- $logic_rules = isset( $update_quiz_settings['logic_rules'] ) ? unserialize(unserialize($update_quiz_settings['logic_rules'])) : array();
471
  }
472
-
 
 
 
473
 
474
  if ( false != $results ) {
475
  $current_user = wp_get_current_user();
476
- $quiz_post = array(
477
- 'post_title' => $quiz_name,
478
- 'post_content' => "[mlw_quizmaster quiz=$mlw_new_id]",
479
- 'post_status' => 'publish',
480
- 'post_author' => $current_user->ID,
481
- 'post_type' => 'qsm_quiz'
482
  );
483
  $quiz_post_id = wp_insert_post( $quiz_post );
484
  add_post_meta( $quiz_post_id, 'quiz_id', $mlw_new_id );
485
- $mlwQuizMasterNext->alertManager->newAlert(__('Your quiz or survey has been duplicated successfully.', 'quiz-master-next'), 'success');
486
  $mlwQuizMasterNext->audit_manager->new_audit( "New Quiz/Survey Has Been Created: $quiz_name" );
487
- do_action('qmn_quiz_duplicated', $quiz_id, $mlw_new_id);
488
- }
489
- else
490
- {
491
- $mlwQuizMasterNext->alertManager->newAlert(sprintf(__('There has been an error in this action. Please share this with the developer. Error Code: %s', 'quiz-master-next'), '0011'), 'error');
492
- $mlwQuizMasterNext->log_manager->add("Error 0011", $wpdb->last_error.' from '.$wpdb->last_query, 0, 'error');
493
  }
494
- if ($is_duplicating_questions)
495
- {
496
- $table_name = $wpdb->prefix."mlw_questions";
497
- $mlw_current_questions = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM $table_name WHERE deleted=0 AND quiz_id=%d", $quiz_id ) );
498
- foreach ($mlw_current_questions as $mlw_question)
499
- {
 
 
 
 
 
500
  $question_results = $wpdb->insert(
501
  $table_name,
502
  array(
503
- 'quiz_id' => $mlw_new_id,
504
- 'question_name' => $mlw_question->question_name,
505
- 'answer_array' => $mlw_question->answer_array,
506
- 'answer_one' => $mlw_question->answer_one,
507
- 'answer_one_points' => $mlw_question->answer_one_points,
508
- 'answer_two' => $mlw_question->answer_two,
509
- 'answer_two_points' => $mlw_question->answer_two_points,
510
- 'answer_three' => $mlw_question->answer_three,
511
- 'answer_three_points' => $mlw_question->answer_three_points,
512
- 'answer_four' => $mlw_question->answer_four,
513
- 'answer_four_points' => $mlw_question->answer_four_points,
514
- 'answer_five' => $mlw_question->answer_five,
515
- 'answer_five_points' => $mlw_question->answer_five_points,
516
- 'answer_six' => $mlw_question->answer_six,
517
- 'answer_six_points' => $mlw_question->answer_six_points,
518
- 'correct_answer' => $mlw_question->correct_answer,
519
  'question_answer_info' => $mlw_question->question_answer_info,
520
- 'comments' => $mlw_question->comments,
521
- 'hints' => $mlw_question->hints,
522
- 'question_order' => $mlw_question->question_order,
523
- 'question_type_new' => $mlw_question->question_type_new,
524
- 'question_settings' => $mlw_question->question_settings,
525
- 'category' => $mlw_question->category,
526
- 'deleted' => 0
527
  ),
528
  array(
529
  '%d',
@@ -549,63 +554,69 @@ class QMNQuizCreator {
549
  '%s',
550
  '%s',
551
  '%s',
552
- '%d'
553
  )
554
  );
555
- foreach ($update_pages as $pages_key => $pages_value) {
556
- foreach ($pages_value as $pages_k_q => $page_q_id) {
557
- if($page_q_id == $mlw_question->question_id){
558
- $update_pages[$pages_key][$pages_k_q] = $wpdb->insert_id;
559
- }
560
- }
561
- }
562
- // Fixed Rules Questions with new question ids
563
- if( $logic_rules ){
564
- foreach ($logic_rules as $logic_key => $logic_value) {
565
- foreach ($logic_value as $logic_cond_k => $logic_cond) {
566
- foreach($logic_cond as $l_cond_k => $logic_val) {
567
- if($logic_val['question'] == $mlw_question->question_id) {
568
- $logic_rules[$logic_key][$logic_cond_k][$l_cond_k]['question'] = $wpdb->insert_id;
569
- }
570
- }
571
- }
572
- }
573
- }
574
- if ($question_results == false)
575
- {
576
- $mlwQuizMasterNext->alertManager->newAlert(sprintf(__('There has been an error in this action. Please share this with the developer. Error Code: %s', 'quiz-master-next'), '0020'), 'error');
577
- $mlwQuizMasterNext->log_manager->add("Error 0020", $wpdb->last_error.' from '.$wpdb->last_query, 0, 'error');
578
- }
579
- }
580
- $update_quiz_settings['pages'] = serialize($update_pages);
581
- //saves data in logic table first or else in quiz_settings
582
- foreach($logic_rules as $logic_data){
583
- $data = array(
584
- $mlw_new_id,
585
- serialize($logic_data),
586
- );
587
- $value_array[] = stripslashes($wpdb->prepare("(%d, %s)", $data));
588
  }
589
- $values = implode(',', $value_array);
590
- $query = "INSERT INTO $logic_table (quiz_id, logic) VALUES ";
591
- $query .= $values;
592
- $saved = $wpdb->query($query);
593
- if($saved != FALSE){
594
- update_option("logic_rules_quiz_$mlw_new_id", date(time()));
595
- $update_quiz_settings['logic_rules'] = '';
596
- } else {
597
- $update_quiz_settings['logic_rules'] = serialize(serialize($logic_rules));
 
 
598
  }
599
-
600
- $wpdb->update(
601
- $wpdb->prefix . "mlw_quizzes",
602
- array(
603
- 'quiz_settings' => serialize($update_quiz_settings),
604
- ),
605
- array(
606
- 'quiz_id' => $mlw_new_id
607
- )
608
- );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
609
  }
610
  }
611
 
@@ -621,7 +632,7 @@ class QMNQuizCreator {
621
  public function get_setting( $setting_name ) {
622
  global $wpdb;
623
  $qmn_settings_array = '';
624
- $qmn_quiz_settings = $wpdb->get_var( $wpdb->prepare( "SELECT quiz_settings FROM " . $wpdb->prefix . "mlw_quizzes" . " WHERE quiz_id=%d", $this->quiz_id ) );
625
  if ( is_serialized( $qmn_quiz_settings ) && is_array( @unserialize( $qmn_quiz_settings ) ) ) {
626
  $qmn_settings_array = @unserialize( $qmn_quiz_settings );
627
  }
@@ -646,30 +657,26 @@ class QMNQuizCreator {
646
  public function update_setting( $setting_name, $setting_value ) {
647
  global $wpdb;
648
  $qmn_settings_array = array();
649
- $qmn_quiz_settings = $wpdb->get_var( $wpdb->prepare( "SELECT quiz_settings FROM " . $wpdb->prefix . "mlw_quizzes" . " WHERE quiz_id=%d", $this->quiz_id ) );
650
- if (is_serialized($qmn_quiz_settings) && is_array(@unserialize($qmn_quiz_settings)))
651
- {
652
- $qmn_settings_array = @unserialize($qmn_quiz_settings);
653
  }
654
- $qmn_settings_array[$setting_name] = $setting_value;
655
- $qmn_serialized_array = serialize($qmn_settings_array);
656
- $results = $wpdb->update(
657
- $wpdb->prefix . "mlw_quizzes",
658
  array(
659
- 'quiz_settings' => $qmn_serialized_array
660
  ),
661
  array( 'quiz_id' => $this->quiz_id ),
662
  array(
663
- '%s'
664
  ),
665
  array( '%d' )
666
  );
667
- if ($results != false)
668
- {
669
  return true;
670
- }
671
- else
672
- {
673
  return false;
674
  }
675
  }
@@ -685,26 +692,24 @@ class QMNQuizCreator {
685
  public function delete_setting( $setting_name ) {
686
  global $wpdb;
687
  $qmn_settings_array = array();
688
- $qmn_quiz_settings = $wpdb->get_var( $wpdb->prepare( "SELECT quiz_settings FROM " . $wpdb->prefix . "mlw_quizzes" . " WHERE quiz_id=%d", $this->quiz_id ) );
689
- if (is_serialized($qmn_quiz_settings) && is_array(@unserialize($qmn_quiz_settings)))
690
- {
691
- $qmn_settings_array = @unserialize($qmn_quiz_settings);
692
  }
693
- if (is_array($qmn_settings_array) && isset($qmn_settings_array[$setting_name]))
694
- {
695
- unset($qmn_settings_array[$setting_name]);
696
  }
697
- $qmn_serialized_array = serialize($qmn_settings_array);
698
- $results = $wpdb->update(
699
- $wpdb->prefix . "mlw_quizzes",
700
  array(
701
- 'quiz_settings' => $qmn_serialized_array
702
  ),
703
  array( 'quiz_id' => $this->quiz_id ),
704
  array(
705
- '%s'
706
  ),
707
  array( '%d' )
708
  );
709
  }
710
- }
14
  */
15
  class QMNQuizCreator {
16
 
17
+
18
  /**
19
  * QMN ID of quiz
20
  *
71
  public function create_quiz( $quiz_name, $quiz_settings = '' ) {
72
  global $mlwQuizMasterNext;
73
  global $wpdb;
74
+ $current_user = wp_get_current_user();
75
+ $results = $wpdb->insert(
76
  $wpdb->prefix . 'mlw_quizzes',
77
  array(
78
  'quiz_name' => $quiz_name,
79
+ 'message_before' => __( 'Welcome to your %QUIZ_NAME%', 'quiz-master-next' ),
80
+ 'message_after' => __( 'Thanks for submitting your response! You can edit this message on the "Results Pages" tab. <br>%CONTACT_ALL% <br>%QUESTIONS_ANSWERS%', 'quiz-master-next' ),
81
+ 'message_comment' => __( 'Please fill in the comment box below.', 'quiz-master-next' ),
82
  'message_end_template' => '',
83
  'user_email_template' => '%QUESTIONS_ANSWERS_EMAIL%',
84
  'admin_email_template' => '%QUESTIONS_ANSWERS_EMAIL%',
85
+ 'submit_button_text' => __( 'Submit', 'quiz-master-next' ),
86
+ 'name_field_text' => __( 'Name', 'quiz-master-next' ),
87
+ 'business_field_text' => __( 'Business', 'quiz-master-next' ),
88
+ 'email_field_text' => __( 'Email', 'quiz-master-next' ),
89
+ 'phone_field_text' => __( 'Phone Number', 'quiz-master-next' ),
90
+ 'comment_field_text' => __( 'Comments', 'quiz-master-next' ),
91
  'email_from_text' => 'Wordpress',
92
  'question_answer_template' => '%QUESTION%<br />%USER_ANSWERS_DEFAULT%',
93
  'leaderboard_template' => '',
106
  'comment_section' => 1,
107
  'question_from_total' => 0,
108
  'total_user_tries' => 0,
109
+ 'total_user_tries_text' => __( 'You have utilized all of your attempts to pass this quiz.', 'quiz-master-next' ),
110
  'certificate_template' => '',
111
  'social_media' => 0,
112
+ 'social_media_text' => __( 'I just scored %CORRECT_SCORE%% on %QUIZ_NAME%!', 'quiz-master-next' ),
113
  'pagination' => 0,
114
+ 'pagination_text' => __( 'Next', 'quiz-master-next' ),
115
  'timer_limit' => 0,
116
  'quiz_stye' => '',
117
  'question_numbering' => 0,
119
  'theme_selected' => 'primary',
120
  'last_activity' => current_time( 'mysql' ),
121
  'require_log_in' => 0,
122
+ 'require_log_in_text' => __( 'This quiz is for logged in users only.', 'quiz-master-next' ),
123
  'limit_total_entries' => 0,
124
+ 'limit_total_entries_text' => __( 'Unfortunately, this quiz has a limited amount of entries it can recieve and has already reached that limit.', 'quiz-master-next' ),
125
  'scheduled_timeframe' => '',
126
  'scheduled_timeframe_text' => '',
127
  'quiz_views' => 0,
186
  )
187
  );
188
  if ( false !== $results ) {
189
+ $new_quiz = $wpdb->insert_id;
190
+ $quiz_post = array(
191
  'post_title' => $quiz_name,
192
  'post_content' => "[mlw_quizmaster quiz=$new_quiz]",
193
  'post_status' => 'draft',
195
  'post_type' => 'qsm_quiz',
196
  );
197
  $quiz_post_id = wp_insert_post( $quiz_post );
198
+ add_post_meta( $quiz_post_id, 'quiz_id', $new_quiz );
199
 
200
+ $mlwQuizMasterNext->alertManager->newAlert( __( 'Your new quiz or survey has been created successfully. To begin editing, click the Edit link.', 'quiz-master-next' ), 'success' );
201
  $mlwQuizMasterNext->audit_manager->new_audit( "New Quiz/Survey Has Been Created: $quiz_name" );
202
 
203
  // Hook called after new quiz or survey has been created. Passes quiz_id to hook
204
+ do_action( 'qmn_quiz_created', $new_quiz );
205
  } else {
206
+ $mlwQuizMasterNext->alertManager->newAlert( sprintf( __( 'There has been an error in this action. Please share this with the developer. Error Code: %s', 'quiz-master-next' ), '0001' ), 'error' );
207
+ $mlwQuizMasterNext->log_manager->add( 'Error 0001', $wpdb->last_error . ' from ' . $wpdb->last_query, 0, 'error' );
208
  }
209
  }
210
 
215
  * @since 3.7.1
216
  * @return void
217
  */
218
+ public function delete_quiz( $quiz_id, $quiz_name ) {
219
+ global $mlwQuizMasterNext;
 
220
  global $wpdb;
221
+ $results = $wpdb->update(
222
+ $wpdb->prefix . 'mlw_quizzes',
223
+ array(
224
+ 'deleted' => 1,
225
+ ),
226
+ array( 'quiz_id' => $quiz_id ),
227
+ array(
228
+ '%d',
229
+ ),
230
+ array( '%d' )
231
+ );
232
+ $deleted = 0;
233
+ if ( isset( $_POST['qsm_delete_question_from_qb'] ) && $_POST['qsm_delete_question_from_qb'] == 1 ) {
234
+ $deleted = 1;
235
+ }
236
+ $delete_question_results = $wpdb->update(
237
+ $wpdb->prefix . 'mlw_questions',
238
+ array(
239
+ 'deleted' => $deleted,
240
+ ),
241
+ array( 'quiz_id' => $quiz_id ),
242
+ array(
243
+ '%d',
244
+ ),
245
+ array( '%d' )
246
+ );
247
+ if ( $results != false ) {
248
+ $my_query = new WP_Query(
249
+ array(
250
+ 'post_type' => 'qsm_quiz',
251
+ 'meta_key' => 'quiz_id',
252
+ 'meta_value' => $quiz_id,
253
+ )
254
+ );
255
+ if ( $my_query->have_posts() ) {
256
+ while ( $my_query->have_posts() ) {
257
+ $my_query->the_post();
258
  $my_post = array(
259
+ 'ID' => get_the_ID(),
260
+ 'post_status' => 'trash',
261
+ );
262
  wp_update_post( $my_post );
263
+ }
264
  }
265
  wp_reset_postdata();
266
+ $mlwQuizMasterNext->alertManager->newAlert( __( 'Your quiz or survey has been deleted successfully.', 'quiz-master-next' ), 'success' );
267
  $mlwQuizMasterNext->audit_manager->new_audit( "Quiz/Survey Has Been Deleted: $quiz_name" );
268
+ } else {
269
+ $mlwQuizMasterNext->alertManager->newAlert( sprintf( __( 'There has been an error in this action. Please share this with the developer. Error Code: %s', 'quiz-master-next' ), '0002' ), 'error' );
270
+ $mlwQuizMasterNext->log_manager->add( 'Error 0002', $wpdb->last_error . ' from ' . $wpdb->last_query, 0, 'error' );
 
 
271
  }
272
 
273
  // Hook called after quiz or survey is deleted. Hook passes quiz_id to function
274
+ do_action( 'qmn_quiz_deleted', $quiz_id );
275
+ }
276
 
277
  /**
278
  * Edits the name of the quiz with the given ID
297
  ),
298
  array( '%d' )
299
  );
300
+ if ( false !== $results ) {
301
  $mlwQuizMasterNext->alertManager->newAlert( __( 'The name of your quiz or survey has been updated successfully.', 'quiz-master-next' ), 'success' );
302
  $mlwQuizMasterNext->audit_manager->new_audit( "Quiz/Survey Name Has Been Edited: $quiz_name" );
303
  } else {
316
  do_action( 'qmn_quiz_name_edited', $quiz_id );
317
  }
318
 
319
+ /**
320
  * Duplicates the quiz with the given ID and gives new quiz the given quiz name
321
  *
322
  * @access public
323
  * @since 3.7.1
324
  * @return void
325
  */
326
+ public function duplicate_quiz( $quiz_id, $quiz_name, $is_duplicating_questions ) {
327
+ global $mlwQuizMasterNext;
328
+ global $wpdb;
329
+ $current_user = wp_get_current_user();
330
+ $table_name = $wpdb->prefix . 'mlw_quizzes';
331
+ $logic_table = $wpdb->prefix . 'mlw_logic';
332
+ $logic_table_exists = $wpdb->get_var( $wpdb->prepare( 'SHOW TABLES LIKE %s', $logic_table ) );
333
  $mlw_qmn_duplicate_data = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $table_name WHERE quiz_id=%d", $quiz_id ) );
334
+ $quiz_settings = unserialize( $mlw_qmn_duplicate_data->quiz_settings );
335
+ if ( $is_duplicating_questions == 0 ) {
336
+ $quiz_settings['pages'] = '';
337
+ }
338
+ $qsm_create_quiz_system = 0;
339
+ if ( isset( $mlw_qmn_duplicate_data->system ) ) {
340
+ $qsm_create_quiz_system = $mlw_qmn_duplicate_data->system;
341
+ } elseif ( isset( $mlw_qmn_duplicate_data->quiz_system ) ) {
342
+ $qsm_create_quiz_system = $mlw_qmn_duplicate_data->quiz_system;
343
+ }
344
+ $results = $wpdb->insert(
345
+ $table_name,
346
+ array(
347
+ 'quiz_name' => $quiz_name,
348
+ 'message_before' => $mlw_qmn_duplicate_data->message_before,
349
+ 'message_after' => $mlw_qmn_duplicate_data->message_after,
350
+ 'message_comment' => $mlw_qmn_duplicate_data->message_comment,
351
+ 'message_end_template' => $mlw_qmn_duplicate_data->message_end_template,
352
+ 'user_email_template' => $mlw_qmn_duplicate_data->user_email_template,
353
+ 'admin_email_template' => $mlw_qmn_duplicate_data->admin_email_template,
354
+ 'submit_button_text' => $mlw_qmn_duplicate_data->submit_button_text,
355
+ 'name_field_text' => $mlw_qmn_duplicate_data->name_field_text,
356
+ 'business_field_text' => $mlw_qmn_duplicate_data->business_field_text,
357
+ 'email_field_text' => $mlw_qmn_duplicate_data->email_field_text,
358
+ 'phone_field_text' => $mlw_qmn_duplicate_data->phone_field_text,
359
+ 'comment_field_text' => $mlw_qmn_duplicate_data->comment_field_text,
360
+ 'email_from_text' => $mlw_qmn_duplicate_data->email_from_text,
361
+ 'question_answer_template' => $mlw_qmn_duplicate_data->question_answer_template,
362
+ 'leaderboard_template' => $mlw_qmn_duplicate_data->leaderboard_template,
363
+ 'quiz_system' => $qsm_create_quiz_system,
364
+ 'randomness_order' => $mlw_qmn_duplicate_data->randomness_order,
365
+ 'loggedin_user_contact' => $mlw_qmn_duplicate_data->loggedin_user_contact,
366
+ 'show_score' => $mlw_qmn_duplicate_data->show_score,
367
+ 'send_user_email' => $mlw_qmn_duplicate_data->send_user_email,
368
+ 'send_admin_email' => $mlw_qmn_duplicate_data->send_admin_email,
369
+ 'contact_info_location' => $mlw_qmn_duplicate_data->contact_info_location,
370
+ 'user_name' => $mlw_qmn_duplicate_data->user_name,
371
+ 'user_comp' => $mlw_qmn_duplicate_data->user_comp,
372
+ 'user_email' => $mlw_qmn_duplicate_data->user_email,
373
+ 'user_phone' => $mlw_qmn_duplicate_data->user_phone,
374
+ 'admin_email' => get_option( 'admin_email', 'Enter email' ),
375
+ 'comment_section' => $mlw_qmn_duplicate_data->comment_section,
376
+ 'question_from_total' => $mlw_qmn_duplicate_data->question_from_total,
377
+ 'total_user_tries' => $mlw_qmn_duplicate_data->total_user_tries,
378
+ 'total_user_tries_text' => $mlw_qmn_duplicate_data->total_user_tries_text,
379
+ 'certificate_template' => $mlw_qmn_duplicate_data->certificate_template,
380
+ 'social_media' => $mlw_qmn_duplicate_data->social_media,
381
+ 'social_media_text' => $mlw_qmn_duplicate_data->social_media_text,
382
+ 'pagination' => $mlw_qmn_duplicate_data->pagination,
383
+ 'pagination_text' => $mlw_qmn_duplicate_data->pagination_text,
384
+ 'timer_limit' => $mlw_qmn_duplicate_data->timer_limit,
385
+ 'quiz_stye' => $mlw_qmn_duplicate_data->quiz_stye,
386
+ 'question_numbering' => $mlw_qmn_duplicate_data->question_numbering,
387
+ 'quiz_settings' => serialize( $quiz_settings ),
388
+ 'theme_selected' => $mlw_qmn_duplicate_data->theme_selected,
389
+ 'last_activity' => date( 'Y-m-d H:i:s' ),
390
+ 'require_log_in' => $mlw_qmn_duplicate_data->require_log_in,
391
+ 'require_log_in_text' => $mlw_qmn_duplicate_data->require_log_in_text,
392
+ 'limit_total_entries' => $mlw_qmn_duplicate_data->limit_total_entries,
393
+ 'limit_total_entries_text' => $mlw_qmn_duplicate_data->limit_total_entries_text,
394
+ 'scheduled_timeframe' => $mlw_qmn_duplicate_data->scheduled_timeframe,
395
+ 'scheduled_timeframe_text' => $mlw_qmn_duplicate_data->scheduled_timeframe_text,
396
+ 'quiz_views' => 0,
397
+ 'quiz_taken' => 0,
398
+ 'deleted' => 0,
399
+ 'quiz_author_id' => $current_user->ID,
400
+ ),
401
+ array(
402
+ '%s',
403
+ '%s',
404
+ '%s',
405
+ '%s',
406
+ '%s',
407
+ '%s',
408
+ '%s',
409
+ '%s',
410
+ '%s',
411
+ '%s',
412
+ '%s',
413
+ '%s',
414
+ '%s',
415
+ '%s',
416
+ '%s',
417
+ '%s',
418
+ '%d',
419
+ '%d',
420
+ '%d',
421
+ '%d',
422
+ '%d',
423
+ '%d',
424
+ '%d',
425
+ '%d',
426
+ '%d',
427
+ '%d',
428
+ '%d',
429
+ '%s',
430
+ '%d',
431
+ '%d',
432
+ '%d',
433
+ '%s',
434
+ '%s',
435
+ '%d',
436
+ '%s',
437
+ '%d',
438
+ '%s',
439
+ '%d',
440
+ '%s',
441
+ '%d',
442
+ '%s',
443
+ '%s',
444
+ '%s',
445
+ '%d',
446
+ '%s',
447
+ '%d',
448
+ '%s',
449
+ '%s',
450
+ '%s',
451
+ '%d',
452
+ '%d',
453
+ '%d',
454
+ '%d',
455
+ )
456
+ );
457
  $mlw_new_id = $wpdb->insert_id;
458
+
459
+ // Update quiz settings
460
+ $update_quiz_settings = unserialize( $mlw_qmn_duplicate_data->quiz_settings );
461
+ $update_pages = unserialize( $update_quiz_settings['pages'] );
462
+ // get logic data from logic table first or else from quiz_settings
463
+ if ( ! is_null( $logic_table_exists ) ) {
464
+ $query = $wpdb->prepare( "SELECT * FROM $logic_table WHERE quiz_id = %d", $quiz_id );
465
+ $logic_data = $wpdb->get_results( $query );
466
+ $logic_rules = array();
467
+ if ( ! empty( $logic_data ) ) {
468
+ foreach ( $logic_data as $data ) {
469
+ $logic_rules[] = unserialize( $data->logic );
 
 
470
  }
471
+ }
472
+ } else {
473
+ $logic_rules = isset( $update_quiz_settings['logic_rules'] ) ? unserialize( unserialize( $update_quiz_settings['logic_rules'] ) ) : array();
474
+ }
475
 
476
  if ( false != $results ) {
477
  $current_user = wp_get_current_user();
478
+ $quiz_post = array(
479
+ 'post_title' => $quiz_name,
480
+ 'post_content' => "[mlw_quizmaster quiz=$mlw_new_id]",
481
+ 'post_status' => 'publish',
482
+ 'post_author' => $current_user->ID,
483
+ 'post_type' => 'qsm_quiz',
484
  );
485
  $quiz_post_id = wp_insert_post( $quiz_post );
486
  add_post_meta( $quiz_post_id, 'quiz_id', $mlw_new_id );
487
+ $mlwQuizMasterNext->alertManager->newAlert( __( 'Your quiz or survey has been duplicated successfully.', 'quiz-master-next' ), 'success' );
488
  $mlwQuizMasterNext->audit_manager->new_audit( "New Quiz/Survey Has Been Created: $quiz_name" );
489
+ do_action( 'qmn_quiz_duplicated', $quiz_id, $mlw_new_id );
490
+ } else {
491
+ $mlwQuizMasterNext->alertManager->newAlert( sprintf( __( 'There has been an error in this action. Please share this with the developer. Error Code: %s', 'quiz-master-next' ), '0011' ), 'error' );
492
+ $mlwQuizMasterNext->log_manager->add( 'Error 0011', $wpdb->last_error . ' from ' . $wpdb->last_query, 0, 'error' );
 
 
493
  }
494
+ if ( $is_duplicating_questions ) {
495
+ $table_name = $wpdb->prefix . 'mlw_questions';
496
+ $questions = array();
497
+ if ( is_array( $update_pages ) ) {
498
+ foreach ( $update_pages[0] as $ids ) {
499
+ $questions[] = $ids;
500
+ }
501
+ }
502
+ $question_ids = implode( ',', $questions );
503
+ $mlw_current_questions = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM $table_name WHERE question_id IN (%1s)", $question_ids ) );
504
+ foreach ( $mlw_current_questions as $mlw_question ) {
505
  $question_results = $wpdb->insert(
506
  $table_name,
507
  array(
508
+ 'quiz_id' => $mlw_new_id,
509
+ 'question_name' => $mlw_question->question_name,
510
+ 'answer_array' => $mlw_question->answer_array,
511
+ 'answer_one' => $mlw_question->answer_one,
512
+ 'answer_one_points' => $mlw_question->answer_one_points,
513
+ 'answer_two' => $mlw_question->answer_two,
514
+ 'answer_two_points' => $mlw_question->answer_two_points,
515
+ 'answer_three' => $mlw_question->answer_three,
516
+ 'answer_three_points' => $mlw_question->answer_three_points,
517
+ 'answer_four' => $mlw_question->answer_four,
518
+ 'answer_four_points' => $mlw_question->answer_four_points,
519
+ 'answer_five' => $mlw_question->answer_five,
520
+ 'answer_five_points' => $mlw_question->answer_five_points,
521
+ 'answer_six' => $mlw_question->answer_six,
522
+ 'answer_six_points' => $mlw_question->answer_six_points,
523
+ 'correct_answer' => $mlw_question->correct_answer,
524
  'question_answer_info' => $mlw_question->question_answer_info,
525
+ 'comments' => $mlw_question->comments,
526
+ 'hints' => $mlw_question->hints,
527
+ 'question_order' => $mlw_question->question_order,
528
+ 'question_type_new' => $mlw_question->question_type_new,
529
+ 'question_settings' => $mlw_question->question_settings,
530
+ 'category' => $mlw_question->category,
531
+ 'deleted' => 0,
532
  ),
533
  array(
534
  '%d',
554
  '%s',
555
  '%s',
556
  '%s',
557
+ '%d',
558
  )
559
  );
560
+ foreach ( $update_pages as $pages_key => $pages_value ) {
561
+ foreach ( $pages_value as $pages_k_q => $page_q_id ) {
562
+ if ( $page_q_id == $mlw_question->question_id ) {
563
+ $update_pages[ $pages_key ][ $pages_k_q ] = $wpdb->insert_id;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
564
  }
565
+ }
566
+ }
567
+ // Fixed Rules Questions with new question ids
568
+ if ( $logic_rules ) {
569
+ foreach ( $logic_rules as $logic_key => $logic_value ) {
570
+ foreach ( $logic_value as $logic_cond_k => $logic_cond ) {
571
+ foreach ( $logic_cond as $l_cond_k => $logic_val ) {
572
+ if ( $logic_val['question'] == $mlw_question->question_id ) {
573
+ $logic_rules[ $logic_key ][ $logic_cond_k ][ $l_cond_k ]['question'] = $wpdb->insert_id;
574
+ }
575
+ }
576
  }
577
+ }
578
+ }
579
+ if ( $question_results == false ) {
580
+ $mlwQuizMasterNext->alertManager->newAlert( sprintf( __( 'There has been an error in this action. Please share this with the developer. Error Code: %s', 'quiz-master-next' ), '0020' ), 'error' );
581
+ $mlwQuizMasterNext->log_manager->add( 'Error 0020', $wpdb->last_error . ' from ' . $wpdb->last_query, 0, 'error' );
582
+ }
583
+ }
584
+ $update_quiz_settings['pages'] = serialize( $update_pages );
585
+ // saves data in logic table first or else in quiz_settings
586
+ $value_array = array();
587
+ if ( is_array( $logic_rules ) && ! empty( $logic_rules ) ) {
588
+ if ( is_null( $logic_table_exists ) ) {
589
+ $update_quiz_settings['logic_rules'] = serialize( serialize( $logic_rules ) );
590
+ } else {
591
+ foreach ( $logic_rules as $logic_data ) {
592
+ $data = array(
593
+ $mlw_new_id,
594
+ serialize( $logic_data ),
595
+ );
596
+ $value_array[] = stripslashes( $wpdb->prepare( '(%d, %s)', $data ) );
597
+ }
598
+ $values = implode( ',', $value_array );
599
+ $query = "INSERT INTO $logic_table (quiz_id, logic) VALUES ";
600
+ $query .= $values;
601
+ $saved = $wpdb->query( $query );
602
+ if ( $saved != false ) {
603
+ update_option( "logic_rules_quiz_$mlw_new_id", date( time() ) );
604
+ $update_quiz_settings['logic_rules'] = '';
605
+ } else {
606
+ $update_quiz_settings['logic_rules'] = serialize( serialize( $logic_rules ) );
607
+ }
608
+ }
609
+ }
610
+
611
+ $wpdb->update(
612
+ $wpdb->prefix . 'mlw_quizzes',
613
+ array(
614
+ 'quiz_settings' => serialize( $update_quiz_settings ),
615
+ ),
616
+ array(
617
+ 'quiz_id' => $mlw_new_id,
618
+ )
619
+ );
620
  }
621
  }
622
 
632
  public function get_setting( $setting_name ) {
633
  global $wpdb;
634
  $qmn_settings_array = '';
635
+ $qmn_quiz_settings = $wpdb->get_var( $wpdb->prepare( 'SELECT quiz_settings FROM ' . $wpdb->prefix . 'mlw_quizzes' . ' WHERE quiz_id=%d', $this->quiz_id ) );
636
  if ( is_serialized( $qmn_quiz_settings ) && is_array( @unserialize( $qmn_quiz_settings ) ) ) {
637
  $qmn_settings_array = @unserialize( $qmn_quiz_settings );
638
  }
657
  public function update_setting( $setting_name, $setting_value ) {
658
  global $wpdb;
659
  $qmn_settings_array = array();
660
+ $qmn_quiz_settings = $wpdb->get_var( $wpdb->prepare( 'SELECT quiz_settings FROM ' . $wpdb->prefix . 'mlw_quizzes' . ' WHERE quiz_id=%d', $this->quiz_id ) );
661
+ if ( is_serialized( $qmn_quiz_settings ) && is_array( @unserialize( $qmn_quiz_settings ) ) ) {
662
+ $qmn_settings_array = @unserialize( $qmn_quiz_settings );
 
663
  }
664
+ $qmn_settings_array[ $setting_name ] = $setting_value;
665
+ $qmn_serialized_array = serialize( $qmn_settings_array );
666
+ $results = $wpdb->update(
667
+ $wpdb->prefix . 'mlw_quizzes',
668
  array(
669
+ 'quiz_settings' => $qmn_serialized_array,
670
  ),
671
  array( 'quiz_id' => $this->quiz_id ),
672
  array(
673
+ '%s',
674
  ),
675
  array( '%d' )
676
  );
677
+ if ( $results != false ) {
 
678
  return true;
679
+ } else {
 
 
680
  return false;
681
  }
682
  }
692
  public function delete_setting( $setting_name ) {
693
  global $wpdb;
694
  $qmn_settings_array = array();
695
+ $qmn_quiz_settings = $wpdb->get_var( $wpdb->prepare( 'SELECT quiz_settings FROM ' . $wpdb->prefix . 'mlw_quizzes' . ' WHERE quiz_id=%d', $this->quiz_id ) );
696
+ if ( is_serialized( $qmn_quiz_settings ) && is_array( @unserialize( $qmn_quiz_settings ) ) ) {
697
+ $qmn_settings_array = @unserialize( $qmn_quiz_settings );
 
698
  }
699
+ if ( is_array( $qmn_settings_array ) && isset( $qmn_settings_array[ $setting_name ] ) ) {
700
+ unset( $qmn_settings_array[ $setting_name ] );
 
701
  }
702
+ $qmn_serialized_array = serialize( $qmn_settings_array );
703
+ $results = $wpdb->update(
704
+ $wpdb->prefix . 'mlw_quizzes',
705
  array(
706
+ 'quiz_settings' => $qmn_serialized_array,
707
  ),
708
  array( 'quiz_id' => $this->quiz_id ),
709
  array(
710
+ '%s',
711
  ),
712
  array( '%d' )
713
  );
714
  }
715
+ }
php/question-types.php CHANGED
@@ -89,7 +89,10 @@ function qmn_file_upload_review( $id, $question, $answers ) {
89
  break;
90
  }
91
  }
92
- return $return_array;
 
 
 
93
  }
94
 
95
  /**
@@ -198,7 +201,10 @@ function qmn_multiple_choice_review( $id, $question, $answers ) {
198
  }
199
  }
200
  $return_array['correct_text'] = implode( '.', $correct_text );
201
- return $return_array;
 
 
 
202
  }
203
 
204
  add_action( 'plugins_loaded', 'qmn_question_type_date' );
@@ -270,7 +276,10 @@ function qmn_date_review( $id, $question, $answers ) {
270
  break;
271
  }
272
  }
273
- return $return_array;
 
 
 
274
  }
275
 
276
  add_action( 'plugins_loaded', 'qmn_question_type_horizontal_multiple_choice' );
@@ -384,7 +393,10 @@ function qmn_horizontal_multiple_choice_review( $id, $question, $answers ) {
384
  }
385
  }
386
  $return_array['correct_text'] = implode( '.', $correct_text );
387
- return $return_array;
 
 
 
388
  }
389
 
390
  add_action( 'plugins_loaded', 'qmn_question_type_drop_down' );
@@ -473,7 +485,10 @@ function qmn_drop_down_review( $id, $question, $answers ) {
473
  $return_array['correct_text'] = htmlspecialchars_decode( $answer[0], ENT_QUOTES );
474
  }
475
  }
476
- return $return_array;
 
 
 
477
  }
478
 
479
  add_action( 'plugins_loaded', 'qmn_question_type_small_open' );
@@ -549,7 +564,10 @@ function qmn_small_open_review( $id, $question, $answers ) {
549
  break;
550
  }
551
  }
552
- return $return_array;
 
 
 
553
  }
554
 
555
  add_action( 'plugins_loaded', 'qmn_question_type_multiple_response' );
@@ -649,7 +667,10 @@ function qmn_multiple_response_review( $id, $question, $answers ) {
649
  $return_array['correct'] = 'correct';
650
  }
651
  $return_array['correct_text'] = implode( '.', $correct_text );
652
- return $return_array;
 
 
 
653
  }
654
 
655
  add_action( 'plugins_loaded', 'qmn_question_type_large_open' );
@@ -722,7 +743,10 @@ function qmn_large_open_review( $id, $question, $answers ) {
722
  break;
723
  }
724
  }
725
- return $return_array;
 
 
 
726
  }
727
 
728
  add_action( 'plugins_loaded', 'qmn_question_type_text_block' );
@@ -836,7 +860,10 @@ function qmn_number_review( $id, $question, $answers ) {
836
  break;
837
  }
838
  }
839
- return $return_array;
 
 
 
840
  }
841
 
842
  add_action( 'plugins_loaded', 'qmn_question_type_accept' );
@@ -1051,7 +1078,10 @@ function qmn_horizontal_multiple_response_review( $id, $question, $answers ) {
1051
  $return_array['correct'] = 'correct';
1052
  }
1053
  $return_array['correct_text'] = implode( '.', $correct_text );
1054
- return $return_array;
 
 
 
1055
  }
1056
 
1057
  add_action( 'plugins_loaded', 'qmn_question_type_fill_blank' );
@@ -1151,7 +1181,10 @@ function qmn_fill_blank_review( $id, $question, $answers ) {
1151
  break;
1152
  }
1153
  }
1154
- return $return_array;
 
 
 
1155
  }
1156
 
1157
 
@@ -1306,7 +1339,10 @@ function qmn_polar_review( $id, $question, $answers ) {
1306
  break;
1307
  }
1308
  }
1309
- return $return_array;
 
 
 
1310
  }
1311
 
1312
  function qsm_question_title_func( $question, $question_type = '', $new_question_title = '' ) {
89
  break;
90
  }
91
  }
92
+ /**
93
+ * Hook to filter answers array
94
+ */
95
+ return apply_filters( 'qmn_file_upload_review', $return_array , $answers );
96
  }
97
 
98
  /**
201
  }
202
  }
203
  $return_array['correct_text'] = implode( '.', $correct_text );
204
+ /**
205
+ * Hook to filter answers array
206
+ */
207
+ return apply_filters( 'qmn_multiple_choice_review', $return_array , $answers );
208
  }
209
 
210
  add_action( 'plugins_loaded', 'qmn_question_type_date' );
276
  break;
277
  }
278
  }
279
+ /**
280
+ * Hook to filter answers array
281
+ */
282
+ return apply_filters( 'qmn_date_review', $return_array , $answers );
283
  }
284
 
285
  add_action( 'plugins_loaded', 'qmn_question_type_horizontal_multiple_choice' );
393
  }
394
  }
395
  $return_array['correct_text'] = implode( '.', $correct_text );
396
+ /**
397
+ * Hook to filter answers array
398
+ */
399
+ return apply_filters( 'qmn_horizontal_multiple_choice_review', $return_array , $answers );
400
  }
401
 
402
  add_action( 'plugins_loaded', 'qmn_question_type_drop_down' );
485
  $return_array['correct_text'] = htmlspecialchars_decode( $answer[0], ENT_QUOTES );
486
  }
487
  }
488
+ /**
489
+ * Hook to filter answers array
490
+ */
491
+ return apply_filters( 'qmn_drop_down_review', $return_array , $answers );
492
  }
493
 
494
  add_action( 'plugins_loaded', 'qmn_question_type_small_open' );
564
  break;
565
  }
566
  }
567
+ /**
568
+ * Hook to filter answers array
569
+ */
570
+ return apply_filters( 'qmn_small_open_review', $return_array ,$answers);
571
  }
572
 
573
  add_action( 'plugins_loaded', 'qmn_question_type_multiple_response' );
667
  $return_array['correct'] = 'correct';
668
  }
669
  $return_array['correct_text'] = implode( '.', $correct_text );
670
+ /**
671
+ * Hook to filter answers array
672
+ */
673
+ return apply_filters( 'qmn_multiple_response_review', $return_array , $answers );
674
  }
675
 
676
  add_action( 'plugins_loaded', 'qmn_question_type_large_open' );
743
  break;
744
  }
745
  }
746
+ /**
747
+ * Hook to filter answers array
748
+ */
749
+ return apply_filters( 'qmn_large_open_review', $return_array , $answers );
750
  }
751
 
752
  add_action( 'plugins_loaded', 'qmn_question_type_text_block' );
860
  break;
861
  }
862
  }
863
+ /**
864
+ * Hook to filter answers array
865
+ */
866
+ return apply_filters( 'qmn_number_review', $return_array , $answers );
867
  }
868
 
869
  add_action( 'plugins_loaded', 'qmn_question_type_accept' );
1078
  $return_array['correct'] = 'correct';
1079
  }
1080
  $return_array['correct_text'] = implode( '.', $correct_text );
1081
+ /**
1082
+ * Hook to filter answers array
1083
+ */
1084
+ return apply_filters( 'qmn_horizontal_multiple_response_review', $return_array , $answers );
1085
  }
1086
 
1087
  add_action( 'plugins_loaded', 'qmn_question_type_fill_blank' );
1181
  break;
1182
  }
1183
  }
1184
+ /**
1185
+ * Hook to filter answers array
1186
+ */
1187
+ return apply_filters( 'qmn_fill_blank_review', $return_array , $answers );
1188
  }
1189
 
1190
 
1339
  break;
1340
  }
1341
  }
1342
+ /**
1343
+ * Hook to filter answers array
1344
+ */
1345
+ return apply_filters( 'qmn_polar_review', $return_array , $answers );
1346
  }
1347
 
1348
  function qsm_question_title_func( $question, $question_type = '', $new_question_title = '' ) {
php/template-variables.php CHANGED
@@ -1101,7 +1101,8 @@ function qsm_questions_answers_shortcode_to_text($mlw_quiz_array, $qmn_question_
1101
  $extra_border_bottom_class = 'qsm-remove-border-bottom';
1102
  }
1103
  $mlw_question_answer_display = apply_filters('qsm_question_answers_template_variable', $mlw_question_answer_display, $mlw_quiz_array, $answer);
1104
- $display = "<div class='qmn_question_answer $extra_border_bottom_class $question_answer_class'>" . apply_filters('qmn_variable_question_answers', $mlw_question_answer_display, $mlw_quiz_array) . '</div>';
 
1105
  return $display;
1106
  }
1107
  function qsm_get_question_maximum_points($question = array()) {
1101
  $extra_border_bottom_class = 'qsm-remove-border-bottom';
1102
  }
1103
  $mlw_question_answer_display = apply_filters('qsm_question_answers_template_variable', $mlw_question_answer_display, $mlw_quiz_array, $answer);
1104
+ $question_obj = (isset($questions[$answer['id']]) ? $questions[$answer['id']] : null );
1105
+ $display = "<div class='qmn_question_answer $extra_border_bottom_class $question_answer_class'>" . apply_filters('qmn_variable_question_answers', $mlw_question_answer_display, $mlw_quiz_array, $question_obj) . '</div>';
1106
  return $display;
1107
  }
1108
  function qsm_get_question_maximum_points($question = array()) {
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.7
6
  Requires PHP: 5.4
7
- Stable tag: 7.1.16
8
  License: GPLv2
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
@@ -140,6 +140,10 @@ This is usually a theme conflict. You can [checkout out our common conflict solu
140
 
141
  == Changelog ==
142
 
 
 
 
 
143
  = 7.1.16 (April 29, 2021) =
144
  * Bug: Fixed the issue with Facebook share.
145
  * Bug: Fixed issue with timer starting on intro page.
4
  Requires at least: 4.9
5
  Tested up to: 5.7
6
  Requires PHP: 5.4
7
+ Stable tag: 7.1.17
8
  License: GPLv2
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
140
 
141
  == Changelog ==
142
 
143
+ = 7.1.17 (May 28, 2021) =
144
+ * Bug: Fixed the issue where page title shows Nan:Nan:Nan on reload.
145
+ * Bug: Fixed the issue when editing duplicate questions updates original questions.
146
+
147
  = 7.1.16 (April 29, 2021) =
148
  * Bug: Fixed the issue with Facebook share.
149
  * Bug: Fixed issue with timer starting on intro page.