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

Version Description

(May 31, 2021) = * Bug: Fixed recently discovered security issues.

Download this release

Release Info

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

Code changes from version 7.1.17 to 7.1.18

js/qsm-admin-question.js CHANGED
@@ -5,9 +5,9 @@
5
  var QSMQuestion;
6
  var import_button;
7
  (function ($) {
8
- $.QSMSanitize = function(input) {
9
- return input.replace(/<(|\/|[^>\/bi]|\/[^>bi]|[^\/>][^>]+|\/[^>][^>]+)>/g, '');
10
- };
11
  QSMQuestion = {
12
  question: Backbone.Model.extend({
13
  defaults: {
@@ -42,296 +42,296 @@ var import_button;
42
  /**
43
  * Counts the total number of questions and then updates #total-questions span.
44
  */
45
- countTotal: function() {
46
  var total = 0;
47
 
48
  // Cycles through each page.
49
- _.each( jQuery( '.page' ), function( page ) {
50
 
51
  // If page is empty, continue to the next.
52
- if( 0 == jQuery( page ).children( '.question' ).length ) {
53
  return;
54
  }
55
  // Cycle through each question and add to our total.
56
- _.each( jQuery( page ).children( '.question' ), function( question ){
57
  total += 1;
58
  });
59
  });
60
- $( '#total-questions' ).text( total );
61
  },
62
- openQuestionBank: function( pageID ) {
63
  QSMQuestion.loadQuestionBank();
64
- $( '#add-question-bank-page' ).val( pageID );
65
- MicroModal.show( 'modal-2',{
66
- onClose: function(){
67
- $('.save-page-button').trigger('click');
68
- }
69
- });
70
  },
71
- loadQuestionBank: function( action = '' ) {
72
- if( action == 'change' ){
73
- $( '.qb-load-more-wrapper' ).remove();
74
- $( '#question-bank' ).find( '.question-bank-question' ).remove();
75
- $( '#question-bank' ).append( '<div style="top: 45px;position: relative;" class="qsm-spinner-loader"></div>' );
76
- }else if($('.qb-load-more-wrapper').length > 0){
77
- $( '.qb-load-more-question' ).hide();
78
- $( '.qb-load-more-wrapper' ).append( '<div class="qsm-spinner-loader"></div>' );
79
- }else{
80
- $( '#question-bank' ).empty();
81
- $( '#question-bank' ).append( '<div class="qsm-spinner-loader"></div>' );
82
- }
83
- $.ajax( {
84
  url: wpApiSettings.root + 'quiz-survey-master/v1/bank_questions/0/',
85
  method: 'GET',
86
- beforeSend: function ( xhr ) {
87
- xhr.setRequestHeader( 'X-WP-Nonce', qsmQuestionSettings.nonce );
88
  },
89
  data: {
90
- 'quizID' : 0,
91
- 'page' : $('#question_back_page_number').length > 0 ? parseInt( $('#question_back_page_number').val() ) + 1 : 1,
92
- 'category' : $('#question-bank-cat').val()
93
  },
94
  success: QSMQuestion.questionBankLoadSuccess
95
  });
96
  },
97
- questionBankLoadSuccess: function( questions ) {
98
- var pagination = questions.pagination;
99
- var questions = questions.questions;
100
- if($('.qb-load-more-wrapper').length > 0){
101
- $('.qb-load-more-wrapper').remove();
102
- }else{
103
- $( '#question-bank' ).empty();
104
- }
105
- for ( var i = 0; i < questions.length; i++) {
106
- QSMQuestion.addQuestionToQuestionBank( questions[i] );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
107
  }
108
- if( pagination.total_pages > pagination.current_page){
109
- var pagination_html = '<div class="qb-load-more-wrapper" style="text-align: center;margin: 20px 0 10px 0;"><input type="hidden" id="question_back_page_number" value="' + pagination.current_page + '"/>';
110
- pagination_html += '<input type="hidden" id="question_back_total_pages" value="'+ pagination.total_pages +'"/>';
111
- pagination_html += '<a href="#" class="button button-primary qb-load-more-question">Load More Questions</a></div>';
112
- $( '#question-bank' ).append( pagination_html );
113
- }
114
- if(pagination.current_page == 1 && qsmQuestionSettings.categories.length > 0){
115
- var category_arr = qsmQuestionSettings.categories;
116
- $cat_html = '<select name="question-bank-cat" id="question-bank-cat">';
117
- $cat_html += '<option value="">All Questions</option>';
118
- $.each(category_arr, function(index, value){
119
- if(value.category !== '')
120
- $cat_html += '<option value="'+ value.category +'">'+ value.category +' Questions</option>';
121
- });
122
- $cat_html += '</select>';
123
- $( '#question-bank' ).prepend($cat_html);
124
- $('#question-bank-cat').val(pagination.category);
125
- }
126
- if(pagination.current_page == 1){
127
- $( '#question-bank' ).prepend('<button class="button button-primary" id="qsm-import-selected-question">Import All Selected Questions</button>');
128
- $( '#question-bank' ).prepend('<button class="button button-default" id="qsm-delete-selected-question">Delete Selected Question from Bank</button>');
129
- $( '#question-bank' ).prepend('<label class="qsm-select-all-label"><input type="checkbox" id="qsm_select_all_question" /> Select All Question</button>');
130
- }
131
  },
132
- addQuestionToQuestionBank: function( question ) {
133
- var questionText = QSMQuestion.prepareQuestionText( question.name );
134
- var template = wp.template( 'single-question-bank-question' );
135
- if( question.question_title !== "undefined" && question.question_title !== "" ){
136
- questionText = question.question_title;
137
- }
138
- $( '#question-bank' ).append( template( { id: question.id, question: questionText, category: question.category, quiz_name: question.quiz_name } ) );
139
  },
140
- addQuestionFromQuestionBank: function( questionID ) {
141
  //MicroModal.close( 'modal-2' );
142
  //QSMAdmin.displayAlert( 'Adding question...', 'info' );
143
- var model = new QSMQuestion.question( { id: questionID } );
144
- model.fetch({
145
  headers: { 'X-WP-Nonce': qsmQuestionSettings.nonce },
146
  url: wpApiSettings.root + 'quiz-survey-master/v1/questions/' + questionID,
147
  success: QSMQuestion.questionBankSuccess,
148
  error: QSMAdmin.displayError
149
- });
150
  },
151
- questionBankSuccess: function( model ) {
152
- var page = parseInt( $( '#add-question-bank-page' ).val(), 10 );
153
- model.set( 'page', page );
154
  //QSMAdmin.displayAlert( 'Question added!', 'success' );
155
- QSMQuestion.questions.add( model );
156
- QSMQuestion.addQuestionToPage( model );
157
- $('.import-button').removeClass('disable_import');
158
- import_button.html('').html('Add Question');
159
  },
160
- prepareCategories: function() {
161
  QSMQuestion.categories = [];
162
- QSMQuestion.questions.each(function( question ) {
163
- var category = question.get( 'category' );
164
- if ( 0 !== category.length && ! _.contains( QSMQuestion.categories, category ) ) {
165
- QSMQuestion.categories.push( category );
166
  }
167
  });
168
  },
169
- processCategories: function() {
170
- $( '.category' ).remove();
171
- _.each( QSMQuestion.categories, function( category ) {
172
- QSMQuestion.addCategory( category );
173
  });
174
  },
175
- addCategory: function( category ) {
176
- var template = wp.template( 'single-category' );
177
- $( '#categories' ).prepend( template( { category: category } ) );
178
  },
179
- loadQuestions: function() {
180
- QSMAdmin.displayAlert( 'Loading questions...', 'info' );
181
- QSMQuestion.questions.fetch({
182
  headers: { 'X-WP-Nonce': qsmQuestionSettings.nonce },
183
  data: { quizID: qsmQuestionSettings.quizID },
184
  success: QSMQuestion.loadSuccess,
185
  error: QSMAdmin.displayError
186
- });
187
  },
188
- loadSuccess: function() {
189
  QSMAdmin.clearAlerts();
190
  $('.qsm-showing-loader').remove();
191
  var question;
192
- _.each(qsmQuestionSettings.qpages, function( page ){
193
  QSMQuestion.qpages.add(page);
194
  });
195
- if ( qsmQuestionSettings.pages.length > 0 ) {
196
- for ( var i = 0; i < qsmQuestionSettings.pages.length; i++ ) {
197
- for ( var j = 0; j < qsmQuestionSettings.pages[ i ].length; j++ ) {
198
- question = QSMQuestion.questions.get( qsmQuestionSettings.pages[ i ][ j ] );
199
- QSMQuestion.addQuestionToPage( question );
200
  }
201
  }
202
  } else {
203
- //We have removed this code in 7.0.0 because not allow to delete the single page.
204
- QSMQuestion.questions.each( QSMQuestion.addQuestionToPage );
 
 
 
 
 
205
  }
206
- //Create Default pages and one question.
207
- if( qsmQuestionSettings.pages.length == 0 && QSMQuestion.questions.length == 0){
208
- $('.new-page-button').trigger('click');
209
- $('.questions .new-question-button').trigger('click');
210
- }
211
  QSMQuestion.countTotal();
212
  },
213
- updateQPage: function(pageID) {
214
- QSMAdmin.displayAlert( 'Saving page info', 'info' );
215
  var pageInfo = QSMQuestion.qpages.get(pageID);
216
- jQuery('#page-options').find(':input, select, textarea').each(function(i, field){
217
  pageInfo.set(field.name, field.value);
218
  });
219
  },
220
- savePages: function() {
221
- QSMAdmin.displayAlert( 'Saving pages and questions...', 'info' );
222
  var pages = [];
223
  var qpages = [];
224
  var pageInfo = null;
225
 
226
  // Cycles through each page and add page + questions to pages variable
227
- _.each( jQuery( '.page' ), function( page ) {
228
 
229
  // If page is empty, do not add it.
230
- if( 0 == jQuery( page ).children( '.question' ).length ) {
231
  return;
232
  }
233
  var singlePage = [];
234
  // Cycle through each question and add to the page.
235
- _.each( jQuery( page ).children( '.question' ), function( question ){
236
- singlePage.push( jQuery( question ).data( 'question-id' ) )
237
  });
238
- pages.push( singlePage );
239
  /**
240
  * Prepare qpages Object
241
  */
242
- pageInfo = QSMQuestion.qpages.get(jQuery( page ).data('page-id'));
243
  pageInfo.set('questions', singlePage);
244
  qpages.push(pageInfo.attributes);
245
  });
246
- console.log(pages);
247
  var data = {
248
  action: 'qsm_save_pages',
249
  pages: pages,
250
  qpages: qpages,
251
- quiz_id : qsmQuestionSettings.quizID,
252
- nonce : qsmQuestionSettings.saveNonce,
253
  };
254
-
255
- jQuery.ajax( ajaxurl, {
256
  data: data,
257
  method: 'POST',
258
  success: QSMQuestion.savePagesSuccess,
259
  error: QSMAdmin.displayjQueryError
260
  });
261
  },
262
- savePagesSuccess: function() {
263
- QSMAdmin.displayAlert( 'Questions and pages were saved!', 'success' );
264
  $('#save-edit-quiz-pages').removeClass('is-active');
265
  },
266
- addNewPage: function(pageID) {
267
- var template = wp.template( 'page' );
268
  if (typeof pageID == 'undefined' || pageID == '') {
269
  var newPageID = QSMQuestion.qpages.length + 1;
270
  var pageID = newPageID;
271
- var pageInfo = QSMQuestion.qpages.add({id: newPageID, quizID: qsmQuestionSettings.quizID, pagekey: qsmRandomID(8), hide_prevbtn: 0});
272
  }
273
  var pageInfo = QSMQuestion.qpages.get(pageID);
274
- $( '.questions' ).append( template(pageInfo) );
275
- var page = $( '.questions' ).find('.page').length;
276
  $('.page:nth-child(' + page + ')').find('.page-number').text('Page ' + page);
277
- $( '.page' ).sortable({
278
  items: '.question',
279
  opacity: 70,
280
  cursor: 'move',
281
  placeholder: "ui-state-highlight",
282
  connectWith: '.page',
283
- stop: function(evt, ui) {
284
  setTimeout(
285
- function(){
286
  $('.save-page-button').trigger('click');
287
  },
288
  200
289
  )
290
  }
291
  });
292
- setTimeout( QSMQuestion.removeNew, 250 );
293
  },
294
- addNewQuestion: function( model ) {
295
- QSMAdmin.displayAlert( 'Question created!', 'success' );
296
- QSMQuestion.addQuestionToPage( model );
297
- QSMQuestion.openEditPopup( model.id, $( '.question[data-question-id=' + model.id + ']' ).find('.edit-question-button') );
298
  QSMQuestion.countTotal();
299
- if( $('#answers').find('.answers-single').length == 0 ){
300
- $('#new-answer-button').trigger('click');
301
- }
302
  },
303
- addQuestionToPage: function( model ) {
304
- var page = model.get( 'page' ) + 1;
305
- var template = wp.template( 'question' );
306
- var page_exists = $( '.page:nth-child(' + page + ')' ).length;
307
  var count = 0;
308
- while ( ! page_exists ) {
309
- QSMQuestion.addNewPage(page);
310
- page_exists = $( '.page:nth-child(' + page + ')' ).length;
311
  count++;
312
- if ( count > 5 ) {
313
  page_exists = true;
314
- console.log( 'count reached' );
315
  }
316
  }
317
- var questionName = QSMQuestion.prepareQuestionText( model.get( 'name' ) );
318
- var new_question_title = model.get('question_title');
319
- if( new_question_title === null || typeof new_question_title === "undefined" || new_question_title === "" ){
320
- //Do nothing
321
- }else{
322
- questionName = new_question_title;
323
- }
324
-
325
- if( questionName == '' )
326
- questionName = 'Your new question!';
327
-
328
- $( '.page:nth-child(' + page + ')' ).append( template( { id: model.id, category : model.get('category'), question: questionName } ) );
329
- setTimeout( QSMQuestion.removeNew, 250 );
330
  },
331
- createQuestion: function( page ) {
332
- QSMAdmin.displayAlert( 'Creating question...', 'info' );
333
- QSMQuestion.questions.create(
334
- {
335
  quizID: qsmQuestionSettings.quizID,
336
  page: page
337
  },
@@ -342,12 +342,12 @@ var import_button;
342
  }
343
  );
344
  },
345
- duplicateQuestion: function( questionID ) {
346
- QSMAdmin.displayAlert( 'Duplicating question...', 'info' );
347
- var model = QSMQuestion.questions.get( questionID );
348
  var newModel = _.clone(model.attributes);
349
  newModel.id = null;
350
- QSMQuestion.questions.create(
351
  newModel,
352
  {
353
  headers: { 'X-WP-Nonce': qsmQuestionSettings.nonce },
@@ -356,7 +356,7 @@ var import_button;
356
  }
357
  );
358
  },
359
- saveQuestion: function( questionID, CurrentElement ) {
360
  QSMAdmin.displayAlert('Saving question...', 'info');
361
  var model = QSMQuestion.questions.get(questionID);
362
  var hint = $('#hint').val();
@@ -379,7 +379,8 @@ var import_button;
379
  var file_upload_limit = $("#file_upload_limit").val();
380
  var type_arr = [];
381
  $.each($("input[name='file_upload_type[]']:checked"), function () {
382
- type_arr.push($(this).val());
 
383
  });
384
  if ('new_category' == category) {
385
  category = $('#new_category').val();
@@ -439,47 +440,47 @@ var import_button;
439
  answerEditor: answerType,
440
  other_settings: advanced_option
441
  }, {
442
- headers: {'X-WP-Nonce': qsmQuestionSettings.nonce},
443
  success: QSMQuestion.saveSuccess,
444
  error: QSMAdmin.displayError,
445
  type: 'POST'
446
  });
447
  //CurrentElement.parents('.questionElements').slideUp('slow');
448
  },
449
- saveSuccess: function( model ) {
450
- QSMAdmin.displayAlert( 'Question was saved!', 'success' );
451
- var template = wp.template( 'question' );
452
- var page = model.get( 'page' ) + 1;
453
- var questionName = model.get('name');
454
- var new_question_title = model.get('question_title');
455
- if( new_question_title !== '' ){
456
- questionName = $.QSMSanitize(new_question_title);
457
- }
458
- $( '.question[data-question-id=' + model.id + ']' ).replaceWith( template( { id: model.id, type : model.get('type'), category : model.get('category'), question: questionName } ) );
459
  setTimeout(function () {
460
  $('#save-edit-question-spinner').removeClass('is-active');
461
  }, 250);
462
  setTimeout(QSMQuestion.removeNew, 250);
463
  },
464
- addNewAnswer: function( answer ) {
465
- var answerTemplate = wp.template( 'single-answer' );
466
- $( '#answers' ).append( answerTemplate( { answer: decodeEntities( answer[0] ), points: answer[1], correct: answer[2], count: answer[3], question_id: answer[4], answerType: answer[5], form_type: qsmQuestionSettings.form_type, quiz_system: qsmQuestionSettings.quiz_system } ) );
467
- if(answer[5] == 'rich' && qsmQuestionSettings.qsm_user_ve === 'true'){
468
- var textarea_id = 'answer-' + answer[4] + '-' + answer[3];
469
- wp.editor.remove( textarea_id );
470
- var settings = {
471
- mediaButtons: true,
472
- tinymce: {
473
- forced_root_block : '',
474
- toolbar1: 'formatselect,bold,italic,bullist,numlist,blockquote,alignleft,aligncenter,alignright,link,strikethrough,hr,forecolor,pastetext,removeformat,codeformat,charmap,undo,redo'
475
- },
476
- quicktags: true,
477
- };
478
- wp.editor.initialize( textarea_id, settings );
479
- var anser = QSMQuestion.prepareQuestionText(answer[0]);
480
- $( textarea_id ).val(anser);
481
- tinyMCE.get( textarea_id ).setContent( anser );
482
- }
483
  },
484
  openEditPopup: function (questionID, CurrentElement) {
485
  if (CurrentElement.parents('.question').next('.questionElements').length > 0) {
@@ -629,21 +630,21 @@ var import_button;
629
  $('.questions').sortable('disable');
630
  $('.page').sortable('disable');
631
  },
632
- openEditPagePopup: function( pageID ) {
633
  var page = QSMQuestion.qpages.get(pageID);
634
  $('#edit_page_id').val(pageID);
635
  $("#edit-page-id").text('').text(pageID);
636
- jQuery('#page-options').find(':input, select, textarea').each(function(i, field){
637
  field.value = page.get(field.name);
638
  });
639
  MicroModal.show('modal-page-1');
640
  },
641
- removeNew: function() {
642
- $( '.page-new' ).removeClass( 'page-new' );
643
- $( '.question-new' ).removeClass( 'question-new' );
644
  },
645
- prepareQuestionText: function( question ) {
646
- return jQuery('<textarea />').html( question ).text();
647
  },
648
  prepareEditor: function () {
649
  var settings = {
@@ -659,214 +660,214 @@ var import_button;
659
  }
660
  };
661
 
662
- $(function() {
663
- QSMQuestion.pageCollection = Backbone.Collection.extend({model: QSMQuestion.page});
664
  QSMQuestion.qpages = new QSMQuestion.pageCollection();
665
  QSMQuestion.questionCollection = Backbone.Collection.extend({
666
  url: wpApiSettings.root + 'quiz-survey-master/v1/questions',
667
  model: QSMQuestion.question
668
  });
669
  QSMQuestion.questions = new QSMQuestion.questionCollection();
670
- $( '.new-page-button' ).on( 'click', function( event ) {
671
  event.preventDefault();
672
  QSMQuestion.addNewPage();
673
  });
674
 
675
- $( '.questions' ).on( 'click', '.new-question-button', function( event ) {
676
  event.preventDefault();
677
- QSMQuestion.createQuestion( $( this ).parents( '.page' ).index() );
678
- $('.save-page-button').trigger('click');
679
  });
680
-
681
- $( '.questions' ).on( 'click', '.add-question-bank-button', function( event ) {
682
  event.preventDefault();
683
- QSMQuestion.openQuestionBank( $( this ).parents( '.page' ).index() );
684
  });
685
-
686
- //Show more question on load more
687
- $( document ).on( 'click', '.qb-load-more-question', function( event ) {
688
  event.preventDefault();
689
  QSMQuestion.loadQuestionBank();
690
  });
691
-
692
- //Show category related question
693
- $( document ).on( 'change', '#question-bank-cat', function( event ) {
694
  event.preventDefault();
695
  QSMQuestion.loadQuestionBank('change');
696
  });
697
 
698
- $( '.questions' ).on( 'click', '.edit-question-button', function( event ) {
699
  event.preventDefault();
700
- QSMQuestion.openEditPopup( $( this ).parents( '.question' ).data( 'question-id' ), $(this) );
701
  });
702
  $('.questions').on('click', '.edit-page-button', function (event) {
703
  event.preventDefault();
704
  QSMQuestion.openEditPagePopup($(this).parents('.page').data('page-id'));
705
  });
706
 
707
- $( document ).on( 'click', '.questions .duplicate-question-button', function( event ) {
708
  event.preventDefault();
709
- QSMQuestion.duplicateQuestion( $( this ).parents( '.question' ).data( 'question-id' ) );
710
- $('.save-page-button').trigger('click');
711
  });
712
- $( '.questions' ).on( 'click', '.delete-question-button', function( event ) {
713
- event.preventDefault();
714
- remove = $(this);
715
- // opens-up question-delete modal
716
- MicroModal.show('modal-7');
717
- $('#unlink-question-button').attr('data-question-iid', $(this).data('question-iid'));
718
- $('#delete-question-button').attr('data-question-iid', $(this).data('question-iid'));
719
-
720
- // removes question from database
721
- $('#delete-question-button').click(function(event){
722
- event.preventDefault();
723
- if( confirm('Are you sure?') ){
724
- var question_id = $(this).data('question-iid');
725
- console.log(question_id);
726
- $.ajax( {
727
- url: ajaxurl,
728
- method: 'POST',
729
- data: {
730
- 'action' : 'qsm_delete_question_from_database',
731
- 'question_id': question_id,
732
- 'nonce': qsmQuestionSettings.single_question_nonce
733
- },
734
- success: function(response) {
735
- var data = jQuery.parseJSON( response );
736
- if( data.success === true ){
737
-
738
- console.log( data.message );
739
- } else {
740
- console.log( data.message );
741
- }
742
- }
743
- } );
744
- remove.parents( '.question' ).remove();
745
- QSMQuestion.countTotal();
746
- $('.save-page-button').trigger('click');
747
- }
748
- MicroModal.close('modal-7');
749
- });
750
 
751
- // unlink question from a particular quiz.
752
- $('#unlink-question-button').click(function(event){
753
- event.preventDefault();
754
- if( confirm('Are you sure?') ){
755
- var question_id = $(this).data('question-iid');
756
-
757
- console.log(question_id);
758
- remove.parents( '.question' ).remove();
759
- QSMQuestion.countTotal();
760
- $('.save-page-button').trigger('click');
761
- }
762
- MicroModal.close('modal-7');
763
- });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
764
  });
765
- $( '.questions' ).on( 'click', '.delete-page-button', function( event ) {
766
  event.preventDefault();
767
- if( confirm('Are you sure?') ){
768
- $( this ).parents( '.page' ).remove();
769
- $('.save-page-button').trigger('click');
770
- }
771
  });
772
- $( document ).on( 'click', '#answers .delete-answer-button', function( event ) {
773
  event.preventDefault();
774
- $( this ).parents( '.answers-single' ).remove();
775
  });
776
- $( document ).on( 'click', '#delete-action .deletion', function( event ) {
777
  event.preventDefault();
778
- $( this ).parents( '.questionElements' ).slideUp('slow');
779
  });
780
- $( document ).on( 'click', '#save-popup-button', function( event ) {
781
  event.preventDefault();
782
- $('#save-edit-question-spinner').addClass('is-active');
783
- var model_html = $('#modal-1-content').html();
784
- $('#modal-1-content').children().remove();
785
- QSMQuestion.saveQuestion( $( this ).parents('.questionElements').children( '#edit_question_id' ).val(), $(this) );
786
- $('.save-page-button').trigger('click');
787
- $('#modal-1-content').html( model_html );
788
- });
789
- $( document ).on( 'click', '#new-answer-button', function( event ) {
790
  event.preventDefault();
791
- var answer_length = $( '#answers' ).find('.answers-single').length;
792
- if( answer_length > 1 && $('#question_type').val() == 13 ){
793
- alert('You can not add more than 2 answer for Polar Question type');
794
- return;
795
- }
796
- var question_id = $('#edit_question_id').val();
797
- var answerType = $('#change-answer-editor').val();
798
- var answer = [ '', '', 0, answer_length + 1, question_id, answerType];
799
- QSMQuestion.addNewAnswer( answer );
800
  });
801
-
802
- $( '.qsm-popup-bank' ).on( 'click', '.import-button', function( event) {
803
  event.preventDefault();
804
- $(this).text('').text('Adding Question');
805
- import_button = $(this);
806
- QSMQuestion.addQuestionFromQuestionBank( $( this ).parents( '.question-bank-question' ).data( 'question-id' ) );
807
- $('.import-button').addClass('disable_import');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
808
  });
809
-
810
- //Click on selected question button.
811
- $( '.qsm-popup-bank' ).on( 'click', '#qsm-import-selected-question', function( event) {
812
- var $total_selction = $('#question-bank').find('[name="qsm-question-checkbox[]"]:checked').length;
813
- if($total_selction === 0){
814
- alert('No question is selected.');
815
- }else{
816
- $.fn.reverse = [].reverse;
817
- $($('#question-bank').find('[name="qsm-question-checkbox[]"]:checked').parents('.question-bank-question').reverse()).each(function(){
818
- $(this).find('.import-button').text('').text('Adding Question');
819
- import_button = $(this).find('.import-button');
820
- QSMQuestion.addQuestionFromQuestionBank( $( this ).data( 'question-id' ) );
821
- $(this).find('.import-button').text('').text('Add Question');
822
- });
823
- $('.import-button').addClass('disable_import');
824
- $('#question-bank').find('[name="qsm-question-checkbox[]"]').attr('checked',false);
825
- }
826
- });
827
- //Delete question from question bank
828
- $( '.qsm-popup-bank' ).on( 'click', '#qsm-delete-selected-question', function( event) {
829
- if( confirm( 'are you sure?' ) ){
830
- var $total_selction = $('#question-bank').find('[name="qsm-question-checkbox[]"]:checked').length;
831
- if($total_selction === 0){
832
- alert('No question is selected.');
833
- }else{
834
- $.fn.reverse = [].reverse;
835
- var question_ids = $($('#question-bank').find('[name="qsm-question-checkbox[]"]:checked').parents('.question-bank-question').reverse()).map(function() {
836
- return $( this ).data( 'question-id' );
837
- }).get().join(',');
838
- if( question_ids ){
839
- $.ajax( {
840
- url: ajaxurl,
841
- method: 'POST',
842
- data: {
843
- 'action' : 'qsm_delete_question_question_bank',
844
- 'question_ids': question_ids,
845
- 'nonce': qsmQuestionSettings.question_bank_nonce
846
- },
847
- success: function(response) {
848
- var data = jQuery.parseJSON( response );
849
- if( data.success === true ){
850
- $('#question-bank').find('[name="qsm-question-checkbox[]"]:checked').parents('.question-bank-question').slideUp('slow');
851
- alert( data.message );
852
- } else {
853
- alert( data.message );
854
- }
855
- }
856
- } );
857
- }
858
- }
859
- }
860
- });
861
-
862
- //Select all button.
863
- $( document ).on( 'change', '#qsm_select_all_question', function( event) {
864
- $('.qsm-question-checkbox').prop('checked', jQuery('#qsm_select_all_question').prop('checked'));
865
- });
866
 
867
- $( '.save-page-button' ).on( 'click', function( event ) {
868
  event.preventDefault();
869
- $('#save-edit-quiz-pages').addClass('is-active');
870
  QSMQuestion.savePages();
871
  });
872
  $('#save-page-popup-button').on('click', function (event) {
@@ -885,179 +886,179 @@ var import_button;
885
  MicroModal.close('modal-page-1');
886
  }
887
  });
888
-
889
- $( document ).on( 'change', '#change-answer-editor', function( event ) {
890
- var newVal = $(this).val();
891
- if(confirm('All answer will be reset, Do you want to still continue?')){
892
- $('#answers').find( '.answers-single' ).remove();
893
- }else{
894
- if(newVal == 'rich'){
895
- $(this).val('text');
896
- }else{
897
- $(this).val('rich');
898
- }
899
- return false;
900
- }
901
  });
902
-
903
  // Adds event handlers for searching questions
904
- $( '#question_search' ).on( 'keyup', function() {
905
- $( '.question' ).each(function() {
906
- if ( $(this).text().toLowerCase().indexOf( $( '#question_search' ).val().toLowerCase()) === -1 ) {
907
  $(this).hide();
908
  } else {
909
  $(this).show();
910
  }
911
  });
912
- $( '.page' ).each(function() {
913
- if ( 0 === $(this).children( '.question:visible' ).length ) {
914
  $(this).hide();
915
  } else {
916
  $(this).show();
917
  }
918
  });
919
- if ( 0 === $( '#question_search' ).val().length ) {
920
- $( '.page' ).show();
921
- $( '.question' ).show();
922
  }
923
  });
924
 
925
- qsm_init_sortable();
926
-
927
- if(qsmQuestionSettings.qsm_user_ve === 'true'){
928
- QSMQuestion.prepareEditor();
929
- }
930
  QSMQuestion.loadQuestions();
931
-
932
- /**
933
- * Hide/show advanced option
934
- */
935
- $(document).on('click','#show-advanced-option',function(){
936
- var $this = $(this);
937
- $(this).next('div.advanced-content').slideToggle('slow',function(){
938
- if ($(this).is(':visible')) {
939
- $this.text('').html('Hide advance options &laquo;');
940
- } else {
941
- $this.text('').html('Show advance options &raquo;');
942
- }
943
- });
944
- });
945
-
946
- //Hide the question settings based on question type
947
- $(document).on('change','#question_type', function(){
948
- var question_val = $(this).val();
949
- $('.qsm_hide_for_other').hide();
950
- if( $('.qsm_show_question_type_' + question_val).length > 0 ){
951
- $('.qsm_show_question_type_' + question_val).show();
952
- }
953
- qsm_hide_show_question_desc( question_val );
954
- });
955
-
956
- //Add new category
957
- $( document ).on('click', '#qsm-category-add-toggle', function(){
958
- if( $( '#qsm-category-add' ).is(":visible") ){
959
- $('.questionElements #new_category_new').attr('checked', false);
960
- $( '#qsm-category-add' ).slideUp('slow');
961
- }else{
962
- $('.questionElements #new_category_new').attr('checked', true).prop('checked', 'checked');
963
- $( '#qsm-category-add' ).slideDown('slow');
964
- }
965
- });
966
-
967
- //Hide/show quesion description
968
- $( document ).on('click', '.qsm-show-question-desc-box', function(e){
969
- e.preventDefault();
970
- if( $(this).next('.qsm-row').is(':visible') ){
971
- $(this).html('').html('<span class="dashicons dashicons-plus-alt2"></span> ' + qsmQuestionSettings.show_desc_text);
972
- $(this).next('.qsm-row').slideUp();
973
- }else{
974
- $(this).hide();
975
- var question_description = wp.editor.getContent( 'question-text' );
976
- if( question_description == '' || question_description == null ){
977
- tinyMCE.get( 'question-text' ).setContent( 'Add description here!' );
978
- }
979
- $(this).next('.qsm-row').slideDown();
980
- }
981
- });
982
 
983
- //Hide/show correct answer info
984
- $( document ).on('click', '.qsm-show-correct-info-box', function(e){
985
- e.preventDefault();
986
- if( $(this).next('.qsm-row').is(':visible') ){
987
- $(this).html('').html('<span class="dashicons dashicons-plus-alt2"></span> ' + qsmQuestionSettings.show_correct_info_text);
988
- $(this).next('.qsm-row').slideUp();
989
- }else{
990
- $(this).hide();
991
- $(this).next('.qsm-row').slideDown();
992
- }
993
- });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
994
  });
995
- var decodeEntities = (function () {
996
- //create a new html document (doesn't execute script tags in child elements)
997
- var doc = document.implementation.createHTMLDocument("");
998
- var element = doc.createElement('div');
999
 
1000
- function getText(str) {
1001
- element.innerHTML = str;
1002
- str = element.textContent;
1003
- element.textContent = '';
1004
- return str;
1005
- }
1006
 
1007
- function decodeHTMLEntities(str) {
1008
- if (str && typeof str === 'string') {
1009
- var x = getText(str);
1010
- while (str !== x) {
1011
- str = x;
1012
- x = getText(x);
1013
- }
1014
- return x;
1015
- }
1016
- }
1017
- return decodeHTMLEntities;
1018
- })();
1019
-
1020
- function qsm_hide_show_question_desc(question_type){
1021
- $('.question-type-description').hide();
1022
- if( $('#question_type_' + question_type + '_description').length > 0 ){
1023
- $('#question_type_' + question_type + '_description').show();
1024
- }
1025
- }
1026
-
1027
- function qsm_init_sortable(){
1028
- $( '.questions' ).sortable({
1029
  opacity: 70,
1030
  cursor: 'move',
1031
  placeholder: "ui-state-highlight",
1032
- stop: function(evt, ui) {
1033
- $('.questions > .page').each(function(){
1034
- var page = parseInt($(this).index()) + 1;
1035
- $(this).find('.page-number').text( 'Page ' + page );
1036
- });
1037
- setTimeout(
1038
- function(){
1039
- $('.save-page-button').trigger('click');
1040
- },
1041
- 200
1042
- )
1043
- }
1044
  });
1045
- $( '.page' ).sortable({
1046
  items: '.question',
1047
  opacity: 70,
1048
  cursor: 'move',
1049
  placeholder: "ui-state-highlight",
1050
  connectWith: '.page',
1051
- stop: function(evt, ui) {
1052
- setTimeout(
1053
- function(){
1054
- $('.save-page-button').trigger('click');
1055
- },
1056
- 200
1057
- )
1058
- }
1059
  });
1060
- }
1061
  function qsmRandomID(length) {
1062
  var result = '';
1063
  var characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
5
  var QSMQuestion;
6
  var import_button;
7
  (function ($) {
8
+ $.QSMSanitize = function (input) {
9
+ return input.replace(/<(|\/|[^>\/bi]|\/[^>bi]|[^\/>][^>]+|\/[^>][^>]+)>/g, '');
10
+ };
11
  QSMQuestion = {
12
  question: Backbone.Model.extend({
13
  defaults: {
42
  /**
43
  * Counts the total number of questions and then updates #total-questions span.
44
  */
45
+ countTotal: function () {
46
  var total = 0;
47
 
48
  // Cycles through each page.
49
+ _.each(jQuery('.page'), function (page) {
50
 
51
  // If page is empty, continue to the next.
52
+ if (0 == jQuery(page).children('.question').length) {
53
  return;
54
  }
55
  // Cycle through each question and add to our total.
56
+ _.each(jQuery(page).children('.question'), function (question) {
57
  total += 1;
58
  });
59
  });
60
+ $('#total-questions').text(total);
61
  },
62
+ openQuestionBank: function (pageID) {
63
  QSMQuestion.loadQuestionBank();
64
+ $('#add-question-bank-page').val(pageID);
65
+ MicroModal.show('modal-2', {
66
+ onClose: function () {
67
+ $('.save-page-button').trigger('click');
68
+ }
69
+ });
70
  },
71
+ loadQuestionBank: function (action = '') {
72
+ if (action == 'change') {
73
+ $('.qb-load-more-wrapper').remove();
74
+ $('#question-bank').find('.question-bank-question').remove();
75
+ $('#question-bank').append('<div style="top: 45px;position: relative;" class="qsm-spinner-loader"></div>');
76
+ } else if ($('.qb-load-more-wrapper').length > 0) {
77
+ $('.qb-load-more-question').hide();
78
+ $('.qb-load-more-wrapper').append('<div class="qsm-spinner-loader"></div>');
79
+ } else {
80
+ $('#question-bank').empty();
81
+ $('#question-bank').append('<div class="qsm-spinner-loader"></div>');
82
+ }
83
+ $.ajax({
84
  url: wpApiSettings.root + 'quiz-survey-master/v1/bank_questions/0/',
85
  method: 'GET',
86
+ beforeSend: function (xhr) {
87
+ xhr.setRequestHeader('X-WP-Nonce', qsmQuestionSettings.nonce);
88
  },
89
  data: {
90
+ 'quizID': 0,
91
+ 'page': $('#question_back_page_number').length > 0 ? parseInt($('#question_back_page_number').val()) + 1 : 1,
92
+ 'category': $('#question-bank-cat').val()
93
  },
94
  success: QSMQuestion.questionBankLoadSuccess
95
  });
96
  },
97
+ questionBankLoadSuccess: function (questions) {
98
+ var pagination = questions.pagination;
99
+ var questions = questions.questions;
100
+ if ($('.qb-load-more-wrapper').length > 0) {
101
+ $('.qb-load-more-wrapper').remove();
102
+ } else {
103
+ $('#question-bank').empty();
104
+ }
105
+ for (var i = 0; i < questions.length; i++) {
106
+ QSMQuestion.addQuestionToQuestionBank(questions[i]);
107
+ }
108
+ if (pagination.total_pages > pagination.current_page) {
109
+ var pagination_html = '<div class="qb-load-more-wrapper" style="text-align: center;margin: 20px 0 10px 0;"><input type="hidden" id="question_back_page_number" value="' + pagination.current_page + '"/>';
110
+ pagination_html += '<input type="hidden" id="question_back_total_pages" value="' + pagination.total_pages + '"/>';
111
+ pagination_html += '<a href="#" class="button button-primary qb-load-more-question">Load More Questions</a></div>';
112
+ $('#question-bank').append(pagination_html);
113
+ }
114
+ if (pagination.current_page == 1 && qsmQuestionSettings.categories.length > 0) {
115
+ var category_arr = qsmQuestionSettings.categories;
116
+ $cat_html = '<select name="question-bank-cat" id="question-bank-cat">';
117
+ $cat_html += '<option value="">All Questions</option>';
118
+ $.each(category_arr, function (index, value) {
119
+ if (value.category !== '')
120
+ $cat_html += '<option value="' + value.category + '">' + value.category + ' Questions</option>';
121
+ });
122
+ $cat_html += '</select>';
123
+ $('#question-bank').prepend($cat_html);
124
+ $('#question-bank-cat').val(pagination.category);
125
+ }
126
+ if (pagination.current_page == 1) {
127
+ $('#question-bank').prepend('<button class="button button-primary" id="qsm-import-selected-question">Import All Selected Questions</button>');
128
+ $('#question-bank').prepend('<button class="button button-default" id="qsm-delete-selected-question">Delete Selected Question from Bank</button>');
129
+ $('#question-bank').prepend('<label class="qsm-select-all-label"><input type="checkbox" id="qsm_select_all_question" /> Select All Question</button>');
130
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
131
  },
132
+ addQuestionToQuestionBank: function (question) {
133
+ var questionText = QSMQuestion.prepareQuestionText(question.name);
134
+ var template = wp.template('single-question-bank-question');
135
+ if (question.question_title !== "undefined" && question.question_title !== "") {
136
+ questionText = question.question_title;
137
+ }
138
+ $('#question-bank').append(template({ id: question.id, question: questionText, category: question.category, quiz_name: question.quiz_name }));
139
  },
140
+ addQuestionFromQuestionBank: function (questionID) {
141
  //MicroModal.close( 'modal-2' );
142
  //QSMAdmin.displayAlert( 'Adding question...', 'info' );
143
+ var model = new QSMQuestion.question({ id: questionID });
144
+ model.fetch({
145
  headers: { 'X-WP-Nonce': qsmQuestionSettings.nonce },
146
  url: wpApiSettings.root + 'quiz-survey-master/v1/questions/' + questionID,
147
  success: QSMQuestion.questionBankSuccess,
148
  error: QSMAdmin.displayError
149
+ });
150
  },
151
+ questionBankSuccess: function (model) {
152
+ var page = parseInt($('#add-question-bank-page').val(), 10);
153
+ model.set('page', page);
154
  //QSMAdmin.displayAlert( 'Question added!', 'success' );
155
+ QSMQuestion.questions.add(model);
156
+ QSMQuestion.addQuestionToPage(model);
157
+ $('.import-button').removeClass('disable_import');
158
+ import_button.html('').html('Add Question');
159
  },
160
+ prepareCategories: function () {
161
  QSMQuestion.categories = [];
162
+ QSMQuestion.questions.each(function (question) {
163
+ var category = question.get('category');
164
+ if (0 !== category.length && !_.contains(QSMQuestion.categories, category)) {
165
+ QSMQuestion.categories.push(category);
166
  }
167
  });
168
  },
169
+ processCategories: function () {
170
+ $('.category').remove();
171
+ _.each(QSMQuestion.categories, function (category) {
172
+ QSMQuestion.addCategory(category);
173
  });
174
  },
175
+ addCategory: function (category) {
176
+ var template = wp.template('single-category');
177
+ $('#categories').prepend(template({ category: category }));
178
  },
179
+ loadQuestions: function () {
180
+ QSMAdmin.displayAlert('Loading questions...', 'info');
181
+ QSMQuestion.questions.fetch({
182
  headers: { 'X-WP-Nonce': qsmQuestionSettings.nonce },
183
  data: { quizID: qsmQuestionSettings.quizID },
184
  success: QSMQuestion.loadSuccess,
185
  error: QSMAdmin.displayError
186
+ });
187
  },
188
+ loadSuccess: function () {
189
  QSMAdmin.clearAlerts();
190
  $('.qsm-showing-loader').remove();
191
  var question;
192
+ _.each(qsmQuestionSettings.qpages, function (page) {
193
  QSMQuestion.qpages.add(page);
194
  });
195
+ if (qsmQuestionSettings.pages.length > 0) {
196
+ for (var i = 0; i < qsmQuestionSettings.pages.length; i++) {
197
+ for (var j = 0; j < qsmQuestionSettings.pages[i].length; j++) {
198
+ question = QSMQuestion.questions.get(qsmQuestionSettings.pages[i][j]);
199
+ QSMQuestion.addQuestionToPage(question);
200
  }
201
  }
202
  } else {
203
+ //We have removed this code in 7.0.0 because not allow to delete the single page.
204
+ QSMQuestion.questions.each(QSMQuestion.addQuestionToPage);
205
+ }
206
+ //Create Default pages and one question.
207
+ if (qsmQuestionSettings.pages.length == 0 && QSMQuestion.questions.length == 0) {
208
+ $('.new-page-button').trigger('click');
209
+ $('.questions .new-question-button').trigger('click');
210
  }
 
 
 
 
 
211
  QSMQuestion.countTotal();
212
  },
213
+ updateQPage: function (pageID) {
214
+ QSMAdmin.displayAlert('Saving page info', 'info');
215
  var pageInfo = QSMQuestion.qpages.get(pageID);
216
+ jQuery('#page-options').find(':input, select, textarea').each(function (i, field) {
217
  pageInfo.set(field.name, field.value);
218
  });
219
  },
220
+ savePages: function () {
221
+ QSMAdmin.displayAlert('Saving pages and questions...', 'info');
222
  var pages = [];
223
  var qpages = [];
224
  var pageInfo = null;
225
 
226
  // Cycles through each page and add page + questions to pages variable
227
+ _.each(jQuery('.page'), function (page) {
228
 
229
  // If page is empty, do not add it.
230
+ if (0 == jQuery(page).children('.question').length) {
231
  return;
232
  }
233
  var singlePage = [];
234
  // Cycle through each question and add to the page.
235
+ _.each(jQuery(page).children('.question'), function (question) {
236
+ singlePage.push(jQuery(question).data('question-id'))
237
  });
238
+ pages.push(singlePage);
239
  /**
240
  * Prepare qpages Object
241
  */
242
+ pageInfo = QSMQuestion.qpages.get(jQuery(page).data('page-id'));
243
  pageInfo.set('questions', singlePage);
244
  qpages.push(pageInfo.attributes);
245
  });
246
+ console.log(pages);
247
  var data = {
248
  action: 'qsm_save_pages',
249
  pages: pages,
250
  qpages: qpages,
251
+ quiz_id: qsmQuestionSettings.quizID,
252
+ nonce: qsmQuestionSettings.saveNonce,
253
  };
254
+
255
+ jQuery.ajax(ajaxurl, {
256
  data: data,
257
  method: 'POST',
258
  success: QSMQuestion.savePagesSuccess,
259
  error: QSMAdmin.displayjQueryError
260
  });
261
  },
262
+ savePagesSuccess: function () {
263
+ QSMAdmin.displayAlert('Questions and pages were saved!', 'success');
264
  $('#save-edit-quiz-pages').removeClass('is-active');
265
  },
266
+ addNewPage: function (pageID) {
267
+ var template = wp.template('page');
268
  if (typeof pageID == 'undefined' || pageID == '') {
269
  var newPageID = QSMQuestion.qpages.length + 1;
270
  var pageID = newPageID;
271
+ var pageInfo = QSMQuestion.qpages.add({ id: newPageID, quizID: qsmQuestionSettings.quizID, pagekey: qsmRandomID(8), hide_prevbtn: 0 });
272
  }
273
  var pageInfo = QSMQuestion.qpages.get(pageID);
274
+ $('.questions').append(template(pageInfo));
275
+ var page = $('.questions').find('.page').length;
276
  $('.page:nth-child(' + page + ')').find('.page-number').text('Page ' + page);
277
+ $('.page').sortable({
278
  items: '.question',
279
  opacity: 70,
280
  cursor: 'move',
281
  placeholder: "ui-state-highlight",
282
  connectWith: '.page',
283
+ stop: function (evt, ui) {
284
  setTimeout(
285
+ function () {
286
  $('.save-page-button').trigger('click');
287
  },
288
  200
289
  )
290
  }
291
  });
292
+ setTimeout(QSMQuestion.removeNew, 250);
293
  },
294
+ addNewQuestion: function (model) {
295
+ QSMAdmin.displayAlert('Question created!', 'success');
296
+ QSMQuestion.addQuestionToPage(model);
297
+ QSMQuestion.openEditPopup(model.id, $('.question[data-question-id=' + model.id + ']').find('.edit-question-button'));
298
  QSMQuestion.countTotal();
299
+ if ($('#answers').find('.answers-single').length == 0) {
300
+ $('#new-answer-button').trigger('click');
301
+ }
302
  },
303
+ addQuestionToPage: function (model) {
304
+ var page = model.get('page') + 1;
305
+ var template = wp.template('question');
306
+ var page_exists = $('.page:nth-child(' + page + ')').length;
307
  var count = 0;
308
+ while (!page_exists) {
309
+ QSMQuestion.addNewPage(page);
310
+ page_exists = $('.page:nth-child(' + page + ')').length;
311
  count++;
312
+ if (count > 5) {
313
  page_exists = true;
314
+ console.log('count reached');
315
  }
316
  }
317
+ var questionName = QSMQuestion.prepareQuestionText(model.get('name'));
318
+ var new_question_title = model.get('question_title');
319
+ if (new_question_title === null || typeof new_question_title === "undefined" || new_question_title === "") {
320
+ //Do nothing
321
+ } else {
322
+ questionName = new_question_title;
323
+ }
324
+
325
+ if (questionName == '')
326
+ questionName = 'Your new question!';
327
+
328
+ $('.page:nth-child(' + page + ')').append(template({ id: model.id, category: model.get('category'), question: questionName }));
329
+ setTimeout(QSMQuestion.removeNew, 250);
330
  },
331
+ createQuestion: function (page) {
332
+ QSMAdmin.displayAlert('Creating question...', 'info');
333
+ QSMQuestion.questions.create(
334
+ {
335
  quizID: qsmQuestionSettings.quizID,
336
  page: page
337
  },
342
  }
343
  );
344
  },
345
+ duplicateQuestion: function (questionID) {
346
+ QSMAdmin.displayAlert('Duplicating question...', 'info');
347
+ var model = QSMQuestion.questions.get(questionID);
348
  var newModel = _.clone(model.attributes);
349
  newModel.id = null;
350
+ QSMQuestion.questions.create(
351
  newModel,
352
  {
353
  headers: { 'X-WP-Nonce': qsmQuestionSettings.nonce },
356
  }
357
  );
358
  },
359
+ saveQuestion: function (questionID, CurrentElement) {
360
  QSMAdmin.displayAlert('Saving question...', 'info');
361
  var model = QSMQuestion.questions.get(questionID);
362
  var hint = $('#hint').val();
379
  var file_upload_limit = $("#file_upload_limit").val();
380
  var type_arr = [];
381
  $.each($("input[name='file_upload_type[]']:checked"), function () {
382
+ type_value = $(this).val().replace(/,/g, '');
383
+ type_arr.push(type_value);
384
  });
385
  if ('new_category' == category) {
386
  category = $('#new_category').val();
440
  answerEditor: answerType,
441
  other_settings: advanced_option
442
  }, {
443
+ headers: { 'X-WP-Nonce': qsmQuestionSettings.nonce },
444
  success: QSMQuestion.saveSuccess,
445
  error: QSMAdmin.displayError,
446
  type: 'POST'
447
  });
448
  //CurrentElement.parents('.questionElements').slideUp('slow');
449
  },
450
+ saveSuccess: function (model) {
451
+ QSMAdmin.displayAlert('Question was saved!', 'success');
452
+ var template = wp.template('question');
453
+ var page = model.get('page') + 1;
454
+ var questionName = model.get('name');
455
+ var new_question_title = model.get('question_title');
456
+ if (new_question_title !== '') {
457
+ questionName = $.QSMSanitize(new_question_title);
458
+ }
459
+ $('.question[data-question-id=' + model.id + ']').replaceWith(template({ id: model.id, type: model.get('type'), category: model.get('category'), question: questionName }));
460
  setTimeout(function () {
461
  $('#save-edit-question-spinner').removeClass('is-active');
462
  }, 250);
463
  setTimeout(QSMQuestion.removeNew, 250);
464
  },
465
+ addNewAnswer: function (answer) {
466
+ var answerTemplate = wp.template('single-answer');
467
+ $('#answers').append(answerTemplate({ answer: decodeEntities(answer[0]), points: answer[1], correct: answer[2], count: answer[3], question_id: answer[4], answerType: answer[5], form_type: qsmQuestionSettings.form_type, quiz_system: qsmQuestionSettings.quiz_system }));
468
+ if (answer[5] == 'rich' && qsmQuestionSettings.qsm_user_ve === 'true') {
469
+ var textarea_id = 'answer-' + answer[4] + '-' + answer[3];
470
+ wp.editor.remove(textarea_id);
471
+ var settings = {
472
+ mediaButtons: true,
473
+ tinymce: {
474
+ forced_root_block: '',
475
+ toolbar1: 'formatselect,bold,italic,bullist,numlist,blockquote,alignleft,aligncenter,alignright,link,strikethrough,hr,forecolor,pastetext,removeformat,codeformat,charmap,undo,redo'
476
+ },
477
+ quicktags: true,
478
+ };
479
+ wp.editor.initialize(textarea_id, settings);
480
+ var anser = QSMQuestion.prepareQuestionText(answer[0]);
481
+ $(textarea_id).val(anser);
482
+ tinyMCE.get(textarea_id).setContent(anser);
483
+ }
484
  },
485
  openEditPopup: function (questionID, CurrentElement) {
486
  if (CurrentElement.parents('.question').next('.questionElements').length > 0) {
630
  $('.questions').sortable('disable');
631
  $('.page').sortable('disable');
632
  },
633
+ openEditPagePopup: function (pageID) {
634
  var page = QSMQuestion.qpages.get(pageID);
635
  $('#edit_page_id').val(pageID);
636
  $("#edit-page-id").text('').text(pageID);
637
+ jQuery('#page-options').find(':input, select, textarea').each(function (i, field) {
638
  field.value = page.get(field.name);
639
  });
640
  MicroModal.show('modal-page-1');
641
  },
642
+ removeNew: function () {
643
+ $('.page-new').removeClass('page-new');
644
+ $('.question-new').removeClass('question-new');
645
  },
646
+ prepareQuestionText: function (question) {
647
+ return jQuery('<textarea />').html(question).text();
648
  },
649
  prepareEditor: function () {
650
  var settings = {
660
  }
661
  };
662
 
663
+ $(function () {
664
+ QSMQuestion.pageCollection = Backbone.Collection.extend({ model: QSMQuestion.page });
665
  QSMQuestion.qpages = new QSMQuestion.pageCollection();
666
  QSMQuestion.questionCollection = Backbone.Collection.extend({
667
  url: wpApiSettings.root + 'quiz-survey-master/v1/questions',
668
  model: QSMQuestion.question
669
  });
670
  QSMQuestion.questions = new QSMQuestion.questionCollection();
671
+ $('.new-page-button').on('click', function (event) {
672
  event.preventDefault();
673
  QSMQuestion.addNewPage();
674
  });
675
 
676
+ $('.questions').on('click', '.new-question-button', function (event) {
677
  event.preventDefault();
678
+ QSMQuestion.createQuestion($(this).parents('.page').index());
679
+ $('.save-page-button').trigger('click');
680
  });
681
+
682
+ $('.questions').on('click', '.add-question-bank-button', function (event) {
683
  event.preventDefault();
684
+ QSMQuestion.openQuestionBank($(this).parents('.page').index());
685
  });
686
+
687
+ //Show more question on load more
688
+ $(document).on('click', '.qb-load-more-question', function (event) {
689
  event.preventDefault();
690
  QSMQuestion.loadQuestionBank();
691
  });
692
+
693
+ //Show category related question
694
+ $(document).on('change', '#question-bank-cat', function (event) {
695
  event.preventDefault();
696
  QSMQuestion.loadQuestionBank('change');
697
  });
698
 
699
+ $('.questions').on('click', '.edit-question-button', function (event) {
700
  event.preventDefault();
701
+ QSMQuestion.openEditPopup($(this).parents('.question').data('question-id'), $(this));
702
  });
703
  $('.questions').on('click', '.edit-page-button', function (event) {
704
  event.preventDefault();
705
  QSMQuestion.openEditPagePopup($(this).parents('.page').data('page-id'));
706
  });
707
 
708
+ $(document).on('click', '.questions .duplicate-question-button', function (event) {
709
  event.preventDefault();
710
+ QSMQuestion.duplicateQuestion($(this).parents('.question').data('question-id'));
711
+ $('.save-page-button').trigger('click');
712
  });
713
+ $('.questions').on('click', '.delete-question-button', function (event) {
714
+ event.preventDefault();
715
+ remove = $(this);
716
+ // opens-up question-delete modal
717
+ MicroModal.show('modal-7');
718
+ $('#unlink-question-button').attr('data-question-iid', $(this).data('question-iid'));
719
+ $('#delete-question-button').attr('data-question-iid', $(this).data('question-iid'));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
720
 
721
+ // removes question from database
722
+ $('#delete-question-button').click(function (event) {
723
+ event.preventDefault();
724
+ if (confirm('Are you sure?')) {
725
+ var question_id = $(this).data('question-iid');
726
+ console.log(question_id);
727
+ $.ajax({
728
+ url: ajaxurl,
729
+ method: 'POST',
730
+ data: {
731
+ 'action': 'qsm_delete_question_from_database',
732
+ 'question_id': question_id,
733
+ 'nonce': qsmQuestionSettings.single_question_nonce
734
+ },
735
+ success: function (response) {
736
+ var data = jQuery.parseJSON(response);
737
+ if (data.success === true) {
738
+
739
+ console.log(data.message);
740
+ } else {
741
+ console.log(data.message);
742
+ }
743
+ }
744
+ });
745
+ remove.parents('.question').remove();
746
+ QSMQuestion.countTotal();
747
+ $('.save-page-button').trigger('click');
748
+ }
749
+ MicroModal.close('modal-7');
750
+ });
751
+
752
+ // unlink question from a particular quiz.
753
+ $('#unlink-question-button').click(function (event) {
754
+ event.preventDefault();
755
+ if (confirm('Are you sure?')) {
756
+ var question_id = $(this).data('question-iid');
757
+
758
+ console.log(question_id);
759
+ remove.parents('.question').remove();
760
+ QSMQuestion.countTotal();
761
+ $('.save-page-button').trigger('click');
762
+ }
763
+ MicroModal.close('modal-7');
764
+ });
765
  });
766
+ $('.questions').on('click', '.delete-page-button', function (event) {
767
  event.preventDefault();
768
+ if (confirm('Are you sure?')) {
769
+ $(this).parents('.page').remove();
770
+ $('.save-page-button').trigger('click');
771
+ }
772
  });
773
+ $(document).on('click', '#answers .delete-answer-button', function (event) {
774
  event.preventDefault();
775
+ $(this).parents('.answers-single').remove();
776
  });
777
+ $(document).on('click', '#delete-action .deletion', function (event) {
778
  event.preventDefault();
779
+ $(this).parents('.questionElements').slideUp('slow');
780
  });
781
+ $(document).on('click', '#save-popup-button', function (event) {
782
  event.preventDefault();
783
+ $('#save-edit-question-spinner').addClass('is-active');
784
+ var model_html = $('#modal-1-content').html();
785
+ $('#modal-1-content').children().remove();
786
+ QSMQuestion.saveQuestion($(this).parents('.questionElements').children('#edit_question_id').val(), $(this));
787
+ $('.save-page-button').trigger('click');
788
+ $('#modal-1-content').html(model_html);
789
+ });
790
+ $(document).on('click', '#new-answer-button', function (event) {
791
  event.preventDefault();
792
+ var answer_length = $('#answers').find('.answers-single').length;
793
+ if (answer_length > 1 && $('#question_type').val() == 13) {
794
+ alert('You can not add more than 2 answer for Polar Question type');
795
+ return;
796
+ }
797
+ var question_id = $('#edit_question_id').val();
798
+ var answerType = $('#change-answer-editor').val();
799
+ var answer = ['', '', 0, answer_length + 1, question_id, answerType];
800
+ QSMQuestion.addNewAnswer(answer);
801
  });
802
+
803
+ $('.qsm-popup-bank').on('click', '.import-button', function (event) {
804
  event.preventDefault();
805
+ $(this).text('').text('Adding Question');
806
+ import_button = $(this);
807
+ QSMQuestion.addQuestionFromQuestionBank($(this).parents('.question-bank-question').data('question-id'));
808
+ $('.import-button').addClass('disable_import');
809
+ });
810
+
811
+ //Click on selected question button.
812
+ $('.qsm-popup-bank').on('click', '#qsm-import-selected-question', function (event) {
813
+ var $total_selction = $('#question-bank').find('[name="qsm-question-checkbox[]"]:checked').length;
814
+ if ($total_selction === 0) {
815
+ alert('No question is selected.');
816
+ } else {
817
+ $.fn.reverse = [].reverse;
818
+ $($('#question-bank').find('[name="qsm-question-checkbox[]"]:checked').parents('.question-bank-question').reverse()).each(function () {
819
+ $(this).find('.import-button').text('').text('Adding Question');
820
+ import_button = $(this).find('.import-button');
821
+ QSMQuestion.addQuestionFromQuestionBank($(this).data('question-id'));
822
+ $(this).find('.import-button').text('').text('Add Question');
823
+ });
824
+ $('.import-button').addClass('disable_import');
825
+ $('#question-bank').find('[name="qsm-question-checkbox[]"]').attr('checked', false);
826
+ }
827
+ });
828
+ //Delete question from question bank
829
+ $('.qsm-popup-bank').on('click', '#qsm-delete-selected-question', function (event) {
830
+ if (confirm('are you sure?')) {
831
+ var $total_selction = $('#question-bank').find('[name="qsm-question-checkbox[]"]:checked').length;
832
+ if ($total_selction === 0) {
833
+ alert('No question is selected.');
834
+ } else {
835
+ $.fn.reverse = [].reverse;
836
+ var question_ids = $($('#question-bank').find('[name="qsm-question-checkbox[]"]:checked').parents('.question-bank-question').reverse()).map(function () {
837
+ return $(this).data('question-id');
838
+ }).get().join(',');
839
+ if (question_ids) {
840
+ $.ajax({
841
+ url: ajaxurl,
842
+ method: 'POST',
843
+ data: {
844
+ 'action': 'qsm_delete_question_question_bank',
845
+ 'question_ids': question_ids,
846
+ 'nonce': qsmQuestionSettings.question_bank_nonce
847
+ },
848
+ success: function (response) {
849
+ var data = jQuery.parseJSON(response);
850
+ if (data.success === true) {
851
+ $('#question-bank').find('[name="qsm-question-checkbox[]"]:checked').parents('.question-bank-question').slideUp('slow');
852
+ alert(data.message);
853
+ } else {
854
+ alert(data.message);
855
+ }
856
+ }
857
+ });
858
+ }
859
+ }
860
+ }
861
+ });
862
+
863
+ //Select all button.
864
+ $(document).on('change', '#qsm_select_all_question', function (event) {
865
+ $('.qsm-question-checkbox').prop('checked', jQuery('#qsm_select_all_question').prop('checked'));
866
  });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
867
 
868
+ $('.save-page-button').on('click', function (event) {
869
  event.preventDefault();
870
+ $('#save-edit-quiz-pages').addClass('is-active');
871
  QSMQuestion.savePages();
872
  });
873
  $('#save-page-popup-button').on('click', function (event) {
886
  MicroModal.close('modal-page-1');
887
  }
888
  });
889
+
890
+ $(document).on('change', '#change-answer-editor', function (event) {
891
+ var newVal = $(this).val();
892
+ if (confirm('All answer will be reset, Do you want to still continue?')) {
893
+ $('#answers').find('.answers-single').remove();
894
+ } else {
895
+ if (newVal == 'rich') {
896
+ $(this).val('text');
897
+ } else {
898
+ $(this).val('rich');
899
+ }
900
+ return false;
901
+ }
902
  });
903
+
904
  // Adds event handlers for searching questions
905
+ $('#question_search').on('keyup', function () {
906
+ $('.question').each(function () {
907
+ if ($(this).text().toLowerCase().indexOf($('#question_search').val().toLowerCase()) === -1) {
908
  $(this).hide();
909
  } else {
910
  $(this).show();
911
  }
912
  });
913
+ $('.page').each(function () {
914
+ if (0 === $(this).children('.question:visible').length) {
915
  $(this).hide();
916
  } else {
917
  $(this).show();
918
  }
919
  });
920
+ if (0 === $('#question_search').val().length) {
921
+ $('.page').show();
922
+ $('.question').show();
923
  }
924
  });
925
 
926
+ qsm_init_sortable();
927
+
928
+ if (qsmQuestionSettings.qsm_user_ve === 'true') {
929
+ QSMQuestion.prepareEditor();
930
+ }
931
  QSMQuestion.loadQuestions();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
932
 
933
+ /**
934
+ * Hide/show advanced option
935
+ */
936
+ $(document).on('click', '#show-advanced-option', function () {
937
+ var $this = $(this);
938
+ $(this).next('div.advanced-content').slideToggle('slow', function () {
939
+ if ($(this).is(':visible')) {
940
+ $this.text('').html('Hide advance options &laquo;');
941
+ } else {
942
+ $this.text('').html('Show advance options &raquo;');
943
+ }
944
+ });
945
+ });
946
+
947
+ //Hide the question settings based on question type
948
+ $(document).on('change', '#question_type', function () {
949
+ var question_val = $(this).val();
950
+ $('.qsm_hide_for_other').hide();
951
+ if ($('.qsm_show_question_type_' + question_val).length > 0) {
952
+ $('.qsm_show_question_type_' + question_val).show();
953
+ }
954
+ qsm_hide_show_question_desc(question_val);
955
+ });
956
+
957
+ //Add new category
958
+ $(document).on('click', '#qsm-category-add-toggle', function () {
959
+ if ($('#qsm-category-add').is(":visible")) {
960
+ $('.questionElements #new_category_new').attr('checked', false);
961
+ $('#qsm-category-add').slideUp('slow');
962
+ } else {
963
+ $('.questionElements #new_category_new').attr('checked', true).prop('checked', 'checked');
964
+ $('#qsm-category-add').slideDown('slow');
965
+ }
966
+ });
967
+
968
+ //Hide/show quesion description
969
+ $(document).on('click', '.qsm-show-question-desc-box', function (e) {
970
+ e.preventDefault();
971
+ if ($(this).next('.qsm-row').is(':visible')) {
972
+ $(this).html('').html('<span class="dashicons dashicons-plus-alt2"></span> ' + qsmQuestionSettings.show_desc_text);
973
+ $(this).next('.qsm-row').slideUp();
974
+ } else {
975
+ $(this).hide();
976
+ var question_description = wp.editor.getContent('question-text');
977
+ if (question_description == '' || question_description == null) {
978
+ tinyMCE.get('question-text').setContent('Add description here!');
979
+ }
980
+ $(this).next('.qsm-row').slideDown();
981
+ }
982
+ });
983
+
984
+ //Hide/show correct answer info
985
+ $(document).on('click', '.qsm-show-correct-info-box', function (e) {
986
+ e.preventDefault();
987
+ if ($(this).next('.qsm-row').is(':visible')) {
988
+ $(this).html('').html('<span class="dashicons dashicons-plus-alt2"></span> ' + qsmQuestionSettings.show_correct_info_text);
989
+ $(this).next('.qsm-row').slideUp();
990
+ } else {
991
+ $(this).hide();
992
+ $(this).next('.qsm-row').slideDown();
993
+ }
994
+ });
995
  });
996
+ var decodeEntities = (function () {
997
+ //create a new html document (doesn't execute script tags in child elements)
998
+ var doc = document.implementation.createHTMLDocument("");
999
+ var element = doc.createElement('div');
1000
 
1001
+ function getText(str) {
1002
+ element.innerHTML = str;
1003
+ str = element.textContent;
1004
+ element.textContent = '';
1005
+ return str;
1006
+ }
1007
 
1008
+ function decodeHTMLEntities(str) {
1009
+ if (str && typeof str === 'string') {
1010
+ var x = getText(str);
1011
+ while (str !== x) {
1012
+ str = x;
1013
+ x = getText(x);
1014
+ }
1015
+ return x;
1016
+ }
1017
+ }
1018
+ return decodeHTMLEntities;
1019
+ })();
1020
+
1021
+ function qsm_hide_show_question_desc(question_type) {
1022
+ $('.question-type-description').hide();
1023
+ if ($('#question_type_' + question_type + '_description').length > 0) {
1024
+ $('#question_type_' + question_type + '_description').show();
1025
+ }
1026
+ }
1027
+
1028
+ function qsm_init_sortable() {
1029
+ $('.questions').sortable({
1030
  opacity: 70,
1031
  cursor: 'move',
1032
  placeholder: "ui-state-highlight",
1033
+ stop: function (evt, ui) {
1034
+ $('.questions > .page').each(function () {
1035
+ var page = parseInt($(this).index()) + 1;
1036
+ $(this).find('.page-number').text('Page ' + page);
1037
+ });
1038
+ setTimeout(
1039
+ function () {
1040
+ $('.save-page-button').trigger('click');
1041
+ },
1042
+ 200
1043
+ )
1044
+ }
1045
  });
1046
+ $('.page').sortable({
1047
  items: '.question',
1048
  opacity: 70,
1049
  cursor: 'move',
1050
  placeholder: "ui-state-highlight",
1051
  connectWith: '.page',
1052
+ stop: function (evt, ui) {
1053
+ setTimeout(
1054
+ function () {
1055
+ $('.save-page-button').trigger('click');
1056
+ },
1057
+ 200
1058
+ )
1059
+ }
1060
  });
1061
+ }
1062
  function qsmRandomID(length) {
1063
  var result = '';
1064
  var characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
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.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
 
@@ -38,7 +38,7 @@ class MLWQuizMasterNext {
38
  * @var string
39
  * @since 4.0.0
40
  */
41
- public $version = '7.1.17';
42
 
43
  /**
44
  * QSM Alert Manager Object
2
  /**
3
  * Plugin Name: Quiz And Survey Master
4
  * Description: Easily and quickly add quizzes and surveys to your website.
5
+ * Version: 7.1.18
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.18
13
  * @package QSM
14
  */
15
 
38
  * @var string
39
  * @since 4.0.0
40
  */
41
+ public $version = '7.1.18';
42
 
43
  /**
44
  * QSM Alert Manager Object
php/classes/class-qmn-quiz-manager.php CHANGED
@@ -4,8 +4,8 @@
4
  *
5
  * @package QSM
6
  */
7
- if (!defined('ABSPATH')) {
8
- exit;
9
  }
10
 
11
  /**
@@ -15,2244 +15,2306 @@ if (!defined('ABSPATH')) {
15
  */
16
  class QMNQuizManager {
17
 
18
- protected $qsm_background_email;
19
- /**
20
- * Main Construct Function
21
- *
22
- * Call functions within class
23
- *
24
- * @since 4.0.0
25
- * @uses QMNQuizManager::add_hooks() Adds actions to hooks and filters
26
- * @return void
27
- */
28
- public function __construct() {
29
- $this->add_hooks();
30
- }
31
-
32
- /**
33
- * Add Hooks
34
- *
35
- * Adds functions to relavent hooks and filters
36
- *
37
- * @since 4.0.0
38
- * @return void
39
- */
40
- public function add_hooks() {
41
- add_shortcode('mlw_quizmaster', array($this, 'display_shortcode'));
42
- add_shortcode('qsm', array($this, 'display_shortcode'));
43
- add_shortcode('qsm_result', array($this, 'shortcode_display_result'));
44
- add_action('wp_ajax_qmn_process_quiz', array($this, 'ajax_submit_results'));
45
- add_action('wp_ajax_nopriv_qmn_process_quiz', array($this, 'ajax_submit_results'));
46
- add_action('wp_ajax_qsm_get_quiz_to_reload', array($this, 'qsm_get_quiz_to_reload'));
47
- add_action('wp_ajax_nopriv_qsm_get_quiz_to_reload', array($this, 'qsm_get_quiz_to_reload'));
48
- add_action('wp_ajax_qsm_get_question_quick_result', array($this, 'qsm_get_question_quick_result'));
49
- add_action('wp_ajax_nopriv_qsm_get_question_quick_result', array($this, 'qsm_get_question_quick_result'));
50
- //Upload file of file upload question type
51
- add_action('wp_ajax_qsm_upload_image_fd_question', array($this, 'qsm_upload_image_fd_question'));
52
- add_action('wp_ajax_nopriv_qsm_upload_image_fd_question', array($this, 'qsm_upload_image_fd_question'));
53
-
54
- //remove file of file upload question type
55
- add_action('wp_ajax_qsm_remove_file_fd_question', array($this, 'qsm_remove_file_fd_question'));
56
- add_action('wp_ajax_nopriv_qsm_remove_file_fd_question', array($this, 'qsm_remove_file_fd_question'));
57
-
58
- add_action('init', array($this, 'qsm_process_background_email'));
59
- }
60
-
61
- /**
62
- * @version 6.3.7
63
- * Upload file to server
64
- */
65
- public function qsm_upload_image_fd_question(){
66
- global $mlwQuizMasterNext;
67
- $question_id = isset($_POST['question_id']) ? sanitize_text_field($_POST['question_id']) : 0;
68
- $file_upload_type = $mlwQuizMasterNext->pluginHelper->get_question_setting($question_id, 'file_upload_type');
69
- $file_upload_limit = $mlwQuizMasterNext->pluginHelper->get_question_setting($question_id, 'file_upload_limit');
70
- $mimes = array();
71
- if($file_upload_type){
72
- $file_type_exp = explode(',', $file_upload_type);
73
- foreach ($file_type_exp as $value) {
74
- if($value == 'image'){
75
- $mimes[] = 'image/jpeg';
76
- $mimes[] = 'image/png';
77
- $mimes[] = 'image/x-icon';
78
- $mimes[] = 'image/gif';
79
- }else if($value == 'doc'){
80
- $mimes[] = 'application/msword';
81
- $mimes[] = 'application/vnd.openxmlformats-officedocument.wordprocessingml.document';
82
- }else if($value == 'excel'){
83
- $mimes[] = 'application/excel, application/vnd.ms-excel, application/x-excel, application/x-msexcel';
84
- $mimes[] = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';
85
- }else{
86
- $mimes[] = $value;
87
- }
88
- }
89
- }
90
- $json = array();
91
- $file_name = sanitize_file_name( $_FILES["file"]["name"] );
92
- $validate_file = wp_check_filetype( $file_name );
93
- if ( isset( $validate_file['type'] ) && in_array($validate_file['type'], $mimes)) {
94
- if($_FILES["file"]['size'] >= $file_upload_limit * 1024 * 1024){
95
- $json['type']= 'error';
96
- $json['message'] = __('File is too large. File must be less than ', 'quiz-master-next') . $file_upload_limit . ' MB';
97
- echo json_encode($json);
98
- exit;
99
- }
100
- $upload_dir = wp_upload_dir();
101
- $datafile = $_FILES["file"]["tmp_name"];
102
- //$file_name = $_FILES["file"]["name"];
103
- $extension = pathinfo($file_name, PATHINFO_EXTENSION);
104
- //remove white space between file name
105
- $file_name = str_replace(' ', '-', $file_name);
106
- $rawBaseName = 'qsmfileupload_' . md5( date('Y-m-d H:i:s') ) . '_' . pathinfo($file_name, PATHINFO_FILENAME);
107
- $new_fname = $rawBaseName . '.' . $extension;
108
- $file = $upload_dir['path'] . '/' . $new_fname;
109
- $file_url = $upload_dir['url'] . '/' . $new_fname;
110
- $counter = 1;
111
- if(file_exists($file)){
112
- while (file_exists($file)) {
113
- $new_fname = $rawBaseName . '-' . $counter . '.' . $extension;
114
- $file = $upload_dir['path'] . '/' . $new_fname;
115
- $file_url = $upload_dir['url'] . '/' . $new_fname;
116
- $counter++;
117
- }
118
- }
119
- if (!move_uploaded_file($datafile, $file)) {
120
- $json['type']= 'error';
121
- $json['message'] = __('File not uploaded', 'quiz-master-next');
122
- echo json_encode($json);
123
- }else{
124
- // Prepare an array of post data for the attachment.
125
- $attachment = array(
126
- 'guid' => $upload_dir['url'] . '/' . basename( $file ),
127
- 'post_mime_type' => $validate_file['type'],
128
- 'post_title' => preg_replace( '/\.[^.]+$/', '', basename( $file_name ) ),
129
- 'post_content' => '',
130
- 'post_status' => 'inherit'
131
- );
132
- // Insert the attachment.
133
- $attach_id = wp_insert_attachment( $attachment, $file, 0 );
134
- if( $attach_id ){
135
- require_once( ABSPATH . 'wp-admin/includes/image.php' );
136
- $attach_data = wp_generate_attachment_metadata( $attach_id, $file );
137
- wp_update_attachment_metadata( $attach_id, $attach_data );
138
- }
139
- $json['type']= 'success';
140
- $json['message'] = __( 'File uploaded successfully', 'quiz-master-next' );
141
- $json['file_url'] = $file_url;
142
- $json['file_path'] = $new_fname;
143
- echo json_encode($json);
144
- }
145
- }else{
146
- $json['type']= 'error';
147
- $json['message'] = __('File type is not supported', 'quiz-master-next');
148
- echo json_encode($json);
149
- }
150
- exit;
151
- }
152
-
153
- /**
154
- * @since 6.3.7
155
- * Remove the uploaded image
156
- */
157
- public function qsm_remove_file_fd_question(){
158
- $file_url = isset($_POST['file_url']) ? sanitize_text_field($_POST['file_url']) : '';
159
- $upload_dir = wp_upload_dir();
160
- $uploaded_path = $upload_dir['path'];
161
- if($file_url && stristr( $file_url, 'qsmfileupload_' ) && file_exists( $uploaded_path . '/' . $file_url ) ){
162
- $attachment_url = $upload_dir['url'] . '/' . $file_url;
163
- $attachment_id = $this->qsm_get_attachment_id_from_url($attachment_url);
164
- wp_delete_file( $uploaded_path . '/' . $file_url );
165
- wp_delete_attachment( $attachment_id );
166
- $json['type']= 'success';
167
- $json['message'] = __( 'File removed successfully', 'quiz-master-next' );
168
- echo json_encode($json);
169
- exit;
170
- }
171
- $json['type']= 'error';
172
- $json['message'] = __( 'File not removed', 'quiz-master-next' );
173
- echo json_encode($json);
174
- exit;
175
- }
176
-
177
-
178
- /**
179
- * @version 6.3.2
180
- * Get question quick result
181
- */
182
- public function qsm_get_question_quick_result(){
183
- global $wpdb;
184
- $question_id = isset($_POST['question_id']) ? intval($_POST['question_id']) : 0;
185
- $answer = isset( $_POST['answer'] ) ? stripslashes_deep( $_POST['answer'] ) : '';
186
- $question_array = $wpdb->get_row( $wpdb->prepare( "SELECT answer_array, question_answer_info FROM {$wpdb->prefix}mlw_questions WHERE question_id = (%d)", $question_id ), 'ARRAY_A' );
187
- $answer_array = unserialize($question_array['answer_array']);
188
- $correct_info_text = isset( $question_array['question_answer_info'] ) ? html_entity_decode( $question_array['question_answer_info'] ) : '';
189
- $show_correct_info = isset( $_POST['show_correct_info'] ) ? sanitize_text_field( $_POST['show_correct_info'] ) : 0;
190
- $got_ans = false;
191
- $correct_answer = false;
192
- if($answer_array && $got_ans === false){
193
- foreach ($answer_array as $key => $value) {
194
- if( esc_html( $value[0]) == esc_html($answer) && $value[2] == 1 ){
195
- $got_ans = true;
196
- $correct_answer = true;
197
- break;
198
- }
199
- }
200
- }
201
- if( $show_correct_info == 2 ){
202
- $got_ans = true;
203
- }
204
- echo wp_json_encode(
205
- array(
206
- 'success' => $correct_answer ? 'correct' : 'incorrect',
207
- 'message' => $show_correct_info && $got_ans ? '<b>'. __('Correct Info: ', 'quiz-master-next') .'</b>' . do_shortcode($correct_info_text) : ''
208
- )
209
- );
210
- wp_die();
211
- }
212
-
213
- /**
214
- * Generates Content For Quiz Shortcode
215
- *
216
- * Generates the content for the [mlw_quizmaster] shortcode
217
- *
218
- * @since 4.0.0
219
- * @param array $atts The attributes passed from the shortcode.
220
- * @uses QMNQuizManager:load_questions() Loads questions
221
- * @uses QMNQuizManager:create_answer_array() Prepares answers
222
- * @uses QMNQuizManager:display_quiz() Generates and prepares quiz page
223
- * @uses QMNQuizManager:display_results() Generates and prepares results page
224
- * @return string The content for the shortcode
225
- */
226
- public function display_shortcode($atts) {
227
- extract(shortcode_atts(array(
228
- 'quiz' => 0,
229
- 'question_amount' => 0,
230
- ), $atts));
231
-
232
- ob_start();
233
- if(isset($_GET['result_id']) && $_GET['result_id'] != ''){
234
- global $wpdb;
235
- global $mlwQuizMasterNext;
236
- wp_enqueue_style('qmn_quiz_common_style', plugins_url('../../css/common.css', __FILE__));
237
- wp_enqueue_style('dashicons');
238
- wp_enqueue_script( 'jquery' );
239
- wp_enqueue_script( 'jquery-ui-tooltip' );
240
- wp_enqueue_script('qsm_quiz', plugins_url('../../js/qsm-quiz.js', __FILE__), array('wp-util', 'underscore', 'jquery', 'jquery-ui-tooltip'), $mlwQuizMasterNext->version);
241
- wp_enqueue_script( 'math_jax', '//cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.2/MathJax.js?config=TeX-MML-AM_CHTML' );
242
- $result_unique_id =sanitize_text_field($_GET['result_id']);
243
- $query = $wpdb->prepare("SELECT result_id FROM {$wpdb->prefix}mlw_results WHERE unique_id = %s",$result_unique_id);
244
- $result = $wpdb->get_row($query,ARRAY_A);
245
- if( !empty($result) && isset($result['result_id']) ){
246
- $result_id = $result['result_id'];
247
- $return_display = do_shortcode( '[qsm_result id="'. $result_id .'"]' );
248
- $return_display = str_replace('%FB_RESULT_ID%', $result_unique_id, $return_display);
249
- }else{
250
- $return_display = 'Result id is wrong!';
251
- }
252
- $return_display .= ob_get_clean();
253
- }else{
254
- global $wpdb;
255
- global $mlwQuizMasterNext;
256
- global $qmn_allowed_visit;
257
- global $qmn_json_data;
258
- $qmn_json_data = array();
259
- $qmn_allowed_visit = true;
260
- $success = $mlwQuizMasterNext->pluginHelper->prepare_quiz($quiz);
261
- if (false === $success) {
262
- return __('It appears that this quiz is not set up correctly', 'quiz-master-next');
263
- }
264
- $question_amount = intval($question_amount);
265
-
266
- // Legacy variable.
267
- global $mlw_qmn_quiz;
268
- $mlw_qmn_quiz = $quiz;
269
-
270
- $return_display = '';
271
- $qmn_quiz_options = $mlwQuizMasterNext->quiz_settings->get_quiz_options();
272
-
273
- // If quiz options isn't found, stop function.
274
- if (is_null($qmn_quiz_options) || empty($qmn_quiz_options->quiz_name)) {
275
- return __('It appears that this quiz is not set up correctly', 'quiz-master-next');
276
- }
277
-
278
- // Loads Quiz Template.
279
- // The quiz_stye is misspelled because it has always been misspelled and fixing it would break many sites :(.
280
- if ('default' == $qmn_quiz_options->theme_selected) {
281
- $return_display .= '<style type="text/css">' . htmlspecialchars_decode($qmn_quiz_options->quiz_stye) . '</style>';
282
- wp_enqueue_style('qmn_quiz_style', plugins_url('../../css/qmn_quiz.css', __FILE__));
283
- } else {
284
- $registered_template = $mlwQuizMasterNext->pluginHelper->get_quiz_templates($qmn_quiz_options->theme_selected);
285
- // Check direct file first, then check templates folder in plugin, then check templates file in theme.
286
- // If all fails, then load custom styling instead.
287
- if ($registered_template && file_exists($registered_template['path'])) {
288
- wp_enqueue_style('qmn_quiz_template', $registered_template['path'], array(), $mlwQuizMasterNext->version);
289
- } elseif ($registered_template && file_exists(plugin_dir_path(__FILE__) . '../../templates/' . $registered_template['path'])) {
290
- wp_enqueue_style('qmn_quiz_template', plugins_url('../../templates/' . $registered_template['path'], __FILE__), array(), $mlwQuizMasterNext->version);
291
- } elseif ($registered_template && file_exists(get_stylesheet_directory_uri() . '/templates/' . $registered_template['path'])) {
292
- wp_enqueue_style('qmn_quiz_template', get_stylesheet_directory_uri() . '/templates/' . $registered_template['path'], array(), $mlwQuizMasterNext->version);
293
- } else {
294
- echo "<style type='text/css'>{$qmn_quiz_options->quiz_stye}</style>";
295
- }
296
- }
297
- wp_enqueue_style('qmn_quiz_animation_style', plugins_url('../../css/animate.css', __FILE__));
298
- wp_enqueue_style('qmn_quiz_common_style', plugins_url('../../css/common.css', __FILE__));
299
- wp_enqueue_style('dashicons');
300
-
301
- // Starts to prepare variable array for filters.
302
- $qmn_array_for_variables = array(
303
- 'quiz_id' => $qmn_quiz_options->quiz_id,
304
- 'quiz_name' => $qmn_quiz_options->quiz_name,
305
- 'quiz_system' => $qmn_quiz_options->system,
306
- 'user_ip' => $this->get_user_ip(),
307
- );
308
-
309
- $return_display .= "<script>
 
 
 
 
 
 
 
 
310
  if (window.qmn_quiz_data === undefined) {
311
  window.qmn_quiz_data = new Object();
312
  }
313
- </script>";
314
- $qpages = array();
315
- $qpages_arr = $mlwQuizMasterNext->pluginHelper->get_quiz_setting('qpages', array());
316
- if (!empty($qpages_arr)) {
317
- foreach ($qpages_arr as $key => $qpage) {
318
- unset($qpage['questions']);
319
- $qpages[$qpage['id']] = $qpage;
320
  }
321
  }
322
- $qmn_json_data = array(
323
- 'quiz_id' => $qmn_array_for_variables['quiz_id'],
324
- 'quiz_name' => $qmn_array_for_variables['quiz_name'],
325
- 'disable_answer' => $qmn_quiz_options->disable_answer_onselect,
326
- 'ajax_show_correct' => $qmn_quiz_options->ajax_show_correct,
327
- 'progress_bar' => $qmn_quiz_options->progress_bar,
328
- 'contact_info_location' => $qmn_quiz_options->contact_info_location,
329
- 'qpages' => $qpages,
330
- 'skip_validation_time_expire' => $qmn_quiz_options->skip_validation_time_expire,
331
- 'timer_limit_val' => $qmn_quiz_options->timer_limit,
332
  'disable_scroll_next_previous_click' => $qmn_quiz_options->disable_scroll_next_previous_click,
333
- 'enable_result_after_timer_end' => isset($qmn_quiz_options->enable_result_after_timer_end) ? $qmn_quiz_options->enable_result_after_timer_end : '',
334
- 'enable_quick_result_mc' => isset($qmn_quiz_options->enable_quick_result_mc) ? $qmn_quiz_options->enable_quick_result_mc : '',
335
- 'end_quiz_if_wrong' => isset($qmn_quiz_options->end_quiz_if_wrong) ? $qmn_quiz_options->end_quiz_if_wrong : '',
336
- 'form_disable_autofill' => isset($qmn_quiz_options->form_disable_autofill) ? $qmn_quiz_options->form_disable_autofill : '',
337
- 'enable_quick_correct_answer_info' => isset($qmn_quiz_options->enable_quick_correct_answer_info) ? $qmn_quiz_options->enable_quick_correct_answer_info : 0,
338
- 'quick_result_correct_answer_text' => $qmn_quiz_options->quick_result_correct_answer_text,
339
- 'quick_result_wrong_answer_text' => $qmn_quiz_options->quick_result_wrong_answer_text,
340
  );
341
 
342
- $return_display = apply_filters('qmn_begin_shortcode', $return_display, $qmn_quiz_options, $qmn_array_for_variables);
343
 
344
- // Checks if we should be showing quiz or results page.
345
- if ($qmn_allowed_visit && !isset($_POST["complete_quiz"]) && !empty($qmn_quiz_options->quiz_name)) {
346
- $return_display .= $this->display_quiz($qmn_quiz_options, $qmn_array_for_variables, $question_amount);
347
- } elseif (isset($_POST["complete_quiz"]) && 'confirmation' == $_POST["complete_quiz"] && $_POST["qmn_quiz_id"] == $qmn_array_for_variables["quiz_id"]) {
348
- $return_display .= $this->display_results($qmn_quiz_options, $qmn_array_for_variables);
349
- }
350
 
351
- $qmn_filtered_json = apply_filters('qmn_json_data', $qmn_json_data, $qmn_quiz_options, $qmn_array_for_variables);
352
 
353
- $return_display .= '<script>
354
- window.qmn_quiz_data["' . $qmn_json_data["quiz_id"] . '"] = ' . json_encode($qmn_filtered_json) . '
355
  </script>';
356
 
357
- $return_display .= ob_get_clean();
358
- $return_display = apply_filters('qmn_end_shortcode', $return_display, $qmn_quiz_options, $qmn_array_for_variables);
359
- }
360
- return $return_display;
361
- }
362
-
363
- public function shortcode_display_result($atts){
364
- extract(shortcode_atts(array(
365
- 'id' => 0,
366
- ), $atts));
367
- ob_start();
368
- if($id == 0){
369
- $id = (int) isset($_GET['result_id']) ? sanitize_text_field( $_GET['result_id'] ) : 0;
370
- }
371
- if( $id && is_numeric($id) ){
372
- global $wpdb;
373
- $result_data = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->prefix}mlw_results WHERE result_id = %d", $id), ARRAY_A);
374
- if( $result_data ){
375
- wp_enqueue_style('qmn_quiz_common_style', plugins_url('../../css/common.css', __FILE__));
376
- wp_enqueue_style('dashicons');
377
- wp_enqueue_script( 'math_jax', '//cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.2/MathJax.js?config=TeX-MML-AM_CHTML' );
378
- $quiz_result = unserialize($result_data['quiz_results']);
379
- $response_data = array(
380
- 'quiz_id' => $result_data['quiz_id'],
381
- 'quiz_name' => $result_data['quiz_name'],
382
- 'quiz_system' => $result_data['quiz_system'],
383
- 'quiz_payment_id' => '',
384
- 'user_ip' => $result_data['user_ip'],
385
- 'user_name' => $result_data['name'],
386
- 'user_business' => $result_data['business'],
387
- 'user_email' => $result_data['email'],
388
- 'user_phone' => $result_data['phone'],
389
- 'user_id' => $result_data['user'],
390
- 'timer' => 0,
391
- 'time_taken' => $result_data['time_taken'],
392
- 'contact' => $quiz_result['contact'],
393
- 'total_points' => $result_data['point_score'],
394
- 'total_score' => $result_data['correct_score'],
395
- 'total_correct' => $result_data['correct'],
396
- 'total_questions' => $result_data['total'],
397
- 'question_answers_array' => $quiz_result[1],
398
- 'comments' => ''
399
- );
400
- $data = QSM_Results_Pages::generate_pages($response_data);
401
- echo htmlspecialchars_decode($data['display']);
402
- } else {
403
- echo _e('Invalid result id!', 'quiz-master-next');
404
- }
405
- }else{
406
- echo _e('Invalid result id!', 'quiz-master-next');
407
- }
408
- $content = ob_get_clean();
409
- return $content;
410
- }
411
-
412
- /**
413
- * Loads Questions
414
- *
415
- * Retrieves the questions from the database
416
- *
417
- * @since 4.0.0
418
- * @param int $quiz_id The id for the quiz.
419
- * @param array $quiz_options The database row for the quiz.
420
- * @param bool $is_quiz_page If the page being loaded is the quiz page or not.
421
- * @param int $question_amount The amount of questions entered using the shortcode attribute.
422
- * @return array The questions for the quiz
423
- * @deprecated 5.2.0 Use new class: QSM_Questions instead
424
- */
425
- public function load_questions($quiz_id, $quiz_options, $is_quiz_page, $question_amount = 0) {
426
-
427
- // Prepare variables.
428
- global $wpdb;
429
- global $mlwQuizMasterNext;
430
- $questions = array();
431
- $order_by_sql = 'ORDER BY question_order ASC';
432
- $limit_sql = '';
433
-
434
- // Checks if the questions should be randomized.
 
 
 
 
 
435
  $cat_query = '';
436
- if (1 == $quiz_options->randomness_order || 2 == $quiz_options->randomness_order) {
437
- $order_by_sql = 'ORDER BY rand()';
438
- $categories = isset($quiz_options->randon_category) ? $quiz_options->randon_category : '';
439
- if($categories){
440
- $exploded_arr = explode(',', $quiz_options->randon_category);
441
- $cat_str = "'" . implode ( "', '", $exploded_arr ) . "'";
442
- $cat_query = " AND category IN ( $cat_str ) ";
443
  }
444
- }
445
-
446
- // Check if we should load all questions or only a selcted amount.
447
- if ($is_quiz_page && ( 0 != $quiz_options->question_from_total || 0 !== $question_amount )) {
448
- if (0 !== $question_amount) {
449
- $limit_sql = " LIMIT $question_amount";
450
- } else {
451
- $limit_sql = ' LIMIT ' . intval($quiz_options->question_from_total);
452
- }
453
- }
454
-
455
- // If using newer pages system from 5.2.
456
- $pages = $mlwQuizMasterNext->pluginHelper->get_quiz_setting('pages', array());
457
- // Get all question IDs needed.
458
- $total_pages = count($pages);
459
- if ($total_pages > 0) {
460
- for ($i = 0; $i < $total_pages; $i++) {
461
- foreach ($pages[$i] as $question) {
462
- $question_ids[] = intval($question);
463
- }
464
- }
465
- $question_ids = apply_filters('qsm_load_questions_ids', $question_ids, $quiz_id, $quiz_options);
466
- $question_sql = implode(', ', $question_ids);
467
- $query = $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}mlw_questions WHERE question_id IN (%1s) %2s %3s %4s", $question_sql, $cat_query, $order_by_sql, $limit_sql );
468
- $questions = $wpdb->get_results( stripslashes($query));
469
-
470
- // If we are not using randomization, we need to put the questions in the order of the new question editor.
471
- // If a user has saved the pages in the question editor but still uses the older pagination options
472
- // Then they will make it here. So, we need to order the questions based on the new editor.
473
- if (1 != $quiz_options->randomness_order && 2 != $quiz_options->randomness_order) {
474
- $ordered_questions = array();
475
- foreach ($questions as $question) {
476
- $key = array_search($question->question_id, $question_ids);
477
- if (false !== $key) {
478
- $ordered_questions[$key] = $question;
479
- }
480
- }
481
- ksort($ordered_questions);
482
- $questions = $ordered_questions;
483
- }
484
- } else {
485
- $question_ids = apply_filters('qsm_load_questions_ids', array(), $quiz_id, $quiz_options);
486
- $question_sql = '';
487
- if (!empty($question_ids)) {
488
- $qids = implode(', ', $question_ids);
489
- $question_sql = " AND question_id IN ($qids) ";
490
  }
491
- $questions = $wpdb->get_results($wpdb->prepare("SELECT * FROM {$wpdb->prefix}mlw_questions WHERE quiz_id=%d AND deleted=0 %1s %2s %3s", $quiz_id, $question_sql, $order_by_sql, $limit_sql));
492
- }
493
- $questions = apply_filters('qsm_load_questions_filter', $questions, $quiz_id, $quiz_options);
494
- // Returns an array of all the loaded questions.
495
- return $questions;
496
- }
497
-
498
- /**
499
- * Prepares Answers
500
- *
501
- * Prepares or creates the answer array for the quiz
502
- *
503
- * @since 4.0.0
504
- * @param array $questions The questions for the quiz.
505
- * @param bool $is_ajax Pass true if this is an ajax call.
506
- * @return array The answers for the quiz
507
- * @deprecated 5.2.0 Use new class: QSM_Questions instead
508
- */
509
- public function create_answer_array($questions, $is_ajax = false) {
510
-
511
- // Load and prepare answer arrays.
512
- $mlw_qmn_answer_arrays = array();
513
- $question_list = array();
514
- foreach ($questions as $mlw_question_info) {
515
- $question_list[$mlw_question_info->question_id] = get_object_vars($mlw_question_info);
516
- if (is_serialized($mlw_question_info->answer_array) && is_array(@unserialize($mlw_question_info->answer_array))) {
517
- $mlw_qmn_answer_array_each = @unserialize($mlw_question_info->answer_array);
518
- $mlw_qmn_answer_arrays[$mlw_question_info->question_id] = $mlw_qmn_answer_array_each;
519
- $question_list[$mlw_question_info->question_id]["answers"] = $mlw_qmn_answer_array_each;
520
- } else {
521
- $mlw_answer_array_correct = array(0, 0, 0, 0, 0, 0);
522
- $mlw_answer_array_correct[$mlw_question_info->correct_answer - 1] = 1;
523
- $mlw_qmn_answer_arrays[$mlw_question_info->question_id] = array(
524
- array($mlw_question_info->answer_one, $mlw_question_info->answer_one_points, $mlw_answer_array_correct[0]),
525
- array($mlw_question_info->answer_two, $mlw_question_info->answer_two_points, $mlw_answer_array_correct[1]),
526
- array($mlw_question_info->answer_three, $mlw_question_info->answer_three_points, $mlw_answer_array_correct[2]),
527
- array($mlw_question_info->answer_four, $mlw_question_info->answer_four_points, $mlw_answer_array_correct[3]),
528
- array($mlw_question_info->answer_five, $mlw_question_info->answer_five_points, $mlw_answer_array_correct[4]),
529
- array($mlw_question_info->answer_six, $mlw_question_info->answer_six_points, $mlw_answer_array_correct[5]));
530
- $question_list[$mlw_question_info->question_id]["answers"] = $mlw_qmn_answer_arrays[$mlw_question_info->question_id];
531
- }
532
- }
533
- if (!$is_ajax) {
534
- global $qmn_json_data;
535
- $qmn_json_data["question_list"] = $question_list;
536
- }
537
- return $mlw_qmn_answer_arrays;
538
- }
539
-
540
- /**
541
- * Generates Content Quiz Page
542
- *
543
- * Generates the content for the quiz page part of the shortcode
544
- *
545
- * @since 4.0.0
546
- * @param array $options The database row of the quiz.
547
- * @param array $quiz_data The array of results for the quiz.
548
- * @param int $question_amount The number of questions to load for quiz.
549
- * @uses QMNQuizManager:display_begin_section() Creates display for beginning section
550
- * @uses QMNQuizManager:display_questions() Creates display for questions
551
- * @uses QMNQuizManager:display_comment_section() Creates display for comment section
552
- * @uses QMNQuizManager:display_end_section() Creates display for end section
553
- * @return string The content for the quiz page section
554
- */
555
- public function display_quiz($options, $quiz_data, $question_amount) {
556
-
557
- global $qmn_allowed_visit;
558
- global $mlwQuizMasterNext;
559
- $quiz_display = '';
560
- $quiz_display = apply_filters('qmn_begin_quiz', $quiz_display, $options, $quiz_data);
561
- if (!$qmn_allowed_visit) {
562
- return $quiz_display;
563
- }
564
- wp_enqueue_script('json2');
565
- wp_enqueue_script('jquery');
566
- wp_enqueue_script('jquery-ui-core');
567
- wp_enqueue_script('jquery-ui-tooltip');
568
- wp_enqueue_style('jquery-redmond-theme', plugins_url('../../css/jquery-ui.css', __FILE__));
569
-
570
- global $qmn_json_data;
571
- $qmn_json_data['error_messages'] = array(
572
- 'email' => $options->email_error_text,
573
- 'number' => $options->number_error_text,
574
- 'incorrect' => $options->incorrect_error_text,
575
- 'empty' => $options->empty_error_text,
576
- );
577
-
578
- wp_enqueue_script('progress-bar', plugins_url('../../js/progressbar.min.js', __FILE__));
579
- wp_enqueue_script( 'jquery-ui-slider-js', plugins_url('../../js/jquery-ui.js', __FILE__));
580
- wp_enqueue_script( 'jquery-ui-slider-rtl-js', plugins_url('../../js/jquery.ui.slider-rtl.js', __FILE__) );
581
- wp_enqueue_style( 'jquery-ui-slider-rtl-css', plugins_url('../../css/jquery.ui.slider-rtl.css', __FILE__) );
582
- wp_enqueue_script( 'jqueryui-touch-js', '//cdnjs.cloudflare.com/ajax/libs/jqueryui-touch-punch/0.2.3/jquery.ui.touch-punch.min.js' );
583
- wp_enqueue_style('qsm_model_css', plugins_url('../../css/qsm-admin.css', __FILE__));
584
- wp_enqueue_script('qsm_model_js', plugins_url('../../js/micromodal.min.js', __FILE__));
585
- wp_enqueue_script('qsm_quiz', plugins_url('../../js/qsm-quiz.js', __FILE__), array('wp-util', 'underscore', 'jquery', 'jquery-ui-tooltip', 'progress-bar'), $mlwQuizMasterNext->version);
586
- wp_localize_script('qsm_quiz', 'qmn_ajax_object', array('ajaxurl' => admin_url('admin-ajax.php'), 'multicheckbox_limit_reach' => __('Limit of choice is reached.', 'quiz-master-next'), 'out_of_text' => __(' out of ', 'quiz-master-next')));
587
- wp_enqueue_script( 'math_jax', '//cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.2/MathJax.js?config=TeX-MML-AM_CHTML' );
588
- global $qmn_total_questions;
589
- $qmn_total_questions = 0;
590
- global $mlw_qmn_section_count;
591
- $mlw_qmn_section_count = 0;
592
- $auto_pagination_class = $options->pagination > 0 ? 'qsm_auto_pagination_enabled' : '';
593
- $quiz_display .= "<div class='qsm-quiz-container qmn_quiz_container mlw_qmn_quiz {$auto_pagination_class}'>";
594
- // Get quiz post based on quiz id
595
- $args = array(
596
- 'posts_per_page' => 1,
597
- 'post_type' => 'qsm_quiz',
598
- 'meta_query' => array(
599
- array(
600
- 'key' => 'quiz_id',
601
- 'value' => $quiz_data['quiz_id'],
602
- 'compare' => '=',
603
- ),
604
- ),
605
- );
606
- $the_query = new WP_Query($args);
607
-
608
- // The Loop
609
- if ($the_query->have_posts()) {
610
- while ($the_query->have_posts()) {
611
- $the_query->the_post();
612
- $quiz_display .= get_the_post_thumbnail(get_the_ID(),'full');
613
- }
614
- /* Restore original Post Data */
615
- wp_reset_postdata();
616
- }
617
- $quiz_display = apply_filters('qsm_display_before_form', $quiz_display, $options, $quiz_data);
618
- $quiz_display .= "<form name='quizForm{$quiz_data['quiz_id']}' id='quizForm{$quiz_data['quiz_id']}' action='".$_SERVER['REQUEST_URI']."' method='POST' class='qsm-quiz-form qmn_quiz_form mlw_quiz_form' novalidate enctype='multipart/form-data'>";
619
- $quiz_display .= "<input type='hidden' name='qsm_hidden_questions' id='qsm_hidden_questions' value=''>";
620
- $quiz_display .= "<div id='mlw_error_message' class='qsm-error-message qmn_error_message_section'></div>";
621
- $quiz_display .= "<span id='mlw_top_of_quiz'></span>";
622
- $quiz_display = apply_filters('qmn_begin_quiz_form', $quiz_display, $options, $quiz_data);
623
-
624
- // If deprecated pagination setting is not used, use new system...
625
- $pages = $mlwQuizMasterNext->pluginHelper->get_quiz_setting('pages', array());
626
- if (0 == $options->randomness_order && 0 == $options->question_from_total && 0 == $options->pagination && 0 !== count($pages)) {
627
- $quiz_display .= $this->display_pages($options, $quiz_data);
628
- } else {
629
- // ... else, use older system.
630
- $questions = $this->load_questions($quiz_data['quiz_id'], $options, true, $question_amount);
631
- $answers = $this->create_answer_array($questions);
632
- $quiz_display .= $this->display_begin_section($options, $quiz_data);
633
- $quiz_display = apply_filters('qmn_begin_quiz_questions', $quiz_display, $options, $quiz_data);
634
- $quiz_display .= $this->display_questions($options, $questions, $answers);
635
- $quiz_display = apply_filters('qmn_before_comment_section', $quiz_display, $options, $quiz_data);
636
- $quiz_display .= $this->display_comment_section($options, $quiz_data);
637
- $quiz_display = apply_filters('qmn_after_comment_section', $quiz_display, $options, $quiz_data);
638
- $quiz_display .= $this->display_end_section($options, $quiz_data);
639
- }
640
- $quiz_display = apply_filters('qmn_before_error_message', $quiz_display, $options, $quiz_data);
641
- $quiz_display .= "<div id='mlw_error_message_bottom' class='qsm-error-message qmn_error_message_section'></div>";
642
- $quiz_display .= "<input type='hidden' name='total_questions' id='total_questions' value='$qmn_total_questions'/>";
643
- $quiz_display .= "<input type='hidden' name='timer' id='timer' value='0'/>";
644
- $quiz_display .= "<input type='hidden' name='timer_ms' id='timer_ms' value='0'/>";
645
- $quiz_display .= "<input type='hidden' class='qmn_quiz_id' name='qmn_quiz_id' id='qmn_quiz_id' value='{$quiz_data['quiz_id']}'/>";
646
- $quiz_display .= "<input type='hidden' name='complete_quiz' value='confirmation' />";
647
- if (isset($_GET['payment_id']) && $_GET['payment_id'] != '') {
648
- $quiz_display .= "<input type='hidden' name='main_payment_id' value='" . $_GET['payment_id'] . "' />";
649
- }
650
- $quiz_display = apply_filters('qmn_end_quiz_form', $quiz_display, $options, $quiz_data);
651
- $quiz_display .= '</form>';
652
- $quiz_display .= '</div>';
653
-
654
- $quiz_display = apply_filters('qmn_end_quiz', $quiz_display, $options, $quiz_data);
655
- return $quiz_display;
656
- }
657
-
658
- /**
659
- * Creates the pages of content for the quiz/survey
660
- *
661
- * @since 5.2.0
662
- * @param array $options The settings for the quiz.
663
- * @param array $quiz_data The array of quiz data.
664
- * @return string The HTML for the pages
665
- */
666
- public function display_pages($options, $quiz_data) {
667
- global $mlwQuizMasterNext;
668
- global $qmn_json_data;
669
- ob_start();
670
- $pages = $mlwQuizMasterNext->pluginHelper->get_quiz_setting('pages', array());
671
- $qpages = $mlwQuizMasterNext->pluginHelper->get_quiz_setting('qpages', array());
672
- $questions = QSM_Questions::load_questions_by_pages($options->quiz_id);
673
- $question_list = '';
674
- $contact_fields = QSM_Contact_Manager::load_fields();
675
- $animation_effect = isset($options->quiz_animation) && $options->quiz_animation != '' ? ' animated ' . $options->quiz_animation : '';
676
- $enable_pagination_quiz = isset($options->enable_pagination_quiz) && $options->enable_pagination_quiz == 1 ? true : false;
677
- if (count($pages) > 1 && (!empty($options->message_before) || ( 0 == $options->contact_info_location && $contact_fields ) )) {
678
- $qmn_json_data['first_page'] = true;
679
- $message_before = wpautop(htmlspecialchars_decode($options->message_before, ENT_QUOTES));
680
- $message_before = apply_filters('mlw_qmn_template_variable_quiz_page', $message_before, $quiz_data);
681
- ?>
682
- <section class="qsm-page <?php echo $animation_effect; ?>">
683
- <div class="quiz_section quiz_begin">
684
- <div class='qsm-before-message mlw_qmn_message_before'>
685
- <?php
686
- echo $this->qsm_convert_editor_text_to_shortcode( $message_before );
687
- ?>
688
- </div>
689
- <?php
690
- if (0 == $options->contact_info_location) {
691
- echo QSM_Contact_Manager::display_fields($options);
692
- }
693
- ?>
694
- </div>
695
- </section>
696
- <?php
697
- }
698
-
699
- // If there is only one page.
700
- $pages = apply_filters('qsm_display_pages', $pages, $options->quiz_id, $options);
701
- if (1 == count($pages)) {
702
- ?>
703
- <section class="qsm-page <?php echo $animation_effect; ?>">
704
- <?php
705
- if (!empty($options->message_before) || ( 0 == $options->contact_info_location && $contact_fields )) {
706
- $qmn_json_data['first_page'] = false;
707
- $message_before = wpautop(htmlspecialchars_decode($options->message_before, ENT_QUOTES));
708
- $message_before = apply_filters('mlw_qmn_template_variable_quiz_page', $message_before, $quiz_data);
709
- ?>
710
- <div class="quiz_section quiz_begin">
711
- <div class='qsm-before-message mlw_qmn_message_before'>
712
- <?php
713
- echo $this->qsm_convert_editor_text_to_shortcode( $message_before );
714
- ?>
715
- </div>
716
- <?php
717
- if (0 == $options->contact_info_location) {
718
- echo QSM_Contact_Manager::display_fields($options);
719
- }
720
- ?>
721
- </div>
722
- <?php
723
- }
724
- foreach ($pages[0] as $question_id) {
725
- $question_list .= $question_id . 'Q';
726
- $question = $questions[$question_id];
727
- ?>
728
- <div class='quiz_section question-section-id-<?php echo esc_attr($question_id); ?>'>
729
- <?php
730
- echo $mlwQuizMasterNext->pluginHelper->display_question($question['question_type_new'], $question_id, $options);
731
- if (0 == $question['comments']) {
732
- echo "<input type='text' class='qsm-question-comment qsm-question-comment-small mlw_qmn_question_comment' id='mlwComment$question_id' name='mlwComment$question_id' placeholder='" . esc_attr(htmlspecialchars_decode($options->comment_field_text, ENT_QUOTES)) . "' onclick='qmnClearField(this)'/>";
733
- }
734
- if (2 == $question['comments']) {
735
- echo "<textarea class='qsm-question-comment qsm-question-comment-large mlw_qmn_question_comment' id='mlwComment$question_id' name='mlwComment$question_id' placeholder='" . esc_attr(htmlspecialchars_decode($options->comment_field_text, ENT_QUOTES)) ."' onclick='qmnClearField(this)' ></textarea>";
736
- }
737
- // Checks if a hint is entered.
738
- if (!empty($question['hints'])) {
739
- echo '<div class="qsm-hint qsm_hint mlw_qmn_hint_link qsm_tooltip">'.$options->hint_text . '<span class="qsm_tooltiptext">'.htmlspecialchars_decode($question['hints'], ENT_QUOTES).'</span></div>';
740
- }
741
- ?>
742
- </div>
743
- <?php
744
- }
745
- if (0 == $options->comment_section) {
746
- $message_comments = wpautop(htmlspecialchars_decode($options->message_comment, ENT_QUOTES));
747
- $message_comments = apply_filters('mlw_qmn_template_variable_quiz_page', $message_comments, $quiz_data);
748
- ?>
749
- <div class="quiz_section quiz_begin">
750
- <label for='mlwQuizComments' class='qsm-comments-label mlw_qmn_comment_section_text'><?php echo $message_comments; ?></label>
751
- <textarea id='mlwQuizComments' name='mlwQuizComments' class='qsm-comments qmn_comment_section'></textarea>
752
- </div>
753
- <?php
754
- }
755
- if (!empty($options->message_end_template) || ( 1 == $options->contact_info_location && $contact_fields )) {
756
- $message_after = wpautop(htmlspecialchars_decode($options->message_end_template, ENT_QUOTES));
757
- $message_after = apply_filters('mlw_qmn_template_variable_quiz_page', $message_after, $quiz_data);
758
- ?>
759
- <div class="quiz_section">
760
- <div class='qsm-after-message mlw_qmn_message_end'><?php echo $message_after; ?></div>
761
- <?php
762
- if (1 == $options->contact_info_location) {
763
- echo QSM_Contact_Manager::display_fields($options);
764
- }
765
- ?>
766
- </div>
767
- <?php
768
- }
769
- ?>
770
- </section>
771
- <?php
772
- } else {
773
- $total_pages_count = count($pages);
774
- $pages_count = 1;
775
- foreach ($pages as $key => $page) {
776
- $qpage = (isset($qpages[$key]) ? $qpages[$key] : array());
777
- $qpage_id = (isset($qpage['id']) ? $qpage['id'] : $key);
778
- $page_key = (isset($qpage['pagekey']) ? $qpage['pagekey'] : $key);
779
- $hide_prevbtn = (isset($qpage['hide_prevbtn']) ? $qpage['hide_prevbtn'] : 0);
780
- $style = "style='display: none;'";
781
- ?>
782
- <section class="qsm-page <?php echo $animation_effect; ?> qsm-page-<?php echo $qpage_id;?>" data-pid="<?php echo $qpage_id;?>" data-prevbtn="<?php echo $hide_prevbtn;?>" <?php echo $style; ?>>
783
- <?php do_action('qsm_action_before_page', $qpage_id, $qpage);?>
784
- <?php
785
- foreach ($page as $question_id) {
786
- $question_list .= $question_id . 'Q';
787
- $question = $questions[$question_id];
788
- ?>
789
- <div class='quiz_section question-section-id-<?php echo esc_attr($question_id); ?>'>
790
- <?php
791
- echo $mlwQuizMasterNext->pluginHelper->display_question($question['question_type_new'], $question_id, $options);
792
- if (0 == $question['comments']) {
793
- echo "<input type='text' class='qsm-question-comment qsm-question-comment-small mlw_qmn_question_comment' id='mlwComment$question_id' name='mlwComment$question_id' placeholder='" . esc_attr(htmlspecialchars_decode($options->comment_field_text, ENT_QUOTES)) . "' onclick='qmnClearField(this)'/>";
794
- }
795
- if (2 == $question['comments']) {
796
- echo "<textarea class='qsm-question-comment qsm-question-comment-large mlw_qmn_question_comment' id='mlwComment$question_id' name='mlwComment$question_id' placeholder='" . esc_attr(htmlspecialchars_decode($options->comment_field_text, ENT_QUOTES)) ."' onclick='qmnClearField(this)' ></textarea>";
797
- }
798
- // Checks if a hint is entered.
799
- if (!empty($question['hints'])) {
800
- echo '<div class="qsm-hint qsm_hint mlw_qmn_hint_link qsm_tooltip">'.$options->hint_text . '<span class="qsm_tooltiptext">'.htmlspecialchars_decode($question['hints'], ENT_QUOTES).'</span></div>';
801
- }
802
- ?>
803
- </div>
804
- <?php
805
- }
806
- if($enable_pagination_quiz){
807
- ?>
808
- <span class="pages_count">
809
- <?php
810
- $text_c = $pages_count . __(' out of ', 'quiz-master-next') .$total_pages_count;
811
- echo apply_filters('qsm_total_pages_count',$text_c,$pages_count,$total_pages_count);
812
- ?>
813
- </span>
814
- <?php } ?>
815
- </section>
816
- <?php
817
- $pages_count++;
818
- }
819
- }
820
-
821
- if (count($pages) > 1 && 0 == $options->comment_section) {
822
- $message_comments = wpautop(htmlspecialchars_decode($options->message_comment, ENT_QUOTES));
823
- $message_comments = apply_filters('mlw_qmn_template_variable_quiz_page', $message_comments, $quiz_data);
824
- ?>
825
- <section class="qsm-page">
826
- <div class="quiz_section quiz_begin">
827
- <label for='mlwQuizComments' class='qsm-comments-label mlw_qmn_comment_section_text'><?php echo $message_comments; ?></label>
828
- <textarea id='mlwQuizComments' name='mlwQuizComments' class='qsm-comments qmn_comment_section'></textarea>
829
- </div>
830
- </section>
831
- <?php
832
- }
833
- if (count($pages) > 1 && (!empty($options->message_end_template) || ( 1 == $options->contact_info_location && $contact_fields ) )) {
834
- $message_after = wpautop(htmlspecialchars_decode($options->message_end_template, ENT_QUOTES));
835
- $message_after = apply_filters('mlw_qmn_template_variable_quiz_page', $message_after, $quiz_data);
836
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
837
  <section class="qsm-page" style="display: none;">
838
- <div class="quiz_section">
839
- <div class='qsm-after-message mlw_qmn_message_end'><?php echo $message_after; ?></div>
840
- <?php
841
- if (1 == $options->contact_info_location) {
842
- echo QSM_Contact_Manager::display_fields($options);
843
- }
844
- ?>
845
- </div>
846
- <?php
847
- // Legacy code.
848
- do_action('mlw_qmn_end_quiz_section');
849
- ?>
850
- </section>
851
- <?php
852
- }
853
- do_action('qsm_after_all_section');
854
- ?>
855
- <!-- View for pagination -->
856
- <script type="text/template" id="tmpl-qsm-pagination-<?php echo $options->quiz_id;?>">
857
- <div class="qsm-pagination qmn_pagination border margin-bottom">
858
- <a class="qsm-btn qsm-previous qmn_btn mlw_qmn_quiz_link mlw_previous" href="#"><?php echo esc_html($options->previous_button_text); ?></a>
859
- <span class="qmn_page_message"></span>
860
- <div class="qmn_page_counter_message"></div>
861
- <div class="qsm-progress-bar" style="display:none;"><div class="progressbar-text"></div></div>
862
- <a class="qsm-btn qsm-next qmn_btn mlw_qmn_quiz_link mlw_next" href="#"><?php echo esc_html($options->next_button_text); ?></a>
863
- <input type='submit' class='qsm-btn qsm-submit-btn qmn_btn' value='<?php echo esc_attr(htmlspecialchars_decode($options->submit_button_text, ENT_QUOTES)); ?>' />
864
- </div>
865
- </script>
866
- <input type='hidden' name='qmn_question_list' value='<?php echo esc_attr($question_list); ?>' />
867
- <?php
868
- return ob_get_clean();
869
- }
870
-
871
- /**
872
- * Creates Display For Beginning Section
873
- *
874
- * Generates the content for the beginning section of the quiz page
875
- *
876
- * @since 4.0.0
877
- * @param array $qmn_quiz_options The database row of the quiz.
878
- * @param array $qmn_array_for_variables The array of results for the quiz.
879
- * @return string The content for the beginning section
880
- * @deprecated 5.2.0 Use new page system instead
881
- */
882
- public function display_begin_section($qmn_quiz_options, $qmn_array_for_variables) {
883
- $section_display = '';
884
- global $qmn_json_data;
885
- $contact_fields = QSM_Contact_Manager::load_fields();
886
- if (!empty($qmn_quiz_options->message_before) || ( 0 == $qmn_quiz_options->contact_info_location && $contact_fields )) {
887
- $qmn_json_data["first_page"] = true;
888
- global $mlw_qmn_section_count;
889
- $mlw_qmn_section_count += 1;
890
- $animation_effect = isset($qmn_quiz_options->quiz_animation) && $qmn_quiz_options->quiz_animation != '' ? ' animated ' . $qmn_quiz_options->quiz_animation : '';
891
- $section_display .= "<div class='qsm-auto-page-row quiz_section $animation_effect quiz_begin'>";
892
-
893
- $message_before = wpautop(htmlspecialchars_decode($qmn_quiz_options->message_before, ENT_QUOTES));
894
- $message_before = apply_filters('mlw_qmn_template_variable_quiz_page', $message_before, $qmn_array_for_variables);
895
-
896
- $section_display .= "<div class='mlw_qmn_message_before'>". $this->qsm_convert_editor_text_to_shortcode( $message_before ) ."</div>";
897
- if (0 == $qmn_quiz_options->contact_info_location) {
898
- $section_display .= QSM_Contact_Manager::display_fields($qmn_quiz_options);
899
- }
900
- $section_display .= "</div>";
901
- } else {
902
- $qmn_json_data["first_page"] = false;
903
- }
904
- return $section_display;
905
- }
906
-
907
- /**
908
- * Creates Display For Questions
909
- *
910
- * Generates the content for the questions part of the quiz page
911
- *
912
- * @since 4.0.0
913
- * @param array $qmn_quiz_options The database row of the quiz.
914
- * @param array $qmn_quiz_questions The questions of the quiz.
915
- * @param array $qmn_quiz_answers The answers of the quiz.
916
- * @uses QMNPluginHelper:display_question() Displays a question
917
- * @return string The content for the questions section
918
- * @deprecated 5.2.0 Use new page system instead
919
- */
920
- public function display_questions($qmn_quiz_options, $qmn_quiz_questions, $qmn_quiz_answers) {
921
- $question_display = '';
922
- global $mlwQuizMasterNext;
923
- global $qmn_total_questions;
924
- global $mlw_qmn_section_count;
925
- $question_id_list = '';
926
- $animation_effect = isset($qmn_quiz_options->quiz_animation) && $qmn_quiz_options->quiz_animation != '' ? ' animated ' . $qmn_quiz_options->quiz_animation : '';
927
- $enable_pagination_quiz = isset($qmn_quiz_options->enable_pagination_quiz) && $qmn_quiz_options->enable_pagination_quiz ? $qmn_quiz_options->enable_pagination_quiz : 0;
928
- $pagination_optoin = $qmn_quiz_options->pagination;
929
- if($enable_pagination_quiz && $pagination_optoin){
930
- $total_pages_count = count($qmn_quiz_questions);
931
- $total_pagination = ceil($total_pages_count / $pagination_optoin);
932
- }
933
- $pages_count = 1;
934
- $current_page_number = 1;
935
- foreach ($qmn_quiz_questions as $mlw_question) {
936
- if( $pagination_optoin != 0 ){
937
- if( $pagination_optoin == 1 ){
938
- $question_display .='<div class="qsm-auto-page-row qsm-apc-' . $current_page_number . '" style="display: none;">';
939
- $current_page_number++;
940
- }else{
941
- if ($pages_count % $pagination_optoin == 1 || $pages_count == 1) { // beginning of the row or first.
942
- $question_display .='<div class="qsm-auto-page-row qsm-apc-' . $current_page_number . '" style="display: none;">';
943
- $current_page_number++;
944
- }
945
- }
946
- $question_display .= apply_filters('qsm_auto_page_begin_row', '', ($current_page_number - 1), $qmn_quiz_options, $qmn_quiz_questions);
947
  }
948
- $question_id_list .= $mlw_question->question_id . "Q";
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
949
  $question_display .= "<div class='quiz_section {$animation_effect} question-section-id-{$mlw_question->question_id} slide{$mlw_qmn_section_count}'>";
950
- $question_display .= $mlwQuizMasterNext->pluginHelper->display_question($mlw_question->question_type_new, $mlw_question->question_id, $qmn_quiz_options);
951
-
952
- if (0 == $mlw_question->comments) {
953
- $question_display .= "<input type='text' class='mlw_qmn_question_comment' id='mlwComment" . $mlw_question->question_id . "' name='mlwComment" . $mlw_question->question_id . "' placeholder='" . esc_attr(htmlspecialchars_decode($qmn_quiz_options->comment_field_text, ENT_QUOTES)) . "' onclick='qmnClearField(this)'/>";
954
- $question_display .= "<br />";
955
- }
956
- if (2 == $mlw_question->comments) {
957
- $question_display .= "<textarea cols='70' rows='5' class='mlw_qmn_question_comment' id='mlwComment" . $mlw_question->question_id . "' name='mlwComment" . $mlw_question->question_id . "' placeholder='" . htmlspecialchars_decode($qmn_quiz_options->comment_field_text, ENT_QUOTES) . "' onclick='qmnClearField(this)'></textarea>";
958
- $question_display .= "<br />";
959
- }
960
-
961
- // Checks if a hint is entered.
962
- if (!empty($mlw_question->hints)) {
963
- $question_display .= "<div title=\"" . esc_attr(htmlspecialchars_decode($mlw_question->hints, ENT_QUOTES)) . "\" class='qsm_hint mlw_qmn_hint_link'>{$qmn_quiz_options->hint_text}</div>";
964
- $question_display .= "<br /><br />";
965
- }
966
  $question_display .= '</div><!-- .quiz_section -->';
967
- if( $pagination_optoin == 0 ){
968
-
969
- } else if( $pagination_optoin == 1 ){
970
- $question_display .= '</div><!-- .qsm-auto-page-row -->';
971
- }else if ($pages_count % $pagination_optoin == 0 || $pages_count == count($qmn_quiz_questions)) { // end of the row or last
972
- $question_display .= '</div><!-- .qsm-auto-page-row -->';
973
- }
974
- $mlw_qmn_section_count = $mlw_qmn_section_count + 1;
975
- $pages_count++;
976
- }
977
- if($enable_pagination_quiz){
978
- $question_display .= "<span class='pages_count' style='display: none;'>";
979
- $text_c = $current_page_number . __(' out of ', 'quiz-master-next') .$total_pagination;
980
- $question_display .= apply_filters('qsm_total_pages_count',$text_c,$pages_count,$total_pages_count);
981
- $question_display .= "</span>";
982
- }
983
- $question_display .= "<input type='hidden' name='qmn_question_list' value='$question_id_list' />";
984
- return $question_display;
985
- }
986
-
987
- /**
988
- * Creates Display For Comment Section
989
- *
990
- * Generates the content for the comment section part of the quiz page
991
- *
992
- * @since 4.0.0
993
- * @param array $qmn_quiz_options The database row of the quiz.
994
- * @param array $qmn_array_for_variables The array of results for the quiz.
995
- * @return string The content for the comment section
996
- * @deprecated 5.2.0 Use new page system instead
997
- */
998
- public function display_comment_section($qmn_quiz_options, $qmn_array_for_variables) {
999
- global $mlw_qmn_section_count;
1000
- $comment_display = '';
1001
- if (0 == $qmn_quiz_options->comment_section) {
1002
- $mlw_qmn_section_count = $mlw_qmn_section_count + 1;
1003
- $comment_display .= "<div class='quiz_section quiz_end qsm-auto-page-row qsm-quiz-comment-section slide" . $mlw_qmn_section_count . "' style='display: none;'>";
1004
- $message_comments = wpautop(htmlspecialchars_decode($qmn_quiz_options->message_comment, ENT_QUOTES));
1005
- $message_comments = apply_filters('mlw_qmn_template_variable_quiz_page', $message_comments, $qmn_array_for_variables);
1006
- $comment_display .= "<label for='mlwQuizComments' class='mlw_qmn_comment_section_text'>$message_comments</label><br />";
1007
- $comment_display .= "<textarea cols='60' rows='10' id='mlwQuizComments' name='mlwQuizComments' class='qmn_comment_section'></textarea>";
1008
- $comment_display .= "</div>";
1009
- }
1010
- return $comment_display;
1011
- }
1012
-
1013
- /**
1014
- * Creates Display For End Section Of Quiz Page
1015
- *
1016
- * Generates the content for the end section of the quiz page
1017
- *
1018
- * @since 4.0.0
1019
- * @param array $qmn_quiz_options The database row of the quiz.
1020
- * @param array $qmn_array_for_variables The array of results for the quiz.
1021
- * @return string The content for the end section
1022
- * @deprecated 5.2.0 Use new page system instead
1023
- */
1024
- public function display_end_section($qmn_quiz_options, $qmn_array_for_variables) {
1025
- global $mlw_qmn_section_count;
1026
- $section_display = '';
1027
- $section_display .= '<br />';
1028
- $mlw_qmn_section_count = $mlw_qmn_section_count + 1;
1029
- $pagination_optoin = $qmn_quiz_options->pagination;
1030
- $style = '';
1031
- if( $pagination_optoin > 0 ){
1032
- $style = "style='display: none;'";
1033
- }
1034
- $section_display .= "<div class='qsm-auto-page-row quiz_section quiz_end' {$style}>";
1035
- if (!empty($qmn_quiz_options->message_end_template)) {
1036
- $message_end = wpautop(htmlspecialchars_decode($qmn_quiz_options->message_end_template, ENT_QUOTES));
1037
- $message_end = apply_filters('mlw_qmn_template_variable_quiz_page', $message_end, $qmn_array_for_variables);
1038
- $section_display .= "<span class='mlw_qmn_message_end'>$message_end</span>";
1039
- $section_display .= '<br /><br />';
1040
- }
1041
- if (1 == $qmn_quiz_options->contact_info_location) {
1042
- $section_display .= QSM_Contact_Manager::display_fields($qmn_quiz_options);
1043
- }
1044
-
1045
- // Legacy Code.
1046
- ob_start();
1047
- do_action('mlw_qmn_end_quiz_section');
1048
- $section_display .= ob_get_contents();
1049
- ob_end_clean();
1050
- $section_display .= "<input type='submit' class='qsm-btn qsm-submit-btn qmn_btn' value='" . esc_attr(htmlspecialchars_decode($qmn_quiz_options->submit_button_text, ENT_QUOTES)) . "' />";
1051
- $section_display .= "</div>";
1052
-
1053
- return $section_display;
1054
- }
1055
-
1056
- /**
1057
- * Generates Content Results Page
1058
- *
1059
- * Generates the content for the results page part of the shortcode
1060
- *
1061
- * @since 4.0.0
1062
- * @param array $options The database row of the quiz.
1063
- * @param array $data The array of results for the quiz.
1064
- * @uses QMNQuizManager:submit_results() Perform The Quiz/Survey Submission
1065
- * @return string The content for the results page section
1066
- */
1067
- public function display_results($options, $data) {
1068
- $result = $this->submit_results($options, $data);
1069
- $results_array = $result;
1070
- return $results_array['display'];
1071
- }
1072
-
1073
- /**
1074
- * Calls the results page from ajax
1075
- *
1076
- * @since 4.6.0
1077
- * @uses QMNQuizManager:submit_results() Perform The Quiz/Survey Submission
1078
- * @return string The content for the results page section
1079
- */
1080
- public function ajax_submit_results() {
1081
- global $qmn_allowed_visit;
1082
- global $mlwQuizMasterNext;
1083
-
1084
- $qmn_allowed_visit = true;
1085
- $quiz = intval($_POST["qmn_quiz_id"]);
1086
- $mlwQuizMasterNext->pluginHelper->prepare_quiz($quiz);
1087
- $options = $mlwQuizMasterNext->quiz_settings->get_quiz_options();
1088
- $data = array(
1089
- 'quiz_id' => $options->quiz_id,
1090
- 'quiz_name' => $options->quiz_name,
1091
- 'quiz_system' => $options->system,
1092
- 'quiz_payment_id' => isset($_POST['main_payment_id']) ? sanitize_text_field($_POST['main_payment_id']) : ''
1093
- );
1094
- $post_data = array(
1095
- 'g-recaptcha-response' => isset($_POST['g-recaptcha-response']) ? sanitize_textarea_field($_POST['g-recaptcha-response']) : ''
1096
- );
1097
- if(class_exists('QSM_Recaptcha')){
1098
- $recaptcha_data = $mlwQuizMasterNext->pluginHelper->get_quiz_setting( "recaptcha_integration_settings" );
1099
- if(isset($recaptcha_data['enable_recaptcha']) && $recaptcha_data['enable_recaptcha'] != 'no'){
1100
- $verified = qsm_verify_recaptcha($post_data);
1101
- if(!$verified){
1102
- echo json_encode(array(
1103
- 'display' => htmlspecialchars_decode('ReCaptcha Validation failed'),
1104
- 'redirect' => FALSE,
1105
- ));
1106
- exit;
1107
- }
1108
- }
1109
- }
1110
- echo json_encode($this->submit_results($options, $data));
1111
- die();
1112
- }
1113
-
1114
- /**
1115
- * @version 6.3.2
1116
- * Show quiz on button click
1117
- */
1118
- public function qsm_get_quiz_to_reload(){
1119
- $quiz_id = sanitize_text_field(intval($_POST['quiz_id']));
1120
- echo do_shortcode('[qsm quiz="'. $quiz_id .'"]');
1121
- exit;
1122
- }
1123
-
1124
- /**
1125
- * Perform The Quiz/Survey Submission
1126
- *
1127
- * Prepares and save the results, prepares and send emails, prepare results page
1128
- *
1129
- * @since 4.6.0
1130
- * @param array $qmn_quiz_options The database row of the quiz.
1131
- * @param array $qmn_array_for_variables The array of results for the quiz.
1132
- * @uses QMNQuizManager:check_answers() Creates display for beginning section
1133
- * @uses QMNQuizManager:check_comment_section() Creates display for questions
1134
- * @uses QMNQuizManager:display_results_text() Creates display for end section
1135
- * @uses QMNQuizManager:display_social() Creates display for comment section
1136
- * @uses QMNQuizManager:send_user_email() Creates display for end section
1137
- * @uses QMNQuizManager:send_admin_email() Creates display for end section
1138
- * @return string The content for the results page section
1139
- */
1140
- public function submit_results($qmn_quiz_options, $qmn_array_for_variables) {
1141
- global $qmn_allowed_visit;
1142
- $result_display = '';
1143
-
1144
- $qmn_array_for_variables['user_ip'] = $this->get_user_ip();
1145
-
1146
- $result_display = apply_filters('qmn_begin_results', $result_display, $qmn_quiz_options, $qmn_array_for_variables);
1147
- if (!$qmn_allowed_visit) {
1148
- return $result_display;
1149
- }
1150
- //Add form type for new quiz system 7.0.0
1151
- $qmn_array_for_variables['form_type'] = isset( $qmn_quiz_options->form_type ) ? $qmn_quiz_options->form_type : 0;
1152
- // Gathers contact information.
1153
- $qmn_array_for_variables['user_name'] = 'None';
1154
- $qmn_array_for_variables['user_business'] = 'None';
1155
- $qmn_array_for_variables['user_email'] = 'None';
1156
- $qmn_array_for_variables['user_phone'] = 'None';
1157
- $contact_responses = QSM_Contact_Manager::process_fields($qmn_quiz_options);
1158
- foreach ($contact_responses as $field) {
1159
- if (isset($field['use'])) {
1160
- if ('name' === $field['use']) {
1161
- $qmn_array_for_variables['user_name'] = $field["value"];
1162
- }
1163
- if ('comp' === $field['use']) {
1164
- $qmn_array_for_variables['user_business'] = $field["value"];
1165
- }
1166
- if ('email' === $field['use']) {
1167
- $qmn_array_for_variables['user_email'] = $field["value"];
1168
- }
1169
- if ('phone' === $field['use']) {
1170
- $qmn_array_for_variables['user_phone'] = $field["value"];
1171
- }
1172
- }
1173
- }
1174
-
1175
- if( is_user_logged_in() ){
1176
- $current_user = wp_get_current_user();
1177
- if( $qmn_array_for_variables['user_email'] == 'None' )
1178
- $qmn_array_for_variables['user_email'] = esc_html( $current_user->user_email );
1179
-
1180
- if( $qmn_array_for_variables['user_name'] == 'None' )
1181
- $qmn_array_for_variables['user_name'] = esc_html( $current_user->display_name );
1182
- }
1183
-
1184
- $mlw_qmn_pagetime = isset($_POST["pagetime"]) ? $_POST["pagetime"] : array();
1185
- $mlw_qmn_timer = isset($_POST["timer"]) ? sanitize_text_field(intval($_POST["timer"])) : 0;
1186
- $mlw_qmn_timer_ms = isset($_POST["timer_ms"]) ? sanitize_text_field(intval($_POST["timer_ms"])) : 0;
1187
- $qmn_array_for_variables['user_id'] = get_current_user_id();
1188
- $qmn_array_for_variables['timer'] = $mlw_qmn_timer;
1189
- $qmn_array_for_variables['timer_ms'] = $mlw_qmn_timer_ms;
1190
- $qmn_array_for_variables['time_taken'] = current_time('h:i:s A m/d/Y');
1191
- $qmn_array_for_variables['contact'] = $contact_responses;
1192
- $qmn_array_for_variables['hidden_questions'] = isset($_POST['qsm_hidden_questions']) ? json_decode(html_entity_decode(stripslashes($_POST['qsm_hidden_questions'])),true) : array();
1193
- $qmn_array_for_variables = apply_filters('qsm_result_variables', $qmn_array_for_variables);
1194
-
1195
- if (!isset($_POST["mlw_code_captcha"]) || ( isset($_POST["mlw_code_captcha"]) && $_POST["mlw_user_captcha"] == $_POST["mlw_code_captcha"] )) {
1196
-
1197
- $qmn_array_for_variables = array_merge($qmn_array_for_variables, $this->check_answers($qmn_quiz_options, $qmn_array_for_variables));
1198
- $result_display = apply_filters('qmn_after_check_answers', $result_display, $qmn_quiz_options, $qmn_array_for_variables);
1199
- $qmn_array_for_variables['comments'] = $this->check_comment_section($qmn_quiz_options, $qmn_array_for_variables);
1200
- $result_display = apply_filters('qmn_after_check_comments', $result_display, $qmn_quiz_options, $qmn_array_for_variables);
1201
-
1202
- $unique_id = md5(date("Y-m-d H:i:s"));
 
 
 
 
1203
  $results_id = 0;
1204
- // If the store responses in database option is set to Yes.
1205
- if (0 != $qmn_quiz_options->store_responses) {
1206
-
1207
- // Creates our results array.
1208
- $results_array = array(
1209
- intval($qmn_array_for_variables['timer']),
1210
- $qmn_array_for_variables['question_answers_array'],
1211
- htmlspecialchars(stripslashes($qmn_array_for_variables['comments']), ENT_QUOTES),
1212
- 'contact' => $contact_responses,
1213
- 'timer_ms' => intval($qmn_array_for_variables['timer_ms']),
1214
  'pagetime' => $mlw_qmn_pagetime,
1215
- );
1216
- $results_array = apply_filters('qsm_results_array', $results_array, $qmn_array_for_variables);
1217
- if(isset($results_array['parameters'])) {
1218
- $qmn_array_for_variables['parameters'] = $results_array['parameters'];
1219
- }
1220
- $results_array['hidden_questions'] = $qmn_array_for_variables['hidden_questions'];
1221
- $results_array['total_possible_points'] = $qmn_array_for_variables['total_possible_points'];
1222
- $results_array['total_attempted_questions'] = $qmn_array_for_variables['total_attempted_questions'];
1223
- $serialized_results = serialize($results_array);
1224
-
1225
- // Inserts the responses in the database.
1226
- global $wpdb;
1227
- $table_name = $wpdb->prefix . "mlw_results";
1228
- if (isset($_POST['update_result']) && !empty($_POST['update_result'])) {
1229
- $results_id = $_POST['update_result'];
1230
- $results_update = $wpdb->update($table_name, array(
1231
- 'point_score' => $qmn_array_for_variables['total_points'],
1232
- 'correct_score' => $qmn_array_for_variables['total_score'],
1233
- 'correct' => $qmn_array_for_variables['total_correct'],
1234
- 'total' => $qmn_array_for_variables['total_questions'],
1235
- 'user_ip' => $qmn_array_for_variables['user_ip'],
1236
- 'time_taken' => $qmn_array_for_variables['time_taken'],
1237
- 'time_taken_real' => date('Y-m-d H:i:s', strtotime($qmn_array_for_variables['time_taken'])),
1238
- 'quiz_results' => $serialized_results,
1239
- ), array('result_id' => $results_id));
 
 
 
 
1240
  } else {
1241
- $results_insert = $wpdb->insert($table_name, array(
1242
- 'quiz_id' => $qmn_array_for_variables['quiz_id'],
1243
- 'quiz_name' => $qmn_array_for_variables['quiz_name'],
1244
- 'quiz_system' => $qmn_array_for_variables['quiz_system'],
1245
- 'point_score' => $qmn_array_for_variables['total_points'],
1246
- 'correct_score' => $qmn_array_for_variables['total_score'],
1247
- 'correct' => $qmn_array_for_variables['total_correct'],
1248
- 'total' => $qmn_array_for_variables['total_questions'],
1249
- 'name' => $qmn_array_for_variables['user_name'],
1250
- 'business' => $qmn_array_for_variables['user_business'],
1251
- 'email' => $qmn_array_for_variables['user_email'],
1252
- 'phone' => $qmn_array_for_variables['user_phone'],
1253
- 'user' => $qmn_array_for_variables['user_id'],
1254
- 'user_ip' => $qmn_array_for_variables['user_ip'],
1255
- 'time_taken' => $qmn_array_for_variables['time_taken'],
1256
- 'time_taken_real' => date('Y-m-d H:i:s', strtotime($qmn_array_for_variables['time_taken'])),
1257
- 'quiz_results' => $serialized_results,
1258
- 'deleted' => 0,
1259
- 'unique_id' => $unique_id,
1260
- 'form_type' => isset($qmn_quiz_options->form_type) ? $qmn_quiz_options->form_type : 0,
1261
- ), array(
1262
- '%d',
1263
- '%s',
1264
- '%d',
1265
- '%f',
1266
- '%d',
1267
- '%d',
1268
- '%d',
1269
- '%s',
1270
- '%s',
1271
- '%s',
1272
- '%s',
1273
- '%d',
1274
- '%s',
1275
- '%s',
1276
- '%s',
1277
- '%s',
1278
- '%d',
1279
- '%s',
1280
- '%d',
 
 
 
1281
  )
1282
  );
1283
- $results_id = $wpdb->insert_id;
1284
  }
1285
  }
1286
- $qmn_array_for_variables['result_id'] = $results_id;
1287
 
1288
  // Determines redirect/results page.
1289
- $results_pages = $this->display_results_text($qmn_quiz_options, $qmn_array_for_variables);
1290
- $result_display .= $results_pages['display'];
1291
- $result_display = apply_filters('qmn_after_results_text', $result_display, $qmn_quiz_options, $qmn_array_for_variables);
1292
-
1293
- $result_display .= $this->display_social($qmn_quiz_options, $qmn_array_for_variables);
1294
- $result_display = apply_filters('qmn_after_social_media', $result_display, $qmn_quiz_options, $qmn_array_for_variables);
1295
- if ($this->qsm_plugin_active('qsm-save-resume/qsm-save-resume.php') != 1 && $qmn_quiz_options->enable_retake_quiz_button == 1) {
1296
- $result_display .= '<a style="float: right;" class="button btn-reload-quiz" data-quiz_id="' . $qmn_array_for_variables['quiz_id'] . '" href="#" >' . apply_filters('qsm_retake_quiz_text', __('Retake Quiz', 'quiz-master-next')) . '</a>';
1297
- }
1298
 
1299
  /*
1300
  * Update the option `qmn_quiz_taken_cnt` value by 1 each time
1301
  * whenever the record inserted into the required table.
1302
  */
1303
- if( $results_insert ) {
1304
  $rec_inserted = intval( get_option( 'qmn_quiz_taken_cnt' ) );
1305
- if( 1000 > $rec_inserted ) {
1306
- if( ! $rec_inserted ) {
1307
  update_option( 'qmn_quiz_taken_cnt', 1, true );
1308
- }else {
1309
  update_option( 'qmn_quiz_taken_cnt', ++$rec_inserted );
1310
  }
1311
  }
1312
  }
1313
 
1314
- // Hook is fired after the responses are submitted. Passes responses, result ID, quiz settings, and response data.
1315
- do_action('qsm_quiz_submitted', $results_array, $results_id, $qmn_quiz_options, $qmn_array_for_variables);
1316
-
1317
- $qmn_array_for_variables = apply_filters( 'qmn_filter_email_content', $qmn_array_for_variables, $results_id);
1318
-
1319
- $qmn_global_settings = (array) get_option('qmn-settings');
1320
- $background_quiz_email_process = isset( $qmn_global_settings['background_quiz_email_process'] ) ? esc_attr( $qmn_global_settings['background_quiz_email_process'] ) : '1';
1321
- if( $background_quiz_email_process == 1 ){
1322
- // Send the emails in background.
1323
- $qmn_array_for_variables['quiz_settings'] = isset( $qmn_quiz_options->quiz_settings ) ? @unserialize( $qmn_quiz_options->quiz_settings ) : array();
1324
- $qmn_array_for_variables['email_processed'] = 'yes';
1325
- $this->qsm_background_email->data( array( 'name' => 'send_emails', 'variables' => $qmn_array_for_variables ) )->dispatch();
1326
- }else{
1327
- // Sends the emails.
1328
- $qmn_array_for_variables['email_processed'] = 'yes';
1329
- QSM_Emails::send_emails($qmn_array_for_variables);
1330
- }
1331
-
1332
- /**
1333
- * Filters for filtering the results text after emails are sent.
1334
- *
1335
- * @deprecated 6.2.0 There's no reason to use these over the actions
1336
- * in the QSM_Results_Pages class or the other filters in this function.
1337
- */
1338
- $result_display = apply_filters('qmn_after_send_user_email', $result_display, $qmn_quiz_options, $qmn_array_for_variables);
1339
- $result_display = apply_filters('qmn_after_send_admin_email', $result_display, $qmn_quiz_options, $qmn_array_for_variables);
1340
-
1341
- // Last time to filter the HTML results page.
1342
- $result_display = apply_filters('qmn_end_results', $result_display, $qmn_quiz_options, $qmn_array_for_variables);
1343
-
1344
- // Legacy Code.
1345
- do_action('mlw_qmn_load_results_page', $wpdb->insert_id, $qmn_quiz_options->quiz_settings);
1346
- } else {
1347
- $result_display .= apply_filters('qmn_captcha_varification_failed_msg', __('Captcha verification failed.', 'quiz-master-next'), $qmn_quiz_options, $qmn_array_for_variables);
1348
- }
1349
-
1350
- $result_display = str_replace('%FB_RESULT_ID%', $unique_id, $result_display);
1351
-
1352
- // Prepares data to be sent back to front-end.
1353
- $return_array = array(
1354
- 'display' => htmlspecialchars_decode($result_display),
1355
- 'redirect' => apply_filters('mlw_qmn_template_variable_results_page', $results_pages['redirect'], $qmn_array_for_variables),
1356
- );
1357
-
1358
- return $return_array;
1359
- }
1360
-
1361
- /**
1362
- * Scores User Answers
1363
- *
1364
- * Calculates the users scores for the quiz
1365
- *
1366
- * @since 4.0.0
1367
- * @param array $options The database row of the quiz
1368
- * @param array $quiz_data The array of results for the quiz
1369
- * @uses QMNPluginHelper:display_review() Scores the question
1370
- * @return array The results of the user's score
1371
- */
1372
- public function check_answers($options, $quiz_data) {
1373
-
1374
- global $mlwQuizMasterNext;
1375
-
1376
- // Load the pages and questions
1377
- $pages = $mlwQuizMasterNext->pluginHelper->get_quiz_setting('pages', array());
1378
- $questions = QSM_Questions::load_questions_by_pages($options->quiz_id);
1379
-
1380
- // Retrieve data from submission
1381
- $total_questions = isset($_POST["total_questions"]) ? sanitize_text_field(intval($_POST["total_questions"])) : 0;
1382
- $question_list = array();
1383
- if(isset($_POST["qmn_question_list"])){
1384
- $qmn_question_list = sanitize_text_field($_POST["qmn_question_list"]);
1385
- $question_list = explode('Q', $qmn_question_list);
1386
- }
1387
-
1388
- // Prepare variables
1389
- $points_earned = 0;
1390
- $total_correct = 0;
1391
- $total_score = 0;
1392
- $user_answer = "";
1393
- $correct_answer = "";
1394
- $correct_status = "incorrect";
1395
- $answer_points = 0;
1396
- $question_data = array();
1397
- $total_possible_points = 0;
1398
- $attempted_question = 0;
1399
-
1400
- // Question types to calculate result on
1401
- $result_question_types = array(
1402
- 0, // Multiple Choice
1403
- 1, // Horizontal Multiple Choice
1404
- 2, // Drop Down
1405
- 4, // Multiple Response
1406
- 10, // Horizontal Multiple Response
1407
- 12, // Date
1408
- 3, // Small Open Answer
1409
- 5, // Large Open Answer
1410
- 7, // Number
1411
- 14, // Fill In The Blank
1412
- 13 //Polar.
1413
- );
1414
-
1415
- // If deprecated pagination setting is not used, use new system...
1416
- if (0 == $options->question_from_total && 0 !== count($pages)) {
1417
-
1418
- // Cycle through each page in quiz.
1419
- foreach ($pages as $page) {
1420
-
1421
- // Cycle through each question on a page
1422
- foreach ($page as $page_question_id) {
1423
-
1424
- // Cycle through each question that appeared to the user
1425
- foreach ($question_list as $question_id) {
1426
-
1427
- // When the questions are the same...
1428
- if ($page_question_id == $question_id) {
1429
-
1430
- $question = $questions[$page_question_id];
1431
- // Ignore non points questions from result
1432
- $question_type_new = $question['question_type_new'];
1433
- $hidden_questions = is_array($quiz_data['hidden_questions']) ? $quiz_data['hidden_questions']: array();
1434
-
1435
- // Reset question-specific variables
1436
- $user_answer = "";
1437
- $correct_answer = "";
1438
- $correct_status = "incorrect";
1439
- $answer_points = 0;
1440
-
1441
- //Get total correct points
1442
- if( ( $options->system == 3 || $options->system == 1 ) && isset($question['answers']) && !empty( $question['answers'] ) ){
1443
- if(!in_array($question_id,$hidden_questions)) {
1444
- if( $question_type_new == 4 || $question_type_new == 10 ){
1445
- foreach ($question['answers'] as $single_answerk_key => $single_answer_arr) {
1446
- if ( $options->system == 1 && isset( $single_answer_arr[1] ) ){
1447
- $total_possible_points = $total_possible_points + $single_answer_arr[1];
1448
- }
1449
- if( $options->system == 3 && isset( $single_answer_arr[2] ) && $single_answer_arr[2] == 1 ){
1450
- $total_possible_points = $total_possible_points + $single_answer_arr[1];
1451
- }
1452
- }
1453
- }else{
1454
- $max_value = max(array_column($question['answers'], '1'));
1455
- $total_possible_points = $total_possible_points + $max_value;
1456
- }
1457
- }
1458
- }
1459
-
1460
- // Send question to our grading function
1461
- $results_array = apply_filters('qmn_results_array', $mlwQuizMasterNext->pluginHelper->display_review($question['question_type_new'], $question['question_id']));
1462
- if( isset($results_array['question_type']) && $results_array['question_type'] == 'file_upload') {
1463
- $results_array['user_text'] = '<a target="_blank" href="'.$results_array['user_text'].'">' . __('Click here to view', 'quiz-master-next') . '</a>';
1464
- }
1465
- // If question was graded correctly.
1466
- if (!isset($results_array["null_review"])) {
1467
- if(in_array($question_type_new,$result_question_types)) {
1468
- if(!in_array($question_id,$hidden_questions)) {
1469
- $points_earned += $results_array["points"];
1470
- $answer_points += $results_array["points"];
1471
- }
1472
- }
1473
-
1474
-
1475
- // If the user's answer was correct
1476
- if ('correct' == $results_array["correct"]) {
1477
- if(in_array($question_type_new,$result_question_types)) {
1478
- if(!in_array($question_id,$hidden_questions)) {
1479
- $total_correct += 1;
1480
- $correct_status = "correct";
1481
- }
1482
- }
1483
-
1484
- }
1485
- $user_answer = $results_array["user_text"];
1486
- $correct_answer = $results_array["correct_text"];
1487
- $user_compare_text = isset( $results_array["user_compare_text"] ) ? $results_array["user_compare_text"] : '';
1488
-
1489
- if( trim( $user_answer ) != '' ){
1490
- if( $user_answer != 'No Answer Provided' ){
1491
- $attempted_question++;
1492
- }
1493
- }
1494
-
1495
- // If a comment was submitted
1496
- if (isset($_POST["mlwComment" . $question['question_id']])) {
1497
- $comment = sanitize_textarea_field( htmlspecialchars(stripslashes($_POST["mlwComment" . $question['question_id']]), ENT_QUOTES) );
1498
- } else {
1499
- $comment = "";
1500
- }
1501
-
1502
- // Get text for question
1503
- $question_text = $question['question_name'];
1504
- if (isset($results_array["question_text"])) {
1505
- $question_text = $results_array["question_text"];
1506
- }
1507
-
1508
- // Save question data into new array in our array
1509
- $question_data[] = apply_filters('qmn_answer_array', array(
1510
- $question_text,
1511
- htmlspecialchars($user_answer, ENT_QUOTES),
1512
- htmlspecialchars($correct_answer, ENT_QUOTES),
1513
- $comment,
1514
- "correct" => $correct_status,
1515
- "id" => $question['question_id'],
1516
- "points" => $answer_points,
1517
- "category" => $question['category'],
1518
- "question_type" => $question['question_type_new'],
1519
- "question_title" => isset( $question['settings']['question_title'] ) ? $question['settings']['question_title'] : '',
1520
- "user_compare_text" => $user_compare_text
1521
- ), $options, $quiz_data);
1522
- }
1523
- break;
1524
- }
1525
- }
1526
- }
1527
- }
1528
- } else {
1529
- // Cycle through each page in quiz.
1530
- foreach ($questions as $question) {
1531
-
1532
- // Cycle through each question that appeared to the user
1533
- foreach ($question_list as $question_id) {
1534
-
1535
- // When the questions are the same...
1536
- if ($question['question_id'] == $question_id) {
1537
-
1538
- // Reset question-specific variables
1539
- $user_answer = "";
1540
- $correct_answer = "";
1541
- $correct_status = "incorrect";
1542
- $answer_points = 0;
1543
-
1544
- //Get total correct points
1545
- if( ( $options->system == 3 || $options->system == 1 ) && isset($question['answers']) && !empty( $question['answers'] ) ){
1546
- if( $question_type_new == 4 || $question_type_new == 10 ){
1547
- foreach ($question['answers'] as $single_answerk_key => $single_answer_arr) {
1548
- if ( $options->system == 1 && isset( $single_answer_arr[1] ) ){
1549
- $total_possible_points = $total_possible_points + $single_answer_arr[1];
1550
- }
1551
- if( $options->system == 3 && isset( $single_answer_arr[2] ) && $single_answer_arr[2] == 1 ){
1552
- $total_possible_points = $total_possible_points + $single_answer_arr[1];
1553
- }
1554
- }
1555
- }else{
1556
- $max_value = max(array_column($question['answers'], '1'));
1557
- $total_possible_points = $total_possible_points + $max_value;
1558
- }
1559
- }
1560
-
1561
- // Send question to our grading function
1562
- $results_array = apply_filters('qmn_results_array', $mlwQuizMasterNext->pluginHelper->display_review($question['question_type_new'], $question['question_id']));
1563
-
1564
-
1565
- // If question was graded correctly.
1566
- if (!isset($results_array["null_review"])) {
1567
- $points_earned += $results_array["points"];
1568
- $answer_points += $results_array["points"];
1569
-
1570
- // If the user's answer was correct
1571
- if ('correct' == $results_array["correct"]) {
1572
- $total_correct += 1;
1573
- $correct_status = "correct";
1574
- }
1575
- $user_answer = $results_array["user_text"];
1576
- $correct_answer = $results_array["correct_text"];
1577
- $user_compare_text = isset( $results_array["user_compare_text"] ) ? $results_array["user_compare_text"] : '';
1578
- if( trim( $user_answer ) != '' ){
1579
- if( $user_answer != 'No Answer Provided' ){
1580
- $attempted_question++;
1581
- }
1582
- }
1583
- // If a comment was submitted
1584
- if (isset($_POST["mlwComment" . $question['question_id']])) {
1585
- $comment = sanitize_textarea_field( htmlspecialchars(stripslashes($_POST["mlwComment" . $question['question_id']]), ENT_QUOTES) );
1586
- } else {
1587
- $comment = "";
1588
- }
1589
 
1590
- // Get text for question
1591
- $question_text = $question['question_name'];
1592
- if (isset($results_array["question_text"])) {
1593
- $question_text = $results_array["question_text"];
1594
- }
 
 
 
1595
 
1596
- // Save question data into new array in our array
1597
- $question_data[] = apply_filters('qmn_answer_array', array(
1598
- $question_text,
1599
- htmlspecialchars($user_answer, ENT_QUOTES),
1600
- htmlspecialchars($correct_answer, ENT_QUOTES),
1601
- $comment,
1602
- "correct" => $correct_status,
1603
- "id" => $question['question_id'],
1604
- "points" => $answer_points,
1605
- "category" => $question['category'],
1606
- "question_type" => $question['question_type_new'],
1607
- "question_title" => isset( $question['settings']['question_title'] ) ? $question['settings']['question_title'] : '',
1608
- "user_compare_text" => $user_compare_text
1609
- ), $options, $quiz_data);
1610
- }
1611
- break;
1612
- }
1613
- }
1614
- }
1615
- }
1616
-
1617
- // Calculate Total Percent Score And Average Points Only If Total Questions Doesn't Equal Zero To Avoid Division By Zero Error
1618
- if (0 !== $total_questions) {
1619
- $total_score = round(( ( $total_correct / $total_questions ) * 100), 2);
1620
- } else {
1621
- $total_score = 0;
1622
- }
1623
-
1624
- // Return array to be merged with main user response array
1625
- return array(
1626
- 'total_points' => $points_earned,
1627
- 'total_score' => $total_score,
1628
- 'total_correct' => $total_correct,
1629
- 'total_questions' => $total_questions,
1630
- 'question_answers_display' => '', // Kept for backwards compatibility
1631
- 'question_answers_array' => $question_data,
1632
- 'total_possible_points' => $total_possible_points,
1633
- 'total_attempted_questions' => $attempted_question
1634
- );
1635
- }
1636
-
1637
- /**
1638
- * Retrieves User's Comments
1639
- *
1640
- * Checks to see if the user left a comment and returns the comment
1641
- *
1642
- * @since 4.0.0
1643
- * @param array $qmn_quiz_options The database row of the quiz
1644
- * @param array $qmn_array_for_variables The array of results for the quiz
1645
- * @return string The user's comments
1646
- */
1647
- public function check_comment_section($qmn_quiz_options, $qmn_array_for_variables) {
1648
- $qmn_quiz_comments = "";
1649
- if (isset($_POST["mlwQuizComments"])) {
1650
- $qmn_quiz_comments = esc_textarea(stripslashes($_POST["mlwQuizComments"]));
1651
- }
1652
- return apply_filters('qmn_returned_comments', $qmn_quiz_comments, $qmn_quiz_options, $qmn_array_for_variables);
1653
- }
1654
-
1655
- /**
1656
- * Displays Results Text
1657
- *
1658
- * @since 4.0.0
1659
- * @deprecated 6.1.0 Use the newer results page class instead.
1660
- * @param array $options The quiz settings.
1661
- * @param array $response_data The array of results for the quiz.
1662
- * @return string The contents for the results text
1663
- */
1664
- public function display_results_text($options, $response_data) {
1665
- return QSM_Results_Pages::generate_pages($response_data);
1666
- }
1667
-
1668
- /**
1669
- * Displays social media buttons
1670
- *
1671
- * @deprecated 6.1.0 Use the social media template variables instead.
1672
- * @since 4.0.0
1673
- * @param array $qmn_quiz_options The database row of the quiz.
1674
- * @param array $qmn_array_for_variables The array of results for the quiz.
1675
- * @return string The content of the social media button section
1676
- */
1677
- public function display_social($qmn_quiz_options, $qmn_array_for_variables) {
1678
- $social_display = '';
1679
- if ($qmn_quiz_options->social_media == 1) {
1680
- $settings = (array) get_option('qmn-settings');
1681
- $facebook_app_id = '594986844960937';
1682
- if (isset($settings['facebook_app_id'])) {
1683
- $facebook_app_id = esc_js($settings['facebook_app_id']);
1684
- }
1685
-
1686
- // Loads Social Media Text.
1687
- $qmn_social_media_text = "";
1688
- if (is_serialized($qmn_quiz_options->social_media_text) && is_array(@unserialize($qmn_quiz_options->social_media_text))) {
1689
- $qmn_social_media_text = @unserialize($qmn_quiz_options->social_media_text);
1690
- } else {
1691
- $qmn_social_media_text = array(
1692
- 'twitter' => $qmn_quiz_options->social_media_text,
1693
- 'facebook' => $qmn_quiz_options->social_media_text,
1694
- );
1695
- }
1696
- $qmn_social_media_text["twitter"] = apply_filters('mlw_qmn_template_variable_results_page', $qmn_social_media_text["twitter"], $qmn_array_for_variables);
1697
- $qmn_social_media_text["facebook"] = apply_filters('mlw_qmn_template_variable_results_page', $qmn_social_media_text["facebook"], $qmn_array_for_variables);
1698
- $social_display .= "<br /><a class=\"mlw_qmn_quiz_link\" onclick=\"qmnSocialShare('facebook', '" . esc_js($qmn_social_media_text["facebook"]) . "', '" . esc_js($qmn_quiz_options->quiz_name) . "', '$facebook_app_id');\">Facebook</a><a class=\"mlw_qmn_quiz_link\" onclick=\"qmnSocialShare('twitter', '" . esc_js($qmn_social_media_text["twitter"]) . "', '" . esc_js($qmn_quiz_options->quiz_name) . "');\">Twitter</a><br />";
1699
- }
1700
- return apply_filters('qmn_returned_social_buttons', $social_display, $qmn_quiz_options, $qmn_array_for_variables);
1701
- }
1702
-
1703
- /**
1704
- * Send User Email
1705
- *
1706
- * Prepares the email to the user and then sends the email
1707
- *
1708
- * @deprecated 6.2.0 Use the newer QSM_Emails class instead.
1709
- * @since 4.0.0
1710
- * @param array $qmn_quiz_options The database row of the quiz
1711
- * @param array $qmn_array_for_variables The array of results for the quiz
1712
- */
1713
- public function send_user_email($qmn_quiz_options, $qmn_array_for_variables) {
1714
- add_filter('wp_mail_content_type', 'mlw_qmn_set_html_content_type');
1715
- $mlw_message = "";
1716
-
1717
- //Check if this quiz has user emails turned on
1718
- if ($qmn_quiz_options->send_user_email == "0") {
1719
-
1720
- //Make sure that the user filled in the email field
1721
- if ($qmn_array_for_variables['user_email'] != "") {
1722
-
1723
- //Prepare from email and name
1724
- $from_email_array = maybe_unserialize($qmn_quiz_options->email_from_text);
1725
- if (!isset($from_email_array["from_email"])) {
1726
- $from_email_array = array(
1727
- 'from_name' => $qmn_quiz_options->email_from_text,
1728
- 'from_email' => $qmn_quiz_options->admin_email,
1729
- 'reply_to' => 1
1730
- );
1731
- }
1732
-
1733
- if (!is_email($from_email_array["from_email"])) {
1734
- if (is_email($qmn_quiz_options->admin_email)) {
1735
- $from_email_array["from_email"] = $qmn_quiz_options->admin_email;
1736
- } else {
1737
- $from_email_array["from_email"] = get_option('admin_email ', 'test@example.com');
1738
- }
1739
- }
1740
-
1741
- //Prepare email attachments
1742
- $attachments = array();
1743
- $attachments = apply_filters('qsm_user_email_attachments', $attachments, $qmn_array_for_variables);
1744
-
1745
- if (is_serialized($qmn_quiz_options->user_email_template) && is_array(@unserialize($qmn_quiz_options->user_email_template))) {
1746
-
1747
- $mlw_user_email_array = @unserialize($qmn_quiz_options->user_email_template);
1748
-
1749
- //Cycle through emails
1750
- foreach ($mlw_user_email_array as $mlw_each) {
1751
-
1752
- //Generate Email Subject
1753
- if (!isset($mlw_each[3])) {
1754
- $mlw_each[3] = "Quiz Results For %QUIZ_NAME";
1755
- }
1756
- $mlw_each[3] = apply_filters('mlw_qmn_template_variable_results_page', $mlw_each[3], $qmn_array_for_variables);
1757
-
1758
- //Check to see if default
1759
- if ($mlw_each[0] == 0 && $mlw_each[1] == 0) {
1760
- $mlw_message = htmlspecialchars_decode($mlw_each[2], ENT_QUOTES);
1761
- $mlw_message = apply_filters('mlw_qmn_template_variable_results_page', $mlw_message, $qmn_array_for_variables);
1762
- $mlw_message = str_replace("\n", "<br>", $mlw_message);
1763
- $mlw_message = str_replace("<br/>", "<br>", $mlw_message);
1764
- $mlw_message = str_replace("<br />", "<br>", $mlw_message);
1765
- $mlw_headers = 'From: ' . $from_email_array["from_name"] . ' <' . $from_email_array["from_email"] . '>' . "\r\n";
1766
- wp_mail($qmn_array_for_variables['user_email'], $mlw_each[3], $mlw_message, $mlw_headers, $attachments);
1767
- break;
1768
- } else {
1769
-
1770
- //Check to see if this quiz uses points and check if the points earned falls in the point range for this email
1771
- if ($qmn_quiz_options->system == 1 && $qmn_array_for_variables['total_points'] >= $mlw_each[0] && $qmn_array_for_variables['total_points'] <= $mlw_each[1]) {
1772
- $mlw_message = htmlspecialchars_decode($mlw_each[2], ENT_QUOTES);
1773
- $mlw_message = apply_filters('mlw_qmn_template_variable_results_page', $mlw_message, $qmn_array_for_variables);
1774
- $mlw_message = str_replace("\n", "<br>", $mlw_message);
1775
- $mlw_message = str_replace("<br/>", "<br>", $mlw_message);
1776
- $mlw_message = str_replace("<br />", "<br>", $mlw_message);
1777
- $mlw_headers = 'From: ' . $from_email_array["from_name"] . ' <' . $from_email_array["from_email"] . '>' . "\r\n";
1778
- wp_mail($qmn_array_for_variables['user_email'], $mlw_each[3], $mlw_message, $mlw_headers, $attachments);
1779
- break;
1780
- }
1781
 
1782
- //Check to see if score fall in correct range
1783
- if ($qmn_quiz_options->system == 0 && $qmn_array_for_variables['total_score'] >= $mlw_each[0] && $qmn_array_for_variables['total_score'] <= $mlw_each[1]) {
1784
- $mlw_message = htmlspecialchars_decode($mlw_each[2], ENT_QUOTES);
1785
- $mlw_message = apply_filters('mlw_qmn_template_variable_results_page', $mlw_message, $qmn_array_for_variables);
1786
- $mlw_message = str_replace("\n", "<br>", $mlw_message);
1787
- $mlw_message = str_replace("<br/>", "<br>", $mlw_message);
1788
- $mlw_message = str_replace("<br />", "<br>", $mlw_message);
1789
- $mlw_headers = 'From: ' . $from_email_array["from_name"] . ' <' . $from_email_array["from_email"] . '>' . "\r\n";
1790
- wp_mail($qmn_array_for_variables['user_email'], $mlw_each[3], $mlw_message, $mlw_headers, $attachments);
1791
- break;
1792
- }
1793
- }
1794
- }
1795
- } else {
1796
-
1797
- //Uses older email system still which was before different emails were created.
1798
- $mlw_message = htmlspecialchars_decode($qmn_quiz_options->user_email_template, ENT_QUOTES);
1799
- $mlw_message = apply_filters('mlw_qmn_template_variable_results_page', $mlw_message, $qmn_array_for_variables);
1800
- $mlw_message = str_replace("\n", "<br>", $mlw_message);
1801
- $mlw_message = str_replace("<br/>", "<br>", $mlw_message);
1802
- $mlw_message = str_replace("<br />", "<br>", $mlw_message);
1803
- $mlw_headers = 'From: ' . $from_email_array["from_name"] . ' <' . $from_email_array["from_email"] . '>' . "\r\n";
1804
- wp_mail($qmn_array_for_variables['user_email'], "Quiz Results For " . $qmn_quiz_options->quiz_name, $mlw_message, $mlw_headers, $attachments);
1805
- }
1806
- }
1807
- }
1808
- remove_filter('wp_mail_content_type', 'mlw_qmn_set_html_content_type');
1809
- }
1810
-
1811
- /**
1812
- * Send Admin Email
1813
- *
1814
- * Prepares the email to the admin and then sends the email
1815
- *
1816
- * @deprecated 6.2.0 Use the newer QSM_Emails class instead.
1817
- * @since 4.0.0
1818
- * @param array $qmn_quiz_options The database row of the quiz
1819
- * @param arrar $qmn_array_for_variables The array of results for the quiz
1820
- */
1821
- public function send_admin_email($qmn_quiz_options, $qmn_array_for_variables) {
1822
- //Switch email type to HTML
1823
- add_filter('wp_mail_content_type', 'mlw_qmn_set_html_content_type');
1824
-
1825
- $mlw_message = "";
1826
- if ($qmn_quiz_options->send_admin_email == "0") {
1827
- if ($qmn_quiz_options->admin_email != "") {
1828
- $from_email_array = maybe_unserialize($qmn_quiz_options->email_from_text);
1829
- if (!isset($from_email_array["from_email"])) {
1830
- $from_email_array = array(
1831
- 'from_name' => $qmn_quiz_options->email_from_text,
1832
- 'from_email' => $qmn_quiz_options->admin_email,
1833
- 'reply_to' => 1
1834
- );
1835
- }
1836
-
1837
- if (!is_email($from_email_array["from_email"])) {
1838
- if (is_email($qmn_quiz_options->admin_email)) {
1839
- $from_email_array["from_email"] = $qmn_quiz_options->admin_email;
1840
- } else {
1841
- $from_email_array["from_email"] = get_option('admin_email ', 'test@example.com');
1842
- }
1843
- }
1844
-
1845
- $mlw_message = "";
1846
- $mlw_subject = "";
1847
- if (is_serialized($qmn_quiz_options->admin_email_template) && is_array(@unserialize($qmn_quiz_options->admin_email_template))) {
1848
- $mlw_admin_email_array = @unserialize($qmn_quiz_options->admin_email_template);
1849
-
1850
- //Cycle through landing pages
1851
- foreach ($mlw_admin_email_array as $mlw_each) {
1852
-
1853
- //Generate Email Subject
1854
- if (!isset($mlw_each["subject"])) {
1855
- $mlw_each["subject"] = "Quiz Results For %QUIZ_NAME";
1856
- }
1857
- $mlw_each["subject"] = apply_filters('mlw_qmn_template_variable_results_page', $mlw_each["subject"], $qmn_array_for_variables);
1858
-
1859
- //Check to see if default
1860
- if ($mlw_each["begin_score"] == 0 && $mlw_each["end_score"] == 0) {
1861
- $mlw_message = htmlspecialchars_decode($mlw_each["message"], ENT_QUOTES);
1862
- $mlw_message = apply_filters('mlw_qmn_template_variable_results_page', $mlw_message, $qmn_array_for_variables);
1863
- $mlw_message = str_replace("\n", "<br>", $mlw_message);
1864
- $mlw_message = str_replace("<br/>", "<br>", $mlw_message);
1865
- $mlw_message = str_replace("<br />", "<br>", $mlw_message);
1866
- $mlw_subject = $mlw_each["subject"];
1867
- break;
1868
- } else {
1869
- //Check to see if points fall in correct range
1870
- if ($qmn_quiz_options->system == 1 && $qmn_array_for_variables['total_points'] >= $mlw_each["begin_score"] && $qmn_array_for_variables['total_points'] <= $mlw_each["end_score"]) {
1871
- $mlw_message = htmlspecialchars_decode($mlw_each["message"], ENT_QUOTES);
1872
- $mlw_message = apply_filters('mlw_qmn_template_variable_results_page', $mlw_message, $qmn_array_for_variables);
1873
- $mlw_message = str_replace("\n", "<br>", $mlw_message);
1874
- $mlw_message = str_replace("<br/>", "<br>", $mlw_message);
1875
- $mlw_message = str_replace("<br />", "<br>", $mlw_message);
1876
- $mlw_subject = $mlw_each["subject"];
1877
- break;
1878
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1879
 
1880
- //Check to see if score fall in correct range
1881
- if ($qmn_quiz_options->system == 0 && $qmn_array_for_variables['total_score'] >= $mlw_each["begin_score"] && $qmn_array_for_variables['total_score'] <= $mlw_each["end_score"]) {
1882
- $mlw_message = htmlspecialchars_decode($mlw_each["message"], ENT_QUOTES);
1883
- $mlw_message = apply_filters('mlw_qmn_template_variable_results_page', $mlw_message, $qmn_array_for_variables);
1884
- $mlw_message = str_replace("\n", "<br>", $mlw_message);
1885
- $mlw_message = str_replace("<br/>", "<br>", $mlw_message);
1886
- $mlw_message = str_replace("<br />", "<br>", $mlw_message);
1887
- $mlw_subject = $mlw_each["subject"];
1888
- break;
1889
- }
1890
- }
1891
- }
1892
- } else {
1893
- $mlw_message = htmlspecialchars_decode($qmn_quiz_options->admin_email_template, ENT_QUOTES);
1894
- $mlw_message = apply_filters('mlw_qmn_template_variable_results_page', $mlw_message, $qmn_array_for_variables);
1895
- $mlw_message = str_replace("\n", "<br>", $mlw_message);
1896
- $mlw_message = str_replace("<br/>", "<br>", $mlw_message);
1897
- $mlw_message = str_replace("<br />", "<br>", $mlw_message);
1898
- $mlw_subject = "Quiz Results For " . $qmn_quiz_options->quiz_name;
1899
- }
1900
- }
1901
- if (get_option('mlw_advert_shows') == 'true') {
1902
- $mlw_message .= "<br>This email was generated by the Quiz And Survey Master plugin";
1903
- }
1904
- $headers = array(
1905
- 'From: ' . $from_email_array["from_name"] . ' <' . $from_email_array["from_email"] . '>'
1906
- );
1907
- if ($from_email_array["reply_to"] == 0) {
1908
- $headers[] = 'Reply-To: ' . $qmn_array_for_variables["user_name"] . " <" . $qmn_array_for_variables["user_email"] . ">";
1909
- }
1910
- $admin_emails = explode(",", $qmn_quiz_options->admin_email);
1911
- foreach ($admin_emails as $admin_email) {
1912
- if (is_email($admin_email)) {
1913
- wp_mail($admin_email, $mlw_subject, $mlw_message, $headers);
1914
- }
1915
- }
1916
- }
1917
-
1918
- //Remove HTML type for emails
1919
- remove_filter('wp_mail_content_type', 'mlw_qmn_set_html_content_type');
1920
- }
1921
-
1922
- /**
1923
- * Returns the quiz taker's IP if IP collection is enabled
1924
- *
1925
- * @since 5.3.0
1926
- * @return string The IP address or a phrase if not collected
1927
- */
1928
- private function get_user_ip() {
1929
- $ip = __('Not collected', 'quiz-master-next');
1930
- $settings = (array) get_option('qmn-settings');
1931
- $ip_collection = '0';
1932
- if (isset($settings['ip_collection'])) {
1933
- $ip_collection = $settings['ip_collection'];
1934
- }
1935
- if ('1' != $ip_collection) {
1936
- if ($_SERVER['REMOTE_ADDR']) {
1937
- $ip = $_SERVER['REMOTE_ADDR'];
1938
- } else {
1939
- $ip = __('Unknown', 'quiz-master-next');
1940
- }
1941
-
1942
- if (getenv('HTTP_CLIENT_IP'))
1943
- $ip = getenv('HTTP_CLIENT_IP');
1944
- else if (getenv('HTTP_X_FORWARDED_FOR'))
1945
- $ip = getenv('HTTP_X_FORWARDED_FOR');
1946
- else if (getenv('HTTP_X_FORWARDED'))
1947
- $ip = getenv('HTTP_X_FORWARDED');
1948
- else if (getenv('HTTP_FORWARDED_FOR'))
1949
- $ip = getenv('HTTP_FORWARDED_FOR');
1950
- else if (getenv('HTTP_FORWARDED'))
1951
- $ip = getenv('HTTP_FORWARDED');
1952
- else if (getenv('REMOTE_ADDR'))
1953
- $ip = getenv('REMOTE_ADDR');
1954
- else
1955
- $ip = $_SERVER['REMOTE_ADDR'];
1956
- }
1957
- return $ip;
1958
- }
1959
-
1960
- /**
1961
- * Determines whether a plugin is active.
1962
- *
1963
- * @since 6.4.11
1964
- *
1965
- * @param string $plugin Path to the plugin file relative to the plugins directory.
1966
- * @return bool True, if in the active plugins list. False, not in the list.
1967
- */
1968
- private function qsm_plugin_active( $plugin ){
1969
- return in_array( $plugin, (array) get_option( 'active_plugins', array() ) ) || $this->qsm_plugin_active_for_network( $plugin );
1970
- }
1971
-
1972
- /**
1973
- * Determines whether the plugin is active for the entire network.
1974
- *
1975
- * @since 6.4.11
1976
- *
1977
- * @param string $plugin Path to the plugin file relative to the plugins directory.
1978
- * @return bool True if active for the network, otherwise false.
1979
- */
1980
- private function qsm_plugin_active_for_network(){
1981
- if ( ! is_multisite() ) {
1982
  return false;
1983
  }
1984
 
1985
- $plugins = get_site_option( 'active_sitewide_plugins' );
1986
- if ( isset( $plugins[ $plugin ] ) ) {
1987
- return true;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1988
  }
1989
 
1990
- return false;
1991
- }
1992
-
1993
- /**
1994
- * Include background process files
1995
- *
1996
- * @singce 7.0
1997
- */
1998
- public function qsm_process_background_email(){
1999
- require_once plugin_dir_path( __FILE__ ) . 'class-qmn-background-process.php';
2000
- $this->qsm_background_email = new QSM_Background_Request();
2001
- }
2002
-
2003
- /**
2004
- * Convert editor text into respective shortcodes
2005
- *
2006
- * @since 7.0.2
2007
- * @param string $editor_text
2008
- */
2009
- public function qsm_convert_editor_text_to_shortcode( $editor_text ){
2010
- global $wp_embed;
2011
- $editor_text = $wp_embed->run_shortcode( $editor_text );
2012
- $editor_text = preg_replace("/\s*[a-zA-Z\/\/:\.]*youtube.com\/watch\?v=([a-zA-Z0-9\-_]+)([a-zA-Z0-9\/\*\-\_\?\&\;\%\=\.]*)/i","<iframe width=\"420\" height=\"315\" src=\"//www.youtube.com/embed/$1\" frameborder=\"0\" allowfullscreen></iframe>",$editor_text);
2013
- $allowed_html = wp_kses_allowed_html( 'post' );
2014
- return do_shortcode( wp_kses( $editor_text, $allowed_html ) );
2015
- }
2016
-
2017
- /**
2018
- * Get attachment id from attachment url
2019
- *
2020
- * @since 7.1.2
2021
- *
2022
- * @global obj $wpdb
2023
- * @param url $attachment_url
2024
- * @return int
2025
- */
2026
- public function qsm_get_attachment_id_from_url( $attachment_url = '' ) {
2027
-
2028
- global $wpdb;
2029
- $attachment_id = false;
2030
-
2031
- // If there is no url, return.
2032
- if ( '' == $attachment_url )
2033
- return;
2034
-
2035
- // Get the upload directory paths
2036
- $upload_dir_paths = wp_upload_dir();
2037
-
2038
- // Make sure the upload path base directory exists in the attachment URL, to verify that we're working with a media library image
2039
- if ( false !== strpos( $attachment_url, $upload_dir_paths['baseurl'] ) ) {
2040
-
2041
- // If this is the URL of an auto-generated thumbnail, get the URL of the original image
2042
- $attachment_url = preg_replace( '/-\d+x\d+(?=\.(jpg|jpeg|png|gif)$)/i', '', $attachment_url );
2043
-
2044
- // Remove the upload path base directory from the attachment URL
2045
- $attachment_url = str_replace( $upload_dir_paths['baseurl'] . '/', '', $attachment_url );
2046
-
2047
- // Finally, run a custom database query to get the attachment ID from the modified attachment URL
2048
- $attachment_id = $wpdb->get_var( $wpdb->prepare( "SELECT wposts.ID FROM $wpdb->posts wposts, $wpdb->postmeta wpostmeta WHERE wposts.ID = wpostmeta.post_id AND wpostmeta.meta_key = '_wp_attached_file' AND wpostmeta.meta_value = '%s' AND wposts.post_type = 'attachment'", $attachment_url ) );
2049
-
2050
- }
2051
-
2052
- return $attachment_id;
2053
- }
2054
  }
2055
 
2056
  global $qmnQuizManager;
2057
  $qmnQuizManager = new QMNQuizManager();
2058
 
2059
- add_filter('qmn_begin_shortcode', 'qmn_require_login_check', 10, 3);
2060
-
2061
- function qmn_require_login_check($display, $qmn_quiz_options, $qmn_array_for_variables) {
2062
- global $qmn_allowed_visit;
2063
- if ($qmn_quiz_options->require_log_in == 1 && !is_user_logged_in()) {
2064
- $qmn_allowed_visit = false;
2065
- if(isset($qmn_quiz_options->require_log_in_text) && $qmn_quiz_options->require_log_in_text != ''){
2066
- $mlw_message = wpautop(htmlspecialchars_decode($qmn_quiz_options->require_log_in_text, ENT_QUOTES));
2067
- }else{
2068
- $mlw_message = wpautop(htmlspecialchars_decode($qmn_quiz_options->require_log_in_text, ENT_QUOTES));
2069
- }
2070
- $mlw_message = apply_filters('mlw_qmn_template_variable_quiz_page', $mlw_message, $qmn_array_for_variables);
2071
- $mlw_message = str_replace("\n", "<br>", $mlw_message);
2072
- //$display .= do_shortcode($mlw_message);
2073
- $display .= do_shortcode($mlw_message);
2074
- $display .= wp_login_form(array('echo' => false));
2075
- }
2076
- return $display;
2077
  }
2078
 
2079
- add_filter('qmn_begin_shortcode', 'qsm_scheduled_timeframe_check', 99, 3);
2080
 
2081
  /**
2082
  * @since 7.0.0 Added the condition for start time ( end time blank ) and end time ( start time blank ).
2083
  *
2084
  * @global boolean $qmn_allowed_visit
2085
- * @param HTML $display
2086
  * @param Object $options
2087
- * @param Array $variable_data
2088
  * @return HTML This function check the time frame of quiz.
2089
  */
2090
- function qsm_scheduled_timeframe_check($display, $options, $variable_data) {
2091
- global $qmn_allowed_visit;
2092
-
2093
- $checked_pass = FALSE;
2094
- // Checks if the start and end dates have data
2095
- if (!empty($options->scheduled_time_start) && !empty($options->scheduled_time_end)) {
2096
- $start = strtotime($options->scheduled_time_start);
2097
- $end = strtotime($options->scheduled_time_end);
2098
- if( strpos( $options->scheduled_time_end, ':' ) === false || strpos( $options->scheduled_time_end, '00:00' ) !== false )
2099
- $end = strtotime($options->scheduled_time_end) + 86399;
2100
-
2101
- $current_time = strtotime( current_time( 'm/d/Y H:i' ) );
2102
- // Checks if the current timestamp is outside of scheduled timeframe
2103
- if ( $current_time < $start || $current_time > $end) {
2104
- $checked_pass = TRUE;
2105
- }
2106
- }
2107
- if ( !empty( $options->scheduled_time_start ) && empty( $options->scheduled_time_end ) ){
2108
- $start = new DateTime( $options->scheduled_time_start );
2109
- $current_datetime = new DateTime( current_time( 'm/d/Y H:i' ) );
2110
- if ( $current_datetime < $start ){
2111
- $checked_pass = TRUE;
2112
- }
2113
- }
2114
- if ( empty( $options->scheduled_time_start ) && !empty( $options->scheduled_time_end ) ){
2115
- $end = new DateTime( $options->scheduled_time_end );
2116
- $current_datetime = new DateTime( current_time( 'm/d/Y H:i' ) );
2117
- if ( $current_datetime > $end ) {
2118
- $checked_pass = TRUE;
2119
- }
2120
- }
2121
- if( $checked_pass == TRUE ){
2122
- $qmn_allowed_visit = false;
2123
- $message = wpautop(htmlspecialchars_decode($options->scheduled_timeframe_text, ENT_QUOTES));
2124
- $message = apply_filters('mlw_qmn_template_variable_quiz_page', $message, $variable_data);
2125
- $display .= str_replace("\n", "<br>", $message);
2126
- }
2127
- return $display;
 
2128
  }
2129
 
2130
- add_filter('qmn_begin_shortcode', 'qmn_total_user_tries_check', 10, 3);
2131
 
2132
  /**
2133
  * Checks if user has already reach the user limit of the quiz
2134
  *
2135
  * @since 5.0.0
2136
  * @param string $display The HTML displayed for the quiz
2137
- * @param array $qmn_quiz_options The settings for the quiz
2138
- * @param array $qmn_array_for_variables The array of data by the quiz
2139
  * @return string The altered HTML display for the quiz
2140
  */
2141
- function qmn_total_user_tries_check($display, $qmn_quiz_options, $qmn_array_for_variables) {
2142
-
2143
- global $qmn_allowed_visit;
2144
- if ($qmn_quiz_options->total_user_tries != 0) {
2145
-
2146
- // Prepares the variables
2147
- global $wpdb;
2148
- $mlw_qmn_user_try_count = 0;
2149
-
2150
- // Checks if the user is logged in. If so, check by user id. If not, check by IP.
2151
- if (is_user_logged_in()) {
2152
- $current_user = wp_get_current_user();
2153
- $mlw_qmn_user_try_count = $wpdb->get_var($wpdb->prepare("SELECT COUNT(*) FROM {$wpdb->prefix}mlw_results WHERE user=%d AND deleted=0 AND quiz_id=%d", $current_user->ID, $qmn_array_for_variables['quiz_id']));
2154
- } else {
2155
- $mlw_qmn_user_try_count = $wpdb->get_var($wpdb->prepare("SELECT COUNT(*) FROM {$wpdb->prefix}mlw_results WHERE user_ip=%s AND deleted=0 AND quiz_id=%d", $qmn_array_for_variables['user_ip'], $qmn_array_for_variables['quiz_id']));
2156
- }
2157
-
2158
- // If user has already reached the limit for this quiz
2159
- if ($mlw_qmn_user_try_count >= $qmn_quiz_options->total_user_tries) {
2160
-
2161
- // Stops the quiz and prepares entered text
2162
- $qmn_allowed_visit = false;
2163
- $mlw_message = wpautop(htmlspecialchars_decode($qmn_quiz_options->total_user_tries_text, ENT_QUOTES));
2164
- $mlw_message = apply_filters('mlw_qmn_template_variable_quiz_page', $mlw_message, $qmn_array_for_variables);
2165
- $display .= $mlw_message;
2166
- }
2167
- }
2168
- return $display;
2169
  }
2170
 
2171
- add_filter('qmn_begin_quiz', 'qmn_total_tries_check', 10, 3);
2172
-
2173
- function qmn_total_tries_check($display, $qmn_quiz_options, $qmn_array_for_variables) {
2174
- global $qmn_allowed_visit;
2175
- if ($qmn_quiz_options->limit_total_entries != 0) {
2176
- global $wpdb;
2177
- $mlw_qmn_entries_count = $wpdb->get_var($wpdb->prepare("SELECT COUNT(quiz_id) FROM {$wpdb->prefix}mlw_results WHERE deleted=0 AND quiz_id=%d", $qmn_array_for_variables['quiz_id']));
2178
- if ($mlw_qmn_entries_count >= $qmn_quiz_options->limit_total_entries) {
2179
- $mlw_message = wpautop(htmlspecialchars_decode($qmn_quiz_options->limit_total_entries_text, ENT_QUOTES));
2180
- $mlw_message = apply_filters('mlw_qmn_template_variable_quiz_page', $mlw_message, $qmn_array_for_variables);
2181
- $display .= $mlw_message;
2182
- $qmn_allowed_visit = false;
2183
- }
2184
- }
2185
- return $display;
2186
  }
2187
 
2188
- add_filter('qmn_begin_quiz', 'qmn_pagination_check', 10, 3);
2189
-
2190
- function qmn_pagination_check($display, $qmn_quiz_options, $qmn_array_for_variables) {
2191
- if ($qmn_quiz_options->pagination != 0) {
2192
- global $wpdb;
2193
- global $qmn_json_data;
2194
- $total_questions = 0;
2195
- if ($qmn_quiz_options->question_from_total != 0) {
2196
- $total_questions = $qmn_quiz_options->question_from_total;
2197
- } else {
2198
- $questions = QSM_Questions::load_questions_by_pages($qmn_quiz_options->quiz_id);
2199
- $total_questions = count($questions);
2200
- }
2201
- //$display .= "<style>.quiz_section { display: none; }</style>";
2202
-
2203
- $qmn_json_data["pagination"] = array(
2204
- 'amount' => $qmn_quiz_options->pagination,
2205
- 'section_comments' => $qmn_quiz_options->comment_section,
2206
- 'total_questions' => $total_questions,
2207
- 'previous_text' => $qmn_quiz_options->previous_button_text,
2208
- 'next_text' => $qmn_quiz_options->next_button_text
2209
- );
2210
- }
2211
- return $display;
2212
  }
2213
 
2214
- add_filter('qmn_begin_quiz_form', 'qmn_timer_check', 15, 3);
2215
 
2216
- function qmn_timer_check($display, $qmn_quiz_options, $qmn_array_for_variables) {
2217
- global $qmn_allowed_visit;
2218
- global $qmn_json_data;
2219
- if ($qmn_allowed_visit && $qmn_quiz_options->timer_limit != 0) {
2220
- $qmn_json_data["timer_limit"] = $qmn_quiz_options->timer_limit;
2221
- $display .= '<div style="display:none;" id="mlw_qmn_timer" class="mlw_qmn_timer"></div>';
2222
- }
2223
- return $display;
2224
  }
2225
 
2226
- add_filter('qmn_begin_quiz', 'qmn_update_views', 10, 3);
2227
-
2228
- function qmn_update_views($display, $qmn_quiz_options, $qmn_array_for_variables) {
2229
- global $wpdb;
2230
- $mlw_views = $qmn_quiz_options->quiz_views;
2231
- $mlw_views += 1;
2232
- $results = $wpdb->update(
2233
- $wpdb->prefix . "mlw_quizzes", array(
2234
- 'quiz_views' => $mlw_views
2235
- ), array('quiz_id' => $qmn_array_for_variables["quiz_id"]), array(
2236
- '%d'
2237
- ), array('%d')
2238
- );
2239
- return $display;
 
 
 
 
2240
  }
2241
 
2242
- add_filter('qmn_begin_results', 'qmn_update_taken', 10, 3);
2243
-
2244
- function qmn_update_taken($display, $qmn_quiz_options, $qmn_array_for_variables) {
2245
- global $wpdb;
2246
- $mlw_taken = $qmn_quiz_options->quiz_taken;
2247
- $mlw_taken += 1;
2248
- $results = $wpdb->update(
2249
- $wpdb->prefix . "mlw_quizzes", array(
2250
- 'quiz_taken' => $mlw_taken
2251
- ), array('quiz_id' => $qmn_array_for_variables["quiz_id"]), array(
2252
- '%d'
2253
- ), array('%d')
2254
- );
2255
- return $display;
 
 
 
 
2256
  }
2257
 
2258
  /*
@@ -2261,16 +2323,19 @@ function qmn_update_taken($display, $qmn_quiz_options, $qmn_array_for_variables)
2261
 
2262
  function mlw_qmn_set_html_content_type() {
2263
 
2264
- return 'text/html';
2265
  }
2266
 
2267
  function qsm_time_in_milliseconds() {
2268
- return round(microtime(true) * 1000);
2269
  }
2270
 
2271
- add_filter( 'wp_video_extensions', function( $exts ) {
2272
- $exts[] = 'mov';
2273
- $exts[] = 'avi';
2274
- $exts[] = 'wmv';
2275
- return $exts;
2276
- });
 
 
 
4
  *
5
  * @package QSM
6
  */
7
+ if ( ! defined( 'ABSPATH' ) ) {
8
+ exit;
9
  }
10
 
11
  /**
15
  */
16
  class QMNQuizManager {
17
 
18
+ protected $qsm_background_email;
19
+ /**
20
+ * Main Construct Function
21
+ *
22
+ * Call functions within class
23
+ *
24
+ * @since 4.0.0
25
+ * @uses QMNQuizManager::add_hooks() Adds actions to hooks and filters
26
+ * @return void
27
+ */
28
+ public function __construct() {
29
+ $this->add_hooks();
30
+ }
31
+
32
+ /**
33
+ * Add Hooks
34
+ *
35
+ * Adds functions to relavent hooks and filters
36
+ *
37
+ * @since 4.0.0
38
+ * @return void
39
+ */
40
+ public function add_hooks() {
41
+ add_shortcode( 'mlw_quizmaster', array( $this, 'display_shortcode' ) );
42
+ add_shortcode( 'qsm', array( $this, 'display_shortcode' ) );
43
+ add_shortcode( 'qsm_result', array( $this, 'shortcode_display_result' ) );
44
+ add_action( 'wp_ajax_qmn_process_quiz', array( $this, 'ajax_submit_results' ) );
45
+ add_action( 'wp_ajax_nopriv_qmn_process_quiz', array( $this, 'ajax_submit_results' ) );
46
+ add_action( 'wp_ajax_qsm_get_quiz_to_reload', array( $this, 'qsm_get_quiz_to_reload' ) );
47
+ add_action( 'wp_ajax_nopriv_qsm_get_quiz_to_reload', array( $this, 'qsm_get_quiz_to_reload' ) );
48
+ add_action( 'wp_ajax_qsm_get_question_quick_result', array( $this, 'qsm_get_question_quick_result' ) );
49
+ add_action( 'wp_ajax_nopriv_qsm_get_question_quick_result', array( $this, 'qsm_get_question_quick_result' ) );
50
+ // Upload file of file upload question type
51
+ add_action( 'wp_ajax_qsm_upload_image_fd_question', array( $this, 'qsm_upload_image_fd_question' ) );
52
+ add_action( 'wp_ajax_nopriv_qsm_upload_image_fd_question', array( $this, 'qsm_upload_image_fd_question' ) );
53
+
54
+ // remove file of file upload question type
55
+ add_action( 'wp_ajax_qsm_remove_file_fd_question', array( $this, 'qsm_remove_file_fd_question' ) );
56
+ add_action( 'wp_ajax_nopriv_qsm_remove_file_fd_question', array( $this, 'qsm_remove_file_fd_question' ) );
57
+
58
+ add_action( 'init', array( $this, 'qsm_process_background_email' ) );
59
+ }
60
+
61
+ /**
62
+ * @version 6.3.7
63
+ * Upload file to server
64
+ */
65
+ public function qsm_upload_image_fd_question() {
66
+ global $mlwQuizMasterNext;
67
+ $question_id = isset( $_POST['question_id'] ) ? sanitize_text_field( $_POST['question_id'] ) : 0;
68
+ $file_upload_type = $mlwQuizMasterNext->pluginHelper->get_question_setting( $question_id, 'file_upload_type' );
69
+ $file_upload_limit = $mlwQuizMasterNext->pluginHelper->get_question_setting( $question_id, 'file_upload_limit' );
70
+ $mimes = array();
71
+ if ( $file_upload_type ) {
72
+ $file_type_exp = explode( ',', $file_upload_type );
73
+ foreach ( $file_type_exp as $value ) {
74
+ $value = trim( $value );
75
+ if ( $value == 'image' ) {
76
+ $mimes[] = 'image/jpeg';
77
+ $mimes[] = 'image/png';
78
+ $mimes[] = 'image/x-icon';
79
+ $mimes[] = 'image/gif';
80
+ } elseif ( $value == 'doc' ) {
81
+ $mimes[] = 'application/msword';
82
+ $mimes[] = 'application/vnd.openxmlformats-officedocument.wordprocessingml.document';
83
+ } elseif ( $value == 'excel' ) {
84
+ $mimes[] = 'application/excel, application/vnd.ms-excel, application/x-excel, application/x-msexcel';
85
+ $mimes[] = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';
86
+ } elseif ( empty( $value ) ) {
87
+ // don't add blank mime type
88
+ } else {
89
+ $mimes[] = $value;
90
+ }
91
+ }
92
+ }
93
+ $json = array();
94
+ $file_name = sanitize_file_name( $_FILES['file']['name'] );
95
+ $validate_file = wp_check_filetype( $file_name );
96
+ if ( isset( $validate_file['type'] ) && $validate_file['type'] != false && in_array( $validate_file['type'], $mimes ) ) {
97
+ if ( $_FILES['file']['size'] >= $file_upload_limit * 1024 * 1024 ) {
98
+ $json['type'] = 'error';
99
+ $json['message'] = __( 'File is too large. File must be less than ', 'quiz-master-next' ) . $file_upload_limit . ' MB';
100
+ echo json_encode( $json );
101
+ exit;
102
+ }
103
+ $upload_dir = wp_upload_dir();
104
+ $datafile = $_FILES['file']['tmp_name'];
105
+ // $file_name = $_FILES["file"]["name"];
106
+ $extension = pathinfo( $file_name, PATHINFO_EXTENSION );
107
+ // remove white space between file name
108
+ $file_name = str_replace( ' ', '-', $file_name );
109
+ $rawBaseName = 'qsmfileupload_' . md5( date( 'Y-m-d H:i:s' ) ) . '_' . pathinfo( $file_name, PATHINFO_FILENAME );
110
+ $new_fname = $rawBaseName . '.' . $extension;
111
+ $file = $upload_dir['path'] . '/' . $new_fname;
112
+ $file_url = $upload_dir['url'] . '/' . $new_fname;
113
+ $counter = 1;
114
+ if ( file_exists( $file ) ) {
115
+ while ( file_exists( $file ) ) {
116
+ $new_fname = $rawBaseName . '-' . $counter . '.' . $extension;
117
+ $file = $upload_dir['path'] . '/' . $new_fname;
118
+ $file_url = $upload_dir['url'] . '/' . $new_fname;
119
+ $counter++;
120
+ }
121
+ }
122
+ if ( ! move_uploaded_file( $datafile, $file ) ) {
123
+ $json['type'] = 'error';
124
+ $json['message'] = __( 'File not uploaded', 'quiz-master-next' );
125
+ echo json_encode( $json );
126
+ } else {
127
+ // Prepare an array of post data for the attachment.
128
+ $attachment = array(
129
+ 'guid' => $upload_dir['url'] . '/' . basename( $file ),
130
+ 'post_mime_type' => $validate_file['type'],
131
+ 'post_title' => preg_replace( '/\.[^.]+$/', '', basename( $file_name ) ),
132
+ 'post_content' => '',
133
+ 'post_status' => 'inherit',
134
+ );
135
+ // Insert the attachment.
136
+ $attach_id = wp_insert_attachment( $attachment, $file, 0 );
137
+ if ( $attach_id ) {
138
+ require_once ABSPATH . 'wp-admin/includes/image.php';
139
+ $attach_data = wp_generate_attachment_metadata( $attach_id, $file );
140
+ wp_update_attachment_metadata( $attach_id, $attach_data );
141
+ }
142
+ $json['type'] = 'success';
143
+ $json['message'] = __( 'File uploaded successfully', 'quiz-master-next' );
144
+ $json['file_url'] = $file_url;
145
+ $json['file_path'] = $new_fname;
146
+ echo json_encode( $json );
147
+ }
148
+ } else {
149
+ $json['type'] = 'error';
150
+ $json['message'] = __( 'File type is not supported', 'quiz-master-next' );
151
+ echo json_encode( $json );
152
+ }
153
+ exit;
154
+ }
155
+
156
+ /**
157
+ * @since 6.3.7
158
+ * Remove the uploaded image
159
+ */
160
+ public function qsm_remove_file_fd_question() {
161
+ $file_url = isset( $_POST['file_url'] ) ? sanitize_text_field( $_POST['file_url'] ) : '';
162
+ $upload_dir = wp_upload_dir();
163
+ $uploaded_path = $upload_dir['path'];
164
+ if ( $file_url && stristr( $file_url, 'qsmfileupload_' ) && file_exists( $uploaded_path . '/' . $file_url ) ) {
165
+ $attachment_url = $upload_dir['url'] . '/' . $file_url;
166
+ $attachment_id = $this->qsm_get_attachment_id_from_url( $attachment_url );
167
+ wp_delete_file( $uploaded_path . '/' . $file_url );
168
+ wp_delete_attachment( $attachment_id );
169
+ $json['type'] = 'success';
170
+ $json['message'] = __( 'File removed successfully', 'quiz-master-next' );
171
+ echo json_encode( $json );
172
+ exit;
173
+ }
174
+ $json['type'] = 'error';
175
+ $json['message'] = __( 'File not removed', 'quiz-master-next' );
176
+ echo json_encode( $json );
177
+ exit;
178
+ }
179
+
180
+
181
+ /**
182
+ * @version 6.3.2
183
+ * Get question quick result
184
+ */
185
+ public function qsm_get_question_quick_result() {
186
+ global $wpdb;
187
+ $question_id = isset( $_POST['question_id'] ) ? intval( $_POST['question_id'] ) : 0;
188
+ $answer = isset( $_POST['answer'] ) ? stripslashes_deep( $_POST['answer'] ) : '';
189
+ $question_array = $wpdb->get_row( $wpdb->prepare( "SELECT answer_array, question_answer_info FROM {$wpdb->prefix}mlw_questions WHERE question_id = (%d)", $question_id ), 'ARRAY_A' );
190
+ $answer_array = unserialize( $question_array['answer_array'] );
191
+ $correct_info_text = isset( $question_array['question_answer_info'] ) ? html_entity_decode( $question_array['question_answer_info'] ) : '';
192
+ $show_correct_info = isset( $_POST['show_correct_info'] ) ? sanitize_text_field( $_POST['show_correct_info'] ) : 0;
193
+ $got_ans = false;
194
+ $correct_answer = false;
195
+ if ( $answer_array && $got_ans === false ) {
196
+ foreach ( $answer_array as $key => $value ) {
197
+ if ( esc_html( $value[0] ) == esc_html( $answer ) && $value[2] == 1 ) {
198
+ $got_ans = true;
199
+ $correct_answer = true;
200
+ break;
201
+ }
202
+ }
203
+ }
204
+ if ( $show_correct_info == 2 ) {
205
+ $got_ans = true;
206
+ }
207
+ echo wp_json_encode(
208
+ array(
209
+ 'success' => $correct_answer ? 'correct' : 'incorrect',
210
+ 'message' => $show_correct_info && $got_ans ? '<b>' . __( 'Correct Info: ', 'quiz-master-next' ) . '</b>' . do_shortcode( $correct_info_text ) : '',
211
+ )
212
+ );
213
+ wp_die();
214
+ }
215
+
216
+ /**
217
+ * Generates Content For Quiz Shortcode
218
+ *
219
+ * Generates the content for the [mlw_quizmaster] shortcode
220
+ *
221
+ * @since 4.0.0
222
+ * @param array $atts The attributes passed from the shortcode.
223
+ * @uses QMNQuizManager:load_questions() Loads questions
224
+ * @uses QMNQuizManager:create_answer_array() Prepares answers
225
+ * @uses QMNQuizManager:display_quiz() Generates and prepares quiz page
226
+ * @uses QMNQuizManager:display_results() Generates and prepares results page
227
+ * @return string The content for the shortcode
228
+ */
229
+ public function display_shortcode( $atts ) {
230
+ extract(
231
+ shortcode_atts(
232
+ array(
233
+ 'quiz' => 0,
234
+ 'question_amount' => 0,
235
+ ),
236
+ $atts
237
+ )
238
+ );
239
+
240
+ ob_start();
241
+ if ( isset( $_GET['result_id'] ) && $_GET['result_id'] != '' ) {
242
+ global $wpdb;
243
+ global $mlwQuizMasterNext;
244
+ wp_enqueue_style( 'qmn_quiz_common_style', plugins_url( '../../css/common.css', __FILE__ ) );
245
+ wp_enqueue_style( 'dashicons' );
246
+ wp_enqueue_script( 'jquery' );
247
+ wp_enqueue_script( 'jquery-ui-tooltip' );
248
+ wp_enqueue_script( 'qsm_quiz', plugins_url( '../../js/qsm-quiz.js', __FILE__ ), array( 'wp-util', 'underscore', 'jquery', 'jquery-ui-tooltip' ), $mlwQuizMasterNext->version );
249
+ wp_enqueue_script( 'math_jax', '//cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.2/MathJax.js?config=TeX-MML-AM_CHTML' );
250
+ $result_unique_id = sanitize_text_field( $_GET['result_id'] );
251
+ $query = $wpdb->prepare( "SELECT result_id FROM {$wpdb->prefix}mlw_results WHERE unique_id = %s", $result_unique_id );
252
+ $result = $wpdb->get_row( $query, ARRAY_A );
253
+ if ( ! empty( $result ) && isset( $result['result_id'] ) ) {
254
+ $result_id = $result['result_id'];
255
+ $return_display = do_shortcode( '[qsm_result id="' . $result_id . '"]' );
256
+ $return_display = str_replace( '%FB_RESULT_ID%', $result_unique_id, $return_display );
257
+ } else {
258
+ $return_display = 'Result id is wrong!';
259
+ }
260
+ $return_display .= ob_get_clean();
261
+ } else {
262
+ global $wpdb;
263
+ global $mlwQuizMasterNext;
264
+ global $qmn_allowed_visit;
265
+ global $qmn_json_data;
266
+ $qmn_json_data = array();
267
+ $qmn_allowed_visit = true;
268
+ $success = $mlwQuizMasterNext->pluginHelper->prepare_quiz( $quiz );
269
+ if ( false === $success ) {
270
+ return __( 'It appears that this quiz is not set up correctly', 'quiz-master-next' );
271
+ }
272
+ $question_amount = intval( $question_amount );
273
+
274
+ // Legacy variable.
275
+ global $mlw_qmn_quiz;
276
+ $mlw_qmn_quiz = $quiz;
277
+
278
+ $return_display = '';
279
+ $qmn_quiz_options = $mlwQuizMasterNext->quiz_settings->get_quiz_options();
280
+
281
+ // If quiz options isn't found, stop function.
282
+ if ( is_null( $qmn_quiz_options ) || empty( $qmn_quiz_options->quiz_name ) ) {
283
+ return __( 'It appears that this quiz is not set up correctly', 'quiz-master-next' );
284
+ }
285
+
286
+ // Loads Quiz Template.
287
+ // The quiz_stye is misspelled because it has always been misspelled and fixing it would break many sites :(.
288
+ if ( 'default' == $qmn_quiz_options->theme_selected ) {
289
+ $return_display .= '<style type="text/css">' . htmlspecialchars_decode( $qmn_quiz_options->quiz_stye ) . '</style>';
290
+ wp_enqueue_style( 'qmn_quiz_style', plugins_url( '../../css/qmn_quiz.css', __FILE__ ) );
291
+ } else {
292
+ $registered_template = $mlwQuizMasterNext->pluginHelper->get_quiz_templates( $qmn_quiz_options->theme_selected );
293
+ // Check direct file first, then check templates folder in plugin, then check templates file in theme.
294
+ // If all fails, then load custom styling instead.
295
+ if ( $registered_template && file_exists( $registered_template['path'] ) ) {
296
+ wp_enqueue_style( 'qmn_quiz_template', $registered_template['path'], array(), $mlwQuizMasterNext->version );
297
+ } elseif ( $registered_template && file_exists( plugin_dir_path( __FILE__ ) . '../../templates/' . $registered_template['path'] ) ) {
298
+ wp_enqueue_style( 'qmn_quiz_template', plugins_url( '../../templates/' . $registered_template['path'], __FILE__ ), array(), $mlwQuizMasterNext->version );
299
+ } elseif ( $registered_template && file_exists( get_stylesheet_directory_uri() . '/templates/' . $registered_template['path'] ) ) {
300
+ wp_enqueue_style( 'qmn_quiz_template', get_stylesheet_directory_uri() . '/templates/' . $registered_template['path'], array(), $mlwQuizMasterNext->version );
301
+ } else {
302
+ echo "<style type='text/css'>{$qmn_quiz_options->quiz_stye}</style>";
303
+ }
304
+ }
305
+ wp_enqueue_style( 'qmn_quiz_animation_style', plugins_url( '../../css/animate.css', __FILE__ ) );
306
+ wp_enqueue_style( 'qmn_quiz_common_style', plugins_url( '../../css/common.css', __FILE__ ) );
307
+ wp_enqueue_style( 'dashicons' );
308
+
309
+ // Starts to prepare variable array for filters.
310
+ $qmn_array_for_variables = array(
311
+ 'quiz_id' => $qmn_quiz_options->quiz_id,
312
+ 'quiz_name' => $qmn_quiz_options->quiz_name,
313
+ 'quiz_system' => $qmn_quiz_options->system,
314
+ 'user_ip' => $this->get_user_ip(),
315
+ );
316
+
317
+ $return_display .= '<script>
318
  if (window.qmn_quiz_data === undefined) {
319
  window.qmn_quiz_data = new Object();
320
  }
321
+ </script>';
322
+ $qpages = array();
323
+ $qpages_arr = $mlwQuizMasterNext->pluginHelper->get_quiz_setting( 'qpages', array() );
324
+ if ( ! empty( $qpages_arr ) ) {
325
+ foreach ( $qpages_arr as $key => $qpage ) {
326
+ unset( $qpage['questions'] );
327
+ $qpages[ $qpage['id'] ] = $qpage;
328
  }
329
  }
330
+ $qmn_json_data = array(
331
+ 'quiz_id' => $qmn_array_for_variables['quiz_id'],
332
+ 'quiz_name' => $qmn_array_for_variables['quiz_name'],
333
+ 'disable_answer' => $qmn_quiz_options->disable_answer_onselect,
334
+ 'ajax_show_correct' => $qmn_quiz_options->ajax_show_correct,
335
+ 'progress_bar' => $qmn_quiz_options->progress_bar,
336
+ 'contact_info_location' => $qmn_quiz_options->contact_info_location,
337
+ 'qpages' => $qpages,
338
+ 'skip_validation_time_expire' => $qmn_quiz_options->skip_validation_time_expire,
339
+ 'timer_limit_val' => $qmn_quiz_options->timer_limit,
340
  'disable_scroll_next_previous_click' => $qmn_quiz_options->disable_scroll_next_previous_click,
341
+ 'enable_result_after_timer_end' => isset( $qmn_quiz_options->enable_result_after_timer_end ) ? $qmn_quiz_options->enable_result_after_timer_end : '',
342
+ 'enable_quick_result_mc' => isset( $qmn_quiz_options->enable_quick_result_mc ) ? $qmn_quiz_options->enable_quick_result_mc : '',
343
+ 'end_quiz_if_wrong' => isset( $qmn_quiz_options->end_quiz_if_wrong ) ? $qmn_quiz_options->end_quiz_if_wrong : '',
344
+ 'form_disable_autofill' => isset( $qmn_quiz_options->form_disable_autofill ) ? $qmn_quiz_options->form_disable_autofill : '',
345
+ 'enable_quick_correct_answer_info' => isset( $qmn_quiz_options->enable_quick_correct_answer_info ) ? $qmn_quiz_options->enable_quick_correct_answer_info : 0,
346
+ 'quick_result_correct_answer_text' => $qmn_quiz_options->quick_result_correct_answer_text,
347
+ 'quick_result_wrong_answer_text' => $qmn_quiz_options->quick_result_wrong_answer_text,
348
  );
349
 
350
+ $return_display = apply_filters( 'qmn_begin_shortcode', $return_display, $qmn_quiz_options, $qmn_array_for_variables );
351
 
352
+ // Checks if we should be showing quiz or results page.
353
+ if ( $qmn_allowed_visit && ! isset( $_POST['complete_quiz'] ) && ! empty( $qmn_quiz_options->quiz_name ) ) {
354
+ $return_display .= $this->display_quiz( $qmn_quiz_options, $qmn_array_for_variables, $question_amount );
355
+ } elseif ( isset( $_POST['complete_quiz'] ) && 'confirmation' == $_POST['complete_quiz'] && $_POST['qmn_quiz_id'] == $qmn_array_for_variables['quiz_id'] ) {
356
+ $return_display .= $this->display_results( $qmn_quiz_options, $qmn_array_for_variables );
357
+ }
358
 
359
+ $qmn_filtered_json = apply_filters( 'qmn_json_data', $qmn_json_data, $qmn_quiz_options, $qmn_array_for_variables );
360
 
361
+ $return_display .= '<script>
362
+ window.qmn_quiz_data["' . $qmn_json_data['quiz_id'] . '"] = ' . json_encode( $qmn_filtered_json ) . '
363
  </script>';
364
 
365
+ $return_display .= ob_get_clean();
366
+ $return_display = apply_filters( 'qmn_end_shortcode', $return_display, $qmn_quiz_options, $qmn_array_for_variables );
367
+ }
368
+ return $return_display;
369
+ }
370
+
371
+ public function shortcode_display_result( $atts ) {
372
+ extract(
373
+ shortcode_atts(
374
+ array(
375
+ 'id' => 0,
376
+ ),
377
+ $atts
378
+ )
379
+ );
380
+ ob_start();
381
+ if ( $id == 0 ) {
382
+ $id = (int) isset( $_GET['result_id'] ) ? sanitize_text_field( $_GET['result_id'] ) : 0;
383
+ }
384
+ if ( $id && is_numeric( $id ) ) {
385
+ global $wpdb;
386
+ $result_data = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}mlw_results WHERE result_id = %d", $id ), ARRAY_A );
387
+ if ( $result_data ) {
388
+ wp_enqueue_style( 'qmn_quiz_common_style', plugins_url( '../../css/common.css', __FILE__ ) );
389
+ wp_enqueue_style( 'dashicons' );
390
+ wp_enqueue_script( 'math_jax', '//cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.2/MathJax.js?config=TeX-MML-AM_CHTML' );
391
+ $quiz_result = unserialize( $result_data['quiz_results'] );
392
+ $response_data = array(
393
+ 'quiz_id' => $result_data['quiz_id'],
394
+ 'quiz_name' => $result_data['quiz_name'],
395
+ 'quiz_system' => $result_data['quiz_system'],
396
+ 'quiz_payment_id' => '',
397
+ 'user_ip' => $result_data['user_ip'],
398
+ 'user_name' => $result_data['name'],
399
+ 'user_business' => $result_data['business'],
400
+ 'user_email' => $result_data['email'],
401
+ 'user_phone' => $result_data['phone'],
402
+ 'user_id' => $result_data['user'],
403
+ 'timer' => 0,
404
+ 'time_taken' => $result_data['time_taken'],
405
+ 'contact' => $quiz_result['contact'],
406
+ 'total_points' => $result_data['point_score'],
407
+ 'total_score' => $result_data['correct_score'],
408
+ 'total_correct' => $result_data['correct'],
409
+ 'total_questions' => $result_data['total'],
410
+ 'question_answers_array' => $quiz_result[1],
411
+ 'comments' => '',
412
+ );
413
+ $data = QSM_Results_Pages::generate_pages( $response_data );
414
+ echo htmlspecialchars_decode( $data['display'] );
415
+ } else {
416
+ echo _e( 'Invalid result id!', 'quiz-master-next' );
417
+ }
418
+ } else {
419
+ echo _e( 'Invalid result id!', 'quiz-master-next' );
420
+ }
421
+ $content = ob_get_clean();
422
+ return $content;
423
+ }
424
+
425
+ /**
426
+ * Loads Questions
427
+ *
428
+ * Retrieves the questions from the database
429
+ *
430
+ * @since 4.0.0
431
+ * @param int $quiz_id The id for the quiz.
432
+ * @param array $quiz_options The database row for the quiz.
433
+ * @param bool $is_quiz_page If the page being loaded is the quiz page or not.
434
+ * @param int $question_amount The amount of questions entered using the shortcode attribute.
435
+ * @return array The questions for the quiz
436
+ * @deprecated 5.2.0 Use new class: QSM_Questions instead
437
+ */
438
+ public function load_questions( $quiz_id, $quiz_options, $is_quiz_page, $question_amount = 0 ) {
439
+
440
+ // Prepare variables.
441
+ global $wpdb;
442
+ global $mlwQuizMasterNext;
443
+ $questions = array();
444
+ $order_by_sql = 'ORDER BY question_order ASC';
445
+ $limit_sql = '';
446
+
447
+ // Checks if the questions should be randomized.
448
  $cat_query = '';
449
+ if ( 1 == $quiz_options->randomness_order || 2 == $quiz_options->randomness_order ) {
450
+ $order_by_sql = 'ORDER BY rand()';
451
+ $categories = isset( $quiz_options->randon_category ) ? $quiz_options->randon_category : '';
452
+ if ( $categories ) {
453
+ $exploded_arr = explode( ',', $quiz_options->randon_category );
454
+ $cat_str = "'" . implode( "', '", $exploded_arr ) . "'";
455
+ $cat_query = " AND category IN ( $cat_str ) ";
456
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
457
  }
458
+
459
+ // Check if we should load all questions or only a selcted amount.
460
+ if ( $is_quiz_page && ( 0 != $quiz_options->question_from_total || 0 !== $question_amount ) ) {
461
+ if ( 0 !== $question_amount ) {
462
+ $limit_sql = " LIMIT $question_amount";
463
+ } else {
464
+ $limit_sql = ' LIMIT ' . intval( $quiz_options->question_from_total );
465
+ }
466
+ }
467
+
468
+ // If using newer pages system from 5.2.
469
+ $pages = $mlwQuizMasterNext->pluginHelper->get_quiz_setting( 'pages', array() );
470
+ // Get all question IDs needed.
471
+ $total_pages = count( $pages );
472
+ if ( $total_pages > 0 ) {
473
+ for ( $i = 0; $i < $total_pages; $i++ ) {
474
+ foreach ( $pages[ $i ] as $question ) {
475
+ $question_ids[] = intval( $question );
476
+ }
477
+ }
478
+ $question_ids = apply_filters( 'qsm_load_questions_ids', $question_ids, $quiz_id, $quiz_options );
479
+ $question_sql = implode( ', ', $question_ids );
480
+ $query = $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}mlw_questions WHERE question_id IN (%1s) %2s %3s %4s", $question_sql, $cat_query, $order_by_sql, $limit_sql );
481
+ $questions = $wpdb->get_results( stripslashes( $query ) );
482
+
483
+ // If we are not using randomization, we need to put the questions in the order of the new question editor.
484
+ // If a user has saved the pages in the question editor but still uses the older pagination options
485
+ // Then they will make it here. So, we need to order the questions based on the new editor.
486
+ if ( 1 != $quiz_options->randomness_order && 2 != $quiz_options->randomness_order ) {
487
+ $ordered_questions = array();
488
+ foreach ( $questions as $question ) {
489
+ $key = array_search( $question->question_id, $question_ids );
490
+ if ( false !== $key ) {
491
+ $ordered_questions[ $key ] = $question;
492
+ }
493
+ }
494
+ ksort( $ordered_questions );
495
+ $questions = $ordered_questions;
496
+ }
497
+ } else {
498
+ $question_ids = apply_filters( 'qsm_load_questions_ids', array(), $quiz_id, $quiz_options );
499
+ $question_sql = '';
500
+ if ( ! empty( $question_ids ) ) {
501
+ $qids = implode( ', ', $question_ids );
502
+ $question_sql = " AND question_id IN ($qids) ";
503
+ }
504
+ $questions = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}mlw_questions WHERE quiz_id=%d AND deleted=0 %1s %2s %3s", $quiz_id, $question_sql, $order_by_sql, $limit_sql ) );
505
+ }
506
+ $questions = apply_filters( 'qsm_load_questions_filter', $questions, $quiz_id, $quiz_options );
507
+ // Returns an array of all the loaded questions.
508
+ return $questions;
509
+ }
510
+
511
+ /**
512
+ * Prepares Answers
513
+ *
514
+ * Prepares or creates the answer array for the quiz
515
+ *
516
+ * @since 4.0.0
517
+ * @param array $questions The questions for the quiz.
518
+ * @param bool $is_ajax Pass true if this is an ajax call.
519
+ * @return array The answers for the quiz
520
+ * @deprecated 5.2.0 Use new class: QSM_Questions instead
521
+ */
522
+ public function create_answer_array( $questions, $is_ajax = false ) {
523
+
524
+ // Load and prepare answer arrays.
525
+ $mlw_qmn_answer_arrays = array();
526
+ $question_list = array();
527
+ foreach ( $questions as $mlw_question_info ) {
528
+ $question_list[ $mlw_question_info->question_id ] = get_object_vars( $mlw_question_info );
529
+ if ( is_serialized( $mlw_question_info->answer_array ) && is_array( @unserialize( $mlw_question_info->answer_array ) ) ) {
530
+ $mlw_qmn_answer_array_each = @unserialize( $mlw_question_info->answer_array );
531
+ $mlw_qmn_answer_arrays[ $mlw_question_info->question_id ] = $mlw_qmn_answer_array_each;
532
+ $question_list[ $mlw_question_info->question_id ]['answers'] = $mlw_qmn_answer_array_each;
533
+ } else {
534
+ $mlw_answer_array_correct = array( 0, 0, 0, 0, 0, 0 );
535
+ $mlw_answer_array_correct[ $mlw_question_info->correct_answer - 1 ] = 1;
536
+ $mlw_qmn_answer_arrays[ $mlw_question_info->question_id ] = array(
537
+ array( $mlw_question_info->answer_one, $mlw_question_info->answer_one_points, $mlw_answer_array_correct[0] ),
538
+ array( $mlw_question_info->answer_two, $mlw_question_info->answer_two_points, $mlw_answer_array_correct[1] ),
539
+ array( $mlw_question_info->answer_three, $mlw_question_info->answer_three_points, $mlw_answer_array_correct[2] ),
540
+ array( $mlw_question_info->answer_four, $mlw_question_info->answer_four_points, $mlw_answer_array_correct[3] ),
541
+ array( $mlw_question_info->answer_five, $mlw_question_info->answer_five_points, $mlw_answer_array_correct[4] ),
542
+ array( $mlw_question_info->answer_six, $mlw_question_info->answer_six_points, $mlw_answer_array_correct[5] ),
543
+ );
544
+ $question_list[ $mlw_question_info->question_id ]['answers'] = $mlw_qmn_answer_arrays[ $mlw_question_info->question_id ];
545
+ }
546
+ }
547
+ if ( ! $is_ajax ) {
548
+ global $qmn_json_data;
549
+ $qmn_json_data['question_list'] = $question_list;
550
+ }
551
+ return $mlw_qmn_answer_arrays;
552
+ }
553
+
554
+ /**
555
+ * Generates Content Quiz Page
556
+ *
557
+ * Generates the content for the quiz page part of the shortcode
558
+ *
559
+ * @since 4.0.0
560
+ * @param array $options The database row of the quiz.
561
+ * @param array $quiz_data The array of results for the quiz.
562
+ * @param int $question_amount The number of questions to load for quiz.
563
+ * @uses QMNQuizManager:display_begin_section() Creates display for beginning section
564
+ * @uses QMNQuizManager:display_questions() Creates display for questions
565
+ * @uses QMNQuizManager:display_comment_section() Creates display for comment section
566
+ * @uses QMNQuizManager:display_end_section() Creates display for end section
567
+ * @return string The content for the quiz page section
568
+ */
569
+ public function display_quiz( $options, $quiz_data, $question_amount ) {
570
+
571
+ global $qmn_allowed_visit;
572
+ global $mlwQuizMasterNext;
573
+ $quiz_display = '';
574
+ $quiz_display = apply_filters( 'qmn_begin_quiz', $quiz_display, $options, $quiz_data );
575
+ if ( ! $qmn_allowed_visit ) {
576
+ return $quiz_display;
577
+ }
578
+ wp_enqueue_script( 'json2' );
579
+ wp_enqueue_script( 'jquery' );
580
+ wp_enqueue_script( 'jquery-ui-core' );
581
+ wp_enqueue_script( 'jquery-ui-tooltip' );
582
+ wp_enqueue_style( 'jquery-redmond-theme', plugins_url( '../../css/jquery-ui.css', __FILE__ ) );
583
+
584
+ global $qmn_json_data;
585
+ $qmn_json_data['error_messages'] = array(
586
+ 'email' => $options->email_error_text,
587
+ 'number' => $options->number_error_text,
588
+ 'incorrect' => $options->incorrect_error_text,
589
+ 'empty' => $options->empty_error_text,
590
+ );
591
+
592
+ wp_enqueue_script( 'progress-bar', plugins_url( '../../js/progressbar.min.js', __FILE__ ) );
593
+ wp_enqueue_script( 'jquery-ui-slider-js', plugins_url( '../../js/jquery-ui.js', __FILE__ ) );
594
+ wp_enqueue_script( 'jquery-ui-slider-rtl-js', plugins_url( '../../js/jquery.ui.slider-rtl.js', __FILE__ ) );
595
+ wp_enqueue_style( 'jquery-ui-slider-rtl-css', plugins_url( '../../css/jquery.ui.slider-rtl.css', __FILE__ ) );
596
+ wp_enqueue_script( 'jqueryui-touch-js', '//cdnjs.cloudflare.com/ajax/libs/jqueryui-touch-punch/0.2.3/jquery.ui.touch-punch.min.js' );
597
+ wp_enqueue_style( 'qsm_model_css', plugins_url( '../../css/qsm-admin.css', __FILE__ ) );
598
+ wp_enqueue_script( 'qsm_model_js', plugins_url( '../../js/micromodal.min.js', __FILE__ ) );
599
+ wp_enqueue_script( 'qsm_quiz', plugins_url( '../../js/qsm-quiz.js', __FILE__ ), array( 'wp-util', 'underscore', 'jquery', 'jquery-ui-tooltip', 'progress-bar' ), $mlwQuizMasterNext->version );
600
+ wp_localize_script(
601
+ 'qsm_quiz',
602
+ 'qmn_ajax_object',
603
+ array(
604
+ 'ajaxurl' => admin_url( 'admin-ajax.php' ),
605
+ 'multicheckbox_limit_reach' => __( 'Limit of choice is reached.', 'quiz-master-next' ),
606
+ 'out_of_text' => __(
607
+ ' out of ',
608
+ 'quiz-master-next'
609
+ ),
610
+ )
611
+ );
612
+ wp_enqueue_script( 'math_jax', '//cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.2/MathJax.js?config=TeX-MML-AM_CHTML' );
613
+ global $qmn_total_questions;
614
+ $qmn_total_questions = 0;
615
+ global $mlw_qmn_section_count;
616
+ $mlw_qmn_section_count = 0;
617
+ $auto_pagination_class = $options->pagination > 0 ? 'qsm_auto_pagination_enabled' : '';
618
+ $quiz_display .= "<div class='qsm-quiz-container qmn_quiz_container mlw_qmn_quiz {$auto_pagination_class}'>";
619
+ // Get quiz post based on quiz id
620
+ $args = array(
621
+ 'posts_per_page' => 1,
622
+ 'post_type' => 'qsm_quiz',
623
+ 'meta_query' => array(
624
+ array(
625
+ 'key' => 'quiz_id',
626
+ 'value' => $quiz_data['quiz_id'],
627
+ 'compare' => '=',
628
+ ),
629
+ ),
630
+ );
631
+ $the_query = new WP_Query( $args );
632
+
633
+ // The Loop
634
+ if ( $the_query->have_posts() ) {
635
+ while ( $the_query->have_posts() ) {
636
+ $the_query->the_post();
637
+ $quiz_display .= get_the_post_thumbnail( get_the_ID(), 'full' );
638
+ }
639
+ /* Restore original Post Data */
640
+ wp_reset_postdata();
641
+ }
642
+ $quiz_display = apply_filters( 'qsm_display_before_form', $quiz_display, $options, $quiz_data );
643
+ $quiz_display .= "<form name='quizForm{$quiz_data['quiz_id']}' id='quizForm{$quiz_data['quiz_id']}' action='" . $_SERVER['REQUEST_URI'] . "' method='POST' class='qsm-quiz-form qmn_quiz_form mlw_quiz_form' novalidate enctype='multipart/form-data'>";
644
+ $quiz_display .= "<input type='hidden' name='qsm_hidden_questions' id='qsm_hidden_questions' value=''>";
645
+ $quiz_display .= "<div id='mlw_error_message' class='qsm-error-message qmn_error_message_section'></div>";
646
+ $quiz_display .= "<span id='mlw_top_of_quiz'></span>";
647
+ $quiz_display = apply_filters( 'qmn_begin_quiz_form', $quiz_display, $options, $quiz_data );
648
+
649
+ // If deprecated pagination setting is not used, use new system...
650
+ $pages = $mlwQuizMasterNext->pluginHelper->get_quiz_setting( 'pages', array() );
651
+ if ( 0 == $options->randomness_order && 0 == $options->question_from_total && 0 == $options->pagination && 0 !== count( $pages ) ) {
652
+ $quiz_display .= $this->display_pages( $options, $quiz_data );
653
+ } else {
654
+ // ... else, use older system.
655
+ $questions = $this->load_questions( $quiz_data['quiz_id'], $options, true, $question_amount );
656
+ $answers = $this->create_answer_array( $questions );
657
+ $quiz_display .= $this->display_begin_section( $options, $quiz_data );
658
+ $quiz_display = apply_filters( 'qmn_begin_quiz_questions', $quiz_display, $options, $quiz_data );
659
+ $quiz_display .= $this->display_questions( $options, $questions, $answers );
660
+ $quiz_display = apply_filters( 'qmn_before_comment_section', $quiz_display, $options, $quiz_data );
661
+ $quiz_display .= $this->display_comment_section( $options, $quiz_data );
662
+ $quiz_display = apply_filters( 'qmn_after_comment_section', $quiz_display, $options, $quiz_data );
663
+ $quiz_display .= $this->display_end_section( $options, $quiz_data );
664
+ }
665
+ $quiz_display = apply_filters( 'qmn_before_error_message', $quiz_display, $options, $quiz_data );
666
+ $quiz_display .= "<div id='mlw_error_message_bottom' class='qsm-error-message qmn_error_message_section'></div>";
667
+ $quiz_display .= "<input type='hidden' name='total_questions' id='total_questions' value='$qmn_total_questions'/>";
668
+ $quiz_display .= "<input type='hidden' name='timer' id='timer' value='0'/>";
669
+ $quiz_display .= "<input type='hidden' name='timer_ms' id='timer_ms' value='0'/>";
670
+ $quiz_display .= "<input type='hidden' class='qmn_quiz_id' name='qmn_quiz_id' id='qmn_quiz_id' value='{$quiz_data['quiz_id']}'/>";
671
+ $quiz_display .= "<input type='hidden' name='complete_quiz' value='confirmation' />";
672
+ if ( isset( $_GET['payment_id'] ) && $_GET['payment_id'] != '' ) {
673
+ $quiz_display .= "<input type='hidden' name='main_payment_id' value='" . $_GET['payment_id'] . "' />";
674
+ }
675
+ $quiz_display = apply_filters( 'qmn_end_quiz_form', $quiz_display, $options, $quiz_data );
676
+ $quiz_display .= '</form>';
677
+ $quiz_display .= '</div>';
678
+
679
+ $quiz_display = apply_filters( 'qmn_end_quiz', $quiz_display, $options, $quiz_data );
680
+ return $quiz_display;
681
+ }
682
+
683
+ /**
684
+ * Creates the pages of content for the quiz/survey
685
+ *
686
+ * @since 5.2.0
687
+ * @param array $options The settings for the quiz.
688
+ * @param array $quiz_data The array of quiz data.
689
+ * @return string The HTML for the pages
690
+ */
691
+ public function display_pages( $options, $quiz_data ) {
692
+ global $mlwQuizMasterNext;
693
+ global $qmn_json_data;
694
+ ob_start();
695
+ $pages = $mlwQuizMasterNext->pluginHelper->get_quiz_setting( 'pages', array() );
696
+ $qpages = $mlwQuizMasterNext->pluginHelper->get_quiz_setting( 'qpages', array() );
697
+ $questions = QSM_Questions::load_questions_by_pages( $options->quiz_id );
698
+ $question_list = '';
699
+ $contact_fields = QSM_Contact_Manager::load_fields();
700
+ $animation_effect = isset( $options->quiz_animation ) && $options->quiz_animation != '' ? ' animated ' . $options->quiz_animation : '';
701
+ $enable_pagination_quiz = isset( $options->enable_pagination_quiz ) && $options->enable_pagination_quiz == 1 ? true : false;
702
+ if ( count( $pages ) > 1 && ( ! empty( $options->message_before ) || ( 0 == $options->contact_info_location && $contact_fields ) ) ) {
703
+ $qmn_json_data['first_page'] = true;
704
+ $message_before = wpautop( htmlspecialchars_decode( $options->message_before, ENT_QUOTES ) );
705
+ $message_before = apply_filters( 'mlw_qmn_template_variable_quiz_page', $message_before, $quiz_data );
706
+ ?>
707
+ <section class="qsm-page <?php echo $animation_effect; ?>">
708
+ <div class="quiz_section quiz_begin">
709
+ <div class='qsm-before-message mlw_qmn_message_before'>
710
+ <?php
711
+ echo $this->qsm_convert_editor_text_to_shortcode( $message_before );
712
+ ?>
713
+ </div>
714
+ <?php
715
+ if ( 0 == $options->contact_info_location ) {
716
+ echo QSM_Contact_Manager::display_fields( $options );
717
+ }
718
+ ?>
719
+ </div>
720
+ </section>
721
+ <?php
722
+ }
723
+
724
+ // If there is only one page.
725
+ $pages = apply_filters( 'qsm_display_pages', $pages, $options->quiz_id, $options );
726
+ if ( 1 == count( $pages ) ) {
727
+ ?>
728
+ <section class="qsm-page <?php echo $animation_effect; ?>">
729
+ <?php
730
+ if ( ! empty( $options->message_before ) || ( 0 == $options->contact_info_location && $contact_fields ) ) {
731
+ $qmn_json_data['first_page'] = false;
732
+ $message_before = wpautop( htmlspecialchars_decode( $options->message_before, ENT_QUOTES ) );
733
+ $message_before = apply_filters( 'mlw_qmn_template_variable_quiz_page', $message_before, $quiz_data );
734
+ ?>
735
+ <div class="quiz_section quiz_begin">
736
+ <div class='qsm-before-message mlw_qmn_message_before'>
737
+ <?php
738
+ echo $this->qsm_convert_editor_text_to_shortcode( $message_before );
739
+ ?>
740
+ </div>
741
+ <?php
742
+ if ( 0 == $options->contact_info_location ) {
743
+ echo QSM_Contact_Manager::display_fields( $options );
744
+ }
745
+ ?>
746
+ </div>
747
+ <?php
748
+ }
749
+ foreach ( $pages[0] as $question_id ) {
750
+ $question_list .= $question_id . 'Q';
751
+ $question = $questions[ $question_id ];
752
+ ?>
753
+ <div class='quiz_section question-section-id-<?php echo esc_attr( $question_id ); ?>'>
754
+ <?php
755
+ echo $mlwQuizMasterNext->pluginHelper->display_question( $question['question_type_new'], $question_id, $options );
756
+ if ( 0 == $question['comments'] ) {
757
+ echo "<input type='text' class='qsm-question-comment qsm-question-comment-small mlw_qmn_question_comment' id='mlwComment$question_id' name='mlwComment$question_id' placeholder='" . esc_attr( htmlspecialchars_decode( $options->comment_field_text, ENT_QUOTES ) ) . "' onclick='qmnClearField(this)'/>";
758
+ }
759
+ if ( 2 == $question['comments'] ) {
760
+ echo "<textarea class='qsm-question-comment qsm-question-comment-large mlw_qmn_question_comment' id='mlwComment$question_id' name='mlwComment$question_id' placeholder='" . esc_attr( htmlspecialchars_decode( $options->comment_field_text, ENT_QUOTES ) ) . "' onclick='qmnClearField(this)' ></textarea>";
761
+ }
762
+ // Checks if a hint is entered.
763
+ if ( ! empty( $question['hints'] ) ) {
764
+ echo '<div class="qsm-hint qsm_hint mlw_qmn_hint_link qsm_tooltip">' . $options->hint_text . '<span class="qsm_tooltiptext">' . htmlspecialchars_decode( $question['hints'], ENT_QUOTES ) . '</span></div>';
765
+ }
766
+ ?>
767
+ </div>
768
+ <?php
769
+ }
770
+ if ( 0 == $options->comment_section ) {
771
+ $message_comments = wpautop( htmlspecialchars_decode( $options->message_comment, ENT_QUOTES ) );
772
+ $message_comments = apply_filters( 'mlw_qmn_template_variable_quiz_page', $message_comments, $quiz_data );
773
+ ?>
774
+ <div class="quiz_section quiz_begin">
775
+ <label for='mlwQuizComments'
776
+ class='qsm-comments-label mlw_qmn_comment_section_text'><?php echo $message_comments; ?></label>
777
+ <textarea id='mlwQuizComments' name='mlwQuizComments' class='qsm-comments qmn_comment_section'></textarea>
778
+ </div>
779
+ <?php
780
+ }
781
+ if ( ! empty( $options->message_end_template ) || ( 1 == $options->contact_info_location && $contact_fields ) ) {
782
+ $message_after = wpautop( htmlspecialchars_decode( $options->message_end_template, ENT_QUOTES ) );
783
+ $message_after = apply_filters( 'mlw_qmn_template_variable_quiz_page', $message_after, $quiz_data );
784
+ ?>
785
+ <div class="quiz_section">
786
+ <div class='qsm-after-message mlw_qmn_message_end'><?php echo $message_after; ?></div>
787
+ <?php
788
+ if ( 1 == $options->contact_info_location ) {
789
+ echo QSM_Contact_Manager::display_fields( $options );
790
+ }
791
+ ?>
792
+ </div>
793
+ <?php
794
+ }
795
+ ?>
796
+ </section>
797
+ <?php
798
+ } else {
799
+ $total_pages_count = count( $pages );
800
+ $pages_count = 1;
801
+ foreach ( $pages as $key => $page ) {
802
+ $qpage = ( isset( $qpages[ $key ] ) ? $qpages[ $key ] : array() );
803
+ $qpage_id = ( isset( $qpage['id'] ) ? $qpage['id'] : $key );
804
+ $page_key = ( isset( $qpage['pagekey'] ) ? $qpage['pagekey'] : $key );
805
+ $hide_prevbtn = ( isset( $qpage['hide_prevbtn'] ) ? $qpage['hide_prevbtn'] : 0 );
806
+ $style = "style='display: none;'";
807
+ ?>
808
+ <section class="qsm-page <?php echo $animation_effect; ?> qsm-page-<?php echo $qpage_id; ?>"
809
+ data-pid="<?php echo $qpage_id; ?>" data-prevbtn="<?php echo $hide_prevbtn; ?>" <?php echo $style; ?>>
810
+ <?php do_action( 'qsm_action_before_page', $qpage_id, $qpage ); ?>
811
+ <?php
812
+ foreach ( $page as $question_id ) {
813
+ $question_list .= $question_id . 'Q';
814
+ $question = $questions[ $question_id ];
815
+ ?>
816
+ <div class='quiz_section question-section-id-<?php echo esc_attr( $question_id ); ?>'>
817
+ <?php
818
+ echo $mlwQuizMasterNext->pluginHelper->display_question( $question['question_type_new'], $question_id, $options );
819
+ if ( 0 == $question['comments'] ) {
820
+ echo "<input type='text' class='qsm-question-comment qsm-question-comment-small mlw_qmn_question_comment' id='mlwComment$question_id' name='mlwComment$question_id' placeholder='" . esc_attr( htmlspecialchars_decode( $options->comment_field_text, ENT_QUOTES ) ) . "' onclick='qmnClearField(this)'/>";
821
+ }
822
+ if ( 2 == $question['comments'] ) {
823
+ echo "<textarea class='qsm-question-comment qsm-question-comment-large mlw_qmn_question_comment' id='mlwComment$question_id' name='mlwComment$question_id' placeholder='" . esc_attr( htmlspecialchars_decode( $options->comment_field_text, ENT_QUOTES ) ) . "' onclick='qmnClearField(this)' ></textarea>";
824
+ }
825
+ // Checks if a hint is entered.
826
+ if ( ! empty( $question['hints'] ) ) {
827
+ echo '<div class="qsm-hint qsm_hint mlw_qmn_hint_link qsm_tooltip">' . $options->hint_text . '<span class="qsm_tooltiptext">' . htmlspecialchars_decode( $question['hints'], ENT_QUOTES ) . '</span></div>';
828
+ }
829
+ ?>
830
+ </div>
831
+ <?php
832
+ }
833
+ if ( $enable_pagination_quiz ) {
834
+ ?>
835
+ <span class="pages_count">
836
+ <?php
837
+ $text_c = $pages_count . __( ' out of ', 'quiz-master-next' ) . $total_pages_count;
838
+ echo apply_filters( 'qsm_total_pages_count', $text_c, $pages_count, $total_pages_count );
839
+ ?>
840
+ </span>
841
+ <?php } ?>
842
+ </section>
843
+ <?php
844
+ $pages_count++;
845
+ }
846
+ }
847
+
848
+ if ( count( $pages ) > 1 && 0 == $options->comment_section ) {
849
+ $message_comments = wpautop( htmlspecialchars_decode( $options->message_comment, ENT_QUOTES ) );
850
+ $message_comments = apply_filters( 'mlw_qmn_template_variable_quiz_page', $message_comments, $quiz_data );
851
+ ?>
852
+ <section class="qsm-page">
853
+ <div class="quiz_section quiz_begin">
854
+ <label for='mlwQuizComments'
855
+ class='qsm-comments-label mlw_qmn_comment_section_text'><?php echo $message_comments; ?></label>
856
+ <textarea id='mlwQuizComments' name='mlwQuizComments' class='qsm-comments qmn_comment_section'></textarea>
857
+ </div>
858
+ </section>
859
+ <?php
860
+ }
861
+ if ( count( $pages ) > 1 && ( ! empty( $options->message_end_template ) || ( 1 == $options->contact_info_location && $contact_fields ) ) ) {
862
+ $message_after = wpautop( htmlspecialchars_decode( $options->message_end_template, ENT_QUOTES ) );
863
+ $message_after = apply_filters( 'mlw_qmn_template_variable_quiz_page', $message_after, $quiz_data );
864
+ ?>
865
  <section class="qsm-page" style="display: none;">
866
+ <div class="quiz_section">
867
+ <div class='qsm-after-message mlw_qmn_message_end'><?php echo $message_after; ?></div>
868
+ <?php
869
+ if ( 1 == $options->contact_info_location ) {
870
+ echo QSM_Contact_Manager::display_fields( $options );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
871
  }
872
+ ?>
873
+ </div>
874
+ <?php
875
+ // Legacy code.
876
+ do_action( 'mlw_qmn_end_quiz_section' );
877
+ ?>
878
+ </section>
879
+ <?php
880
+ }
881
+ do_action( 'qsm_after_all_section' );
882
+ ?>
883
+ <!-- View for pagination -->
884
+ <script type="text/template" id="tmpl-qsm-pagination-<?php echo $options->quiz_id; ?>">
885
+ <div class="qsm-pagination qmn_pagination border margin-bottom">
886
+ <a class="qsm-btn qsm-previous qmn_btn mlw_qmn_quiz_link mlw_previous" href="#"><?php echo esc_html( $options->previous_button_text ); ?></a>
887
+ <span class="qmn_page_message"></span>
888
+ <div class="qmn_page_counter_message"></div>
889
+ <div class="qsm-progress-bar" style="display:none;"><div class="progressbar-text"></div></div>
890
+ <a class="qsm-btn qsm-next qmn_btn mlw_qmn_quiz_link mlw_next" href="#"><?php echo esc_html( $options->next_button_text ); ?></a>
891
+ <input type='submit' class='qsm-btn qsm-submit-btn qmn_btn' value='<?php echo esc_attr( htmlspecialchars_decode( $options->submit_button_text, ENT_QUOTES ) ); ?>' />
892
+ </div>
893
+ </script>
894
+ <input type='hidden' name='qmn_question_list' value='<?php echo esc_attr( $question_list ); ?>' />
895
+ <?php
896
+ return ob_get_clean();
897
+ }
898
+
899
+ /**
900
+ * Creates Display For Beginning Section
901
+ *
902
+ * Generates the content for the beginning section of the quiz page
903
+ *
904
+ * @since 4.0.0
905
+ * @param array $qmn_quiz_options The database row of the quiz.
906
+ * @param array $qmn_array_for_variables The array of results for the quiz.
907
+ * @return string The content for the beginning section
908
+ * @deprecated 5.2.0 Use new page system instead
909
+ */
910
+ public function display_begin_section( $qmn_quiz_options, $qmn_array_for_variables ) {
911
+ $section_display = '';
912
+ global $qmn_json_data;
913
+ $contact_fields = QSM_Contact_Manager::load_fields();
914
+ if ( ! empty( $qmn_quiz_options->message_before ) || ( 0 == $qmn_quiz_options->contact_info_location && $contact_fields ) ) {
915
+ $qmn_json_data['first_page'] = true;
916
+ global $mlw_qmn_section_count;
917
+ $mlw_qmn_section_count += 1;
918
+ $animation_effect = isset( $qmn_quiz_options->quiz_animation ) && $qmn_quiz_options->quiz_animation != '' ? ' animated ' . $qmn_quiz_options->quiz_animation : '';
919
+ $section_display .= "<div class='qsm-auto-page-row quiz_section $animation_effect quiz_begin'>";
920
+
921
+ $message_before = wpautop( htmlspecialchars_decode( $qmn_quiz_options->message_before, ENT_QUOTES ) );
922
+ $message_before = apply_filters( 'mlw_qmn_template_variable_quiz_page', $message_before, $qmn_array_for_variables );
923
+
924
+ $section_display .= "<div class='mlw_qmn_message_before'>" . $this->qsm_convert_editor_text_to_shortcode( $message_before ) . '</div>';
925
+ if ( 0 == $qmn_quiz_options->contact_info_location ) {
926
+ $section_display .= QSM_Contact_Manager::display_fields( $qmn_quiz_options );
927
+ }
928
+ $section_display .= '</div>';
929
+ } else {
930
+ $qmn_json_data['first_page'] = false;
931
+ }
932
+ return $section_display;
933
+ }
934
+
935
+ /**
936
+ * Creates Display For Questions
937
+ *
938
+ * Generates the content for the questions part of the quiz page
939
+ *
940
+ * @since 4.0.0
941
+ * @param array $qmn_quiz_options The database row of the quiz.
942
+ * @param array $qmn_quiz_questions The questions of the quiz.
943
+ * @param array $qmn_quiz_answers The answers of the quiz.
944
+ * @uses QMNPluginHelper:display_question() Displays a question
945
+ * @return string The content for the questions section
946
+ * @deprecated 5.2.0 Use new page system instead
947
+ */
948
+ public function display_questions( $qmn_quiz_options, $qmn_quiz_questions, $qmn_quiz_answers ) {
949
+ $question_display = '';
950
+ global $mlwQuizMasterNext;
951
+ global $qmn_total_questions;
952
+ global $mlw_qmn_section_count;
953
+ $question_id_list = '';
954
+ $animation_effect = isset( $qmn_quiz_options->quiz_animation ) && $qmn_quiz_options->quiz_animation != '' ? ' animated ' . $qmn_quiz_options->quiz_animation : '';
955
+ $enable_pagination_quiz = isset( $qmn_quiz_options->enable_pagination_quiz ) && $qmn_quiz_options->enable_pagination_quiz ? $qmn_quiz_options->enable_pagination_quiz : 0;
956
+ $pagination_optoin = $qmn_quiz_options->pagination;
957
+ if ( $enable_pagination_quiz && $pagination_optoin ) {
958
+ $total_pages_count = count( $qmn_quiz_questions );
959
+ $total_pagination = ceil( $total_pages_count / $pagination_optoin );
960
+ }
961
+ $pages_count = 1;
962
+ $current_page_number = 1;
963
+ foreach ( $qmn_quiz_questions as $mlw_question ) {
964
+ if ( $pagination_optoin != 0 ) {
965
+ if ( $pagination_optoin == 1 ) {
966
+ $question_display .= '<div class="qsm-auto-page-row qsm-apc-' . $current_page_number . '" style="display: none;">';
967
+ $current_page_number++;
968
+ } else {
969
+ if ( $pages_count % $pagination_optoin == 1 || $pages_count == 1 ) { // beginning of the row or first.
970
+ $question_display .= '<div class="qsm-auto-page-row qsm-apc-' . $current_page_number . '" style="display: none;">';
971
+ $current_page_number++;
972
+ }
973
+ }
974
+ $question_display .= apply_filters( 'qsm_auto_page_begin_row', '', ( $current_page_number - 1 ), $qmn_quiz_options, $qmn_quiz_questions );
975
+ }
976
+ $question_id_list .= $mlw_question->question_id . 'Q';
977
  $question_display .= "<div class='quiz_section {$animation_effect} question-section-id-{$mlw_question->question_id} slide{$mlw_qmn_section_count}'>";
978
+ $question_display .= $mlwQuizMasterNext->pluginHelper->display_question( $mlw_question->question_type_new, $mlw_question->question_id, $qmn_quiz_options );
979
+
980
+ if ( 0 == $mlw_question->comments ) {
981
+ $question_display .= "<input type='text' class='mlw_qmn_question_comment' id='mlwComment" . $mlw_question->question_id . "' name='mlwComment" . $mlw_question->question_id . "' placeholder='" . esc_attr( htmlspecialchars_decode( $qmn_quiz_options->comment_field_text, ENT_QUOTES ) ) . "' onclick='qmnClearField(this)'/>";
982
+ $question_display .= '<br />';
983
+ }
984
+ if ( 2 == $mlw_question->comments ) {
985
+ $question_display .= "<textarea cols='70' rows='5' class='mlw_qmn_question_comment' id='mlwComment" . $mlw_question->question_id . "' name='mlwComment" . $mlw_question->question_id . "' placeholder='" . htmlspecialchars_decode( $qmn_quiz_options->comment_field_text, ENT_QUOTES ) . "' onclick='qmnClearField(this)'></textarea>";
986
+ $question_display .= '<br />';
987
+ }
988
+
989
+ // Checks if a hint is entered.
990
+ if ( ! empty( $mlw_question->hints ) ) {
991
+ $question_display .= '<div title="' . esc_attr( htmlspecialchars_decode( $mlw_question->hints, ENT_QUOTES ) ) . "\" class='qsm_hint mlw_qmn_hint_link'>{$qmn_quiz_options->hint_text}</div>";
992
+ $question_display .= '<br /><br />';
993
+ }
994
  $question_display .= '</div><!-- .quiz_section -->';
995
+ if ( $pagination_optoin == 0 ) {
996
+
997
+ } elseif ( $pagination_optoin == 1 ) {
998
+ $question_display .= '</div><!-- .qsm-auto-page-row -->';
999
+ } elseif ( $pages_count % $pagination_optoin == 0 || $pages_count == count( $qmn_quiz_questions ) ) { // end of the row or last
1000
+ $question_display .= '</div><!-- .qsm-auto-page-row -->';
1001
+ }
1002
+ $mlw_qmn_section_count = $mlw_qmn_section_count + 1;
1003
+ $pages_count++;
1004
+ }
1005
+ if ( $enable_pagination_quiz ) {
1006
+ $question_display .= "<span class='pages_count' style='display: none;'>";
1007
+ $text_c = $current_page_number . __( ' out of ', 'quiz-master-next' ) . $total_pagination;
1008
+ $question_display .= apply_filters( 'qsm_total_pages_count', $text_c, $pages_count, $total_pages_count );
1009
+ $question_display .= '</span>';
1010
+ }
1011
+ $question_display .= "<input type='hidden' name='qmn_question_list' value='$question_id_list' />";
1012
+ return $question_display;
1013
+ }
1014
+
1015
+ /**
1016
+ * Creates Display For Comment Section
1017
+ *
1018
+ * Generates the content for the comment section part of the quiz page
1019
+ *
1020
+ * @since 4.0.0
1021
+ * @param array $qmn_quiz_options The database row of the quiz.
1022
+ * @param array $qmn_array_for_variables The array of results for the quiz.
1023
+ * @return string The content for the comment section
1024
+ * @deprecated 5.2.0 Use new page system instead
1025
+ */
1026
+ public function display_comment_section( $qmn_quiz_options, $qmn_array_for_variables ) {
1027
+ global $mlw_qmn_section_count;
1028
+ $comment_display = '';
1029
+ if ( 0 == $qmn_quiz_options->comment_section ) {
1030
+ $mlw_qmn_section_count = $mlw_qmn_section_count + 1;
1031
+ $comment_display .= "<div class='quiz_section quiz_end qsm-auto-page-row qsm-quiz-comment-section slide" . $mlw_qmn_section_count . "' style='display: none;'>";
1032
+ $message_comments = wpautop( htmlspecialchars_decode( $qmn_quiz_options->message_comment, ENT_QUOTES ) );
1033
+ $message_comments = apply_filters( 'mlw_qmn_template_variable_quiz_page', $message_comments, $qmn_array_for_variables );
1034
+ $comment_display .= "<label for='mlwQuizComments' class='mlw_qmn_comment_section_text'>$message_comments</label><br />";
1035
+ $comment_display .= "<textarea cols='60' rows='10' id='mlwQuizComments' name='mlwQuizComments' class='qmn_comment_section'></textarea>";
1036
+ $comment_display .= '</div>';
1037
+ }
1038
+ return $comment_display;
1039
+ }
1040
+
1041
+ /**
1042
+ * Creates Display For End Section Of Quiz Page
1043
+ *
1044
+ * Generates the content for the end section of the quiz page
1045
+ *
1046
+ * @since 4.0.0
1047
+ * @param array $qmn_quiz_options The database row of the quiz.
1048
+ * @param array $qmn_array_for_variables The array of results for the quiz.
1049
+ * @return string The content for the end section
1050
+ * @deprecated 5.2.0 Use new page system instead
1051
+ */
1052
+ public function display_end_section( $qmn_quiz_options, $qmn_array_for_variables ) {
1053
+ global $mlw_qmn_section_count;
1054
+ $section_display = '';
1055
+ $section_display .= '<br />';
1056
+ $mlw_qmn_section_count = $mlw_qmn_section_count + 1;
1057
+ $pagination_optoin = $qmn_quiz_options->pagination;
1058
+ $style = '';
1059
+ if ( $pagination_optoin > 0 ) {
1060
+ $style = "style='display: none;'";
1061
+ }
1062
+ $section_display .= "<div class='qsm-auto-page-row quiz_section quiz_end' {$style}>";
1063
+ if ( ! empty( $qmn_quiz_options->message_end_template ) ) {
1064
+ $message_end = wpautop( htmlspecialchars_decode( $qmn_quiz_options->message_end_template, ENT_QUOTES ) );
1065
+ $message_end = apply_filters( 'mlw_qmn_template_variable_quiz_page', $message_end, $qmn_array_for_variables );
1066
+ $section_display .= "<span class='mlw_qmn_message_end'>$message_end</span>";
1067
+ $section_display .= '<br /><br />';
1068
+ }
1069
+ if ( 1 == $qmn_quiz_options->contact_info_location ) {
1070
+ $section_display .= QSM_Contact_Manager::display_fields( $qmn_quiz_options );
1071
+ }
1072
+
1073
+ // Legacy Code.
1074
+ ob_start();
1075
+ do_action( 'mlw_qmn_end_quiz_section' );
1076
+ $section_display .= ob_get_contents();
1077
+ ob_end_clean();
1078
+ $section_display .= "<input type='submit' class='qsm-btn qsm-submit-btn qmn_btn' value='" . esc_attr( htmlspecialchars_decode( $qmn_quiz_options->submit_button_text, ENT_QUOTES ) ) . "' />";
1079
+ $section_display .= '</div>';
1080
+
1081
+ return $section_display;
1082
+ }
1083
+
1084
+ /**
1085
+ * Generates Content Results Page
1086
+ *
1087
+ * Generates the content for the results page part of the shortcode
1088
+ *
1089
+ * @since 4.0.0
1090
+ * @param array $options The database row of the quiz.
1091
+ * @param array $data The array of results for the quiz.
1092
+ * @uses QMNQuizManager:submit_results() Perform The Quiz/Survey Submission
1093
+ * @return string The content for the results page section
1094
+ */
1095
+ public function display_results( $options, $data ) {
1096
+ $result = $this->submit_results( $options, $data );
1097
+ $results_array = $result;
1098
+ return $results_array['display'];
1099
+ }
1100
+
1101
+ /**
1102
+ * Calls the results page from ajax
1103
+ *
1104
+ * @since 4.6.0
1105
+ * @uses QMNQuizManager:submit_results() Perform The Quiz/Survey Submission
1106
+ * @return string The content for the results page section
1107
+ */
1108
+ public function ajax_submit_results() {
1109
+ global $qmn_allowed_visit;
1110
+ global $mlwQuizMasterNext;
1111
+
1112
+ $qmn_allowed_visit = true;
1113
+ $quiz = intval( $_POST['qmn_quiz_id'] );
1114
+ $mlwQuizMasterNext->pluginHelper->prepare_quiz( $quiz );
1115
+ $options = $mlwQuizMasterNext->quiz_settings->get_quiz_options();
1116
+ $data = array(
1117
+ 'quiz_id' => $options->quiz_id,
1118
+ 'quiz_name' => $options->quiz_name,
1119
+ 'quiz_system' => $options->system,
1120
+ 'quiz_payment_id' => isset( $_POST['main_payment_id'] ) ? sanitize_text_field( $_POST['main_payment_id'] ) : '',
1121
+ );
1122
+ $post_data = array(
1123
+ 'g-recaptcha-response' => isset( $_POST['g-recaptcha-response'] ) ? sanitize_textarea_field( $_POST['g-recaptcha-response'] ) : '',
1124
+ );
1125
+ if ( class_exists( 'QSM_Recaptcha' ) ) {
1126
+ $recaptcha_data = $mlwQuizMasterNext->pluginHelper->get_quiz_setting( 'recaptcha_integration_settings' );
1127
+ if ( isset( $recaptcha_data['enable_recaptcha'] ) && $recaptcha_data['enable_recaptcha'] != 'no' ) {
1128
+ $verified = qsm_verify_recaptcha( $post_data );
1129
+ if ( ! $verified ) {
1130
+ echo json_encode(
1131
+ array(
1132
+ 'display' => htmlspecialchars_decode( 'ReCaptcha Validation failed' ),
1133
+ 'redirect' => false,
1134
+ )
1135
+ );
1136
+ exit;
1137
+ }
1138
+ }
1139
+ }
1140
+ echo json_encode( $this->submit_results( $options, $data ) );
1141
+ die();
1142
+ }
1143
+
1144
+ /**
1145
+ * @version 6.3.2
1146
+ * Show quiz on button click
1147
+ */
1148
+ public function qsm_get_quiz_to_reload() {
1149
+ $quiz_id = sanitize_text_field( intval( $_POST['quiz_id'] ) );
1150
+ echo do_shortcode( '[qsm quiz="' . $quiz_id . '"]' );
1151
+ exit;
1152
+ }
1153
+
1154
+ /**
1155
+ * Perform The Quiz/Survey Submission
1156
+ *
1157
+ * Prepares and save the results, prepares and send emails, prepare results page
1158
+ *
1159
+ * @since 4.6.0
1160
+ * @param array $qmn_quiz_options The database row of the quiz.
1161
+ * @param array $qmn_array_for_variables The array of results for the quiz.
1162
+ * @uses QMNQuizManager:check_answers() Creates display for beginning section
1163
+ * @uses QMNQuizManager:check_comment_section() Creates display for questions
1164
+ * @uses QMNQuizManager:display_results_text() Creates display for end section
1165
+ * @uses QMNQuizManager:display_social() Creates display for comment section
1166
+ * @uses QMNQuizManager:send_user_email() Creates display for end section
1167
+ * @uses QMNQuizManager:send_admin_email() Creates display for end section
1168
+ * @return string The content for the results page section
1169
+ */
1170
+ public function submit_results( $qmn_quiz_options, $qmn_array_for_variables ) {
1171
+ global $qmn_allowed_visit;
1172
+ $result_display = '';
1173
+
1174
+ $qmn_array_for_variables['user_ip'] = $this->get_user_ip();
1175
+
1176
+ $result_display = apply_filters( 'qmn_begin_results', $result_display, $qmn_quiz_options, $qmn_array_for_variables );
1177
+ if ( ! $qmn_allowed_visit ) {
1178
+ return $result_display;
1179
+ }
1180
+ // Add form type for new quiz system 7.0.0
1181
+ $qmn_array_for_variables['form_type'] = isset( $qmn_quiz_options->form_type ) ? $qmn_quiz_options->form_type : 0;
1182
+ // Gathers contact information.
1183
+ $qmn_array_for_variables['user_name'] = 'None';
1184
+ $qmn_array_for_variables['user_business'] = 'None';
1185
+ $qmn_array_for_variables['user_email'] = 'None';
1186
+ $qmn_array_for_variables['user_phone'] = 'None';
1187
+ $contact_responses = QSM_Contact_Manager::process_fields( $qmn_quiz_options );
1188
+ foreach ( $contact_responses as $field ) {
1189
+ if ( isset( $field['use'] ) ) {
1190
+ if ( 'name' === $field['use'] ) {
1191
+ $qmn_array_for_variables['user_name'] = $field['value'];
1192
+ }
1193
+ if ( 'comp' === $field['use'] ) {
1194
+ $qmn_array_for_variables['user_business'] = $field['value'];
1195
+ }
1196
+ if ( 'email' === $field['use'] ) {
1197
+ $qmn_array_for_variables['user_email'] = $field['value'];
1198
+ }
1199
+ if ( 'phone' === $field['use'] ) {
1200
+ $qmn_array_for_variables['user_phone'] = $field['value'];
1201
+ }
1202
+ }
1203
+ }
1204
+
1205
+ if ( is_user_logged_in() ) {
1206
+ $current_user = wp_get_current_user();
1207
+ if ( $qmn_array_for_variables['user_email'] == 'None' ) {
1208
+ $qmn_array_for_variables['user_email'] = esc_html( $current_user->user_email );
1209
+ }
1210
+
1211
+ if ( $qmn_array_for_variables['user_name'] == 'None' ) {
1212
+ $qmn_array_for_variables['user_name'] = esc_html( $current_user->display_name );
1213
+ }
1214
+ }
1215
+
1216
+ $mlw_qmn_pagetime = isset( $_POST['pagetime'] ) ? $_POST['pagetime'] : array();
1217
+ $mlw_qmn_timer = isset( $_POST['timer'] ) ? sanitize_text_field( intval( $_POST['timer'] ) ) : 0;
1218
+ $mlw_qmn_timer_ms = isset( $_POST['timer_ms'] ) ? sanitize_text_field( intval( $_POST['timer_ms'] ) ) : 0;
1219
+ $qmn_array_for_variables['user_id'] = get_current_user_id();
1220
+ $qmn_array_for_variables['timer'] = $mlw_qmn_timer;
1221
+ $qmn_array_for_variables['timer_ms'] = $mlw_qmn_timer_ms;
1222
+ $qmn_array_for_variables['time_taken'] = current_time( 'h:i:s A m/d/Y' );
1223
+ $qmn_array_for_variables['contact'] = $contact_responses;
1224
+ $qmn_array_for_variables['hidden_questions'] = isset( $_POST['qsm_hidden_questions'] ) ? json_decode( html_entity_decode( stripslashes( $_POST['qsm_hidden_questions'] ) ), true ) : array();
1225
+ $qmn_array_for_variables = apply_filters( 'qsm_result_variables', $qmn_array_for_variables );
1226
+
1227
+ if ( ! isset( $_POST['mlw_code_captcha'] ) || ( isset( $_POST['mlw_code_captcha'] ) && $_POST['mlw_user_captcha'] == $_POST['mlw_code_captcha'] ) ) {
1228
+
1229
+ $qmn_array_for_variables = array_merge( $qmn_array_for_variables, $this->check_answers( $qmn_quiz_options, $qmn_array_for_variables ) );
1230
+ $result_display = apply_filters( 'qmn_after_check_answers', $result_display, $qmn_quiz_options, $qmn_array_for_variables );
1231
+ $qmn_array_for_variables['comments'] = $this->check_comment_section( $qmn_quiz_options, $qmn_array_for_variables );
1232
+ $result_display = apply_filters( 'qmn_after_check_comments', $result_display, $qmn_quiz_options, $qmn_array_for_variables );
1233
+
1234
+ $unique_id = md5( date( 'Y-m-d H:i:s' ) );
1235
  $results_id = 0;
1236
+ // If the store responses in database option is set to Yes.
1237
+ if ( 0 != $qmn_quiz_options->store_responses ) {
1238
+
1239
+ // Creates our results array.
1240
+ $results_array = array(
1241
+ intval( $qmn_array_for_variables['timer'] ),
1242
+ $qmn_array_for_variables['question_answers_array'],
1243
+ htmlspecialchars( stripslashes( $qmn_array_for_variables['comments'] ), ENT_QUOTES ),
1244
+ 'contact' => $contact_responses,
1245
+ 'timer_ms' => intval( $qmn_array_for_variables['timer_ms'] ),
1246
  'pagetime' => $mlw_qmn_pagetime,
1247
+ );
1248
+ $results_array = apply_filters( 'qsm_results_array', $results_array, $qmn_array_for_variables );
1249
+ if ( isset( $results_array['parameters'] ) ) {
1250
+ $qmn_array_for_variables['parameters'] = $results_array['parameters'];
1251
+ }
1252
+ $results_array['hidden_questions'] = $qmn_array_for_variables['hidden_questions'];
1253
+ $results_array['total_possible_points'] = $qmn_array_for_variables['total_possible_points'];
1254
+ $results_array['total_attempted_questions'] = $qmn_array_for_variables['total_attempted_questions'];
1255
+ $serialized_results = serialize( $results_array );
1256
+
1257
+ // Inserts the responses in the database.
1258
+ global $wpdb;
1259
+ $table_name = $wpdb->prefix . 'mlw_results';
1260
+ if ( isset( $_POST['update_result'] ) && ! empty( $_POST['update_result'] ) ) {
1261
+ $results_id = $_POST['update_result'];
1262
+ $results_update = $wpdb->update(
1263
+ $table_name,
1264
+ array(
1265
+ 'point_score' => $qmn_array_for_variables['total_points'],
1266
+ 'correct_score' => $qmn_array_for_variables['total_score'],
1267
+ 'correct' => $qmn_array_for_variables['total_correct'],
1268
+ 'total' => $qmn_array_for_variables['total_questions'],
1269
+ 'user_ip' => $qmn_array_for_variables['user_ip'],
1270
+ 'time_taken' => $qmn_array_for_variables['time_taken'],
1271
+ 'time_taken_real' => date( 'Y-m-d H:i:s', strtotime( $qmn_array_for_variables['time_taken'] ) ),
1272
+ 'quiz_results' => $serialized_results,
1273
+ ),
1274
+ array( 'result_id' => $results_id )
1275
+ );
1276
  } else {
1277
+ $results_insert = $wpdb->insert(
1278
+ $table_name,
1279
+ array(
1280
+ 'quiz_id' => $qmn_array_for_variables['quiz_id'],
1281
+ 'quiz_name' => $qmn_array_for_variables['quiz_name'],
1282
+ 'quiz_system' => $qmn_array_for_variables['quiz_system'],
1283
+ 'point_score' => $qmn_array_for_variables['total_points'],
1284
+ 'correct_score' => $qmn_array_for_variables['total_score'],
1285
+ 'correct' => $qmn_array_for_variables['total_correct'],
1286
+ 'total' => $qmn_array_for_variables['total_questions'],
1287
+ 'name' => $qmn_array_for_variables['user_name'],
1288
+ 'business' => $qmn_array_for_variables['user_business'],
1289
+ 'email' => $qmn_array_for_variables['user_email'],
1290
+ 'phone' => $qmn_array_for_variables['user_phone'],
1291
+ 'user' => $qmn_array_for_variables['user_id'],
1292
+ 'user_ip' => $qmn_array_for_variables['user_ip'],
1293
+ 'time_taken' => $qmn_array_for_variables['time_taken'],
1294
+ 'time_taken_real' => date( 'Y-m-d H:i:s', strtotime( $qmn_array_for_variables['time_taken'] ) ),
1295
+ 'quiz_results' => $serialized_results,
1296
+ 'deleted' => 0,
1297
+ 'unique_id' => $unique_id,
1298
+ 'form_type' => isset( $qmn_quiz_options->form_type ) ? $qmn_quiz_options->form_type : 0,
1299
+ ),
1300
+ array(
1301
+ '%d',
1302
+ '%s',
1303
+ '%d',
1304
+ '%f',
1305
+ '%d',
1306
+ '%d',
1307
+ '%d',
1308
+ '%s',
1309
+ '%s',
1310
+ '%s',
1311
+ '%s',
1312
+ '%d',
1313
+ '%s',
1314
+ '%s',
1315
+ '%s',
1316
+ '%s',
1317
+ '%d',
1318
+ '%s',
1319
+ '%d',
1320
  )
1321
  );
1322
+ $results_id = $wpdb->insert_id;
1323
  }
1324
  }
1325
+ $qmn_array_for_variables['result_id'] = $results_id;
1326
 
1327
  // Determines redirect/results page.
1328
+ $results_pages = $this->display_results_text( $qmn_quiz_options, $qmn_array_for_variables );
1329
+ $result_display .= $results_pages['display'];
1330
+ $result_display = apply_filters( 'qmn_after_results_text', $result_display, $qmn_quiz_options, $qmn_array_for_variables );
1331
+
1332
+ $result_display .= $this->display_social( $qmn_quiz_options, $qmn_array_for_variables );
1333
+ $result_display = apply_filters( 'qmn_after_social_media', $result_display, $qmn_quiz_options, $qmn_array_for_variables );
1334
+ if ( $this->qsm_plugin_active( 'qsm-save-resume/qsm-save-resume.php' ) != 1 && $qmn_quiz_options->enable_retake_quiz_button == 1 ) {
1335
+ $result_display .= '<a style="float: right;" class="button btn-reload-quiz" data-quiz_id="' . $qmn_array_for_variables['quiz_id'] . '" href="#" >' . apply_filters( 'qsm_retake_quiz_text', __( 'Retake Quiz', 'quiz-master-next' ) ) . '</a>';
1336
+ }
1337
 
1338
  /*
1339
  * Update the option `qmn_quiz_taken_cnt` value by 1 each time
1340
  * whenever the record inserted into the required table.
1341
  */
1342
+ if ( $results_insert ) {
1343
  $rec_inserted = intval( get_option( 'qmn_quiz_taken_cnt' ) );
1344
+ if ( 1000 > $rec_inserted ) {
1345
+ if ( ! $rec_inserted ) {
1346
  update_option( 'qmn_quiz_taken_cnt', 1, true );
1347
+ } else {
1348
  update_option( 'qmn_quiz_taken_cnt', ++$rec_inserted );
1349
  }
1350
  }
1351
  }
1352
 
1353
+ // Hook is fired after the responses are submitted. Passes responses, result ID, quiz settings, and response data.
1354
+ do_action( 'qsm_quiz_submitted', $results_array, $results_id, $qmn_quiz_options, $qmn_array_for_variables );
1355
+
1356
+ $qmn_array_for_variables = apply_filters( 'qmn_filter_email_content', $qmn_array_for_variables, $results_id );
1357
+
1358
+ $qmn_global_settings = (array) get_option( 'qmn-settings' );
1359
+ $background_quiz_email_process = isset( $qmn_global_settings['background_quiz_email_process'] ) ? esc_attr( $qmn_global_settings['background_quiz_email_process'] ) : '1';
1360
+ if ( $background_quiz_email_process == 1 ) {
1361
+ // Send the emails in background.
1362
+ $qmn_array_for_variables['quiz_settings'] = isset( $qmn_quiz_options->quiz_settings ) ? @unserialize( $qmn_quiz_options->quiz_settings ) : array();
1363
+ $qmn_array_for_variables['email_processed'] = 'yes';
1364
+ $this->qsm_background_email->data(
1365
+ array(
1366
+ 'name' => 'send_emails',
1367
+ 'variables' => $qmn_array_for_variables,
1368
+ )
1369
+ )->dispatch();
1370
+ } else {
1371
+ // Sends the emails.
1372
+ $qmn_array_for_variables['email_processed'] = 'yes';
1373
+ QSM_Emails::send_emails( $qmn_array_for_variables );
1374
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1375
 
1376
+ /**
1377
+ * Filters for filtering the results text after emails are sent.
1378
+ *
1379
+ * @deprecated 6.2.0 There's no reason to use these over the actions
1380
+ * in the QSM_Results_Pages class or the other filters in this function.
1381
+ */
1382
+ $result_display = apply_filters( 'qmn_after_send_user_email', $result_display, $qmn_quiz_options, $qmn_array_for_variables );
1383
+ $result_display = apply_filters( 'qmn_after_send_admin_email', $result_display, $qmn_quiz_options, $qmn_array_for_variables );
1384
 
1385
+ // Last time to filter the HTML results page.
1386
+ $result_display = apply_filters( 'qmn_end_results', $result_display, $qmn_quiz_options, $qmn_array_for_variables );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1387
 
1388
+ // Legacy Code.
1389
+ do_action( 'mlw_qmn_load_results_page', $wpdb->insert_id, $qmn_quiz_options->quiz_settings );
1390
+ } else {
1391
+ $result_display .= apply_filters( 'qmn_captcha_varification_failed_msg', __( 'Captcha verification failed.', 'quiz-master-next' ), $qmn_quiz_options, $qmn_array_for_variables );
1392
+ }
1393
+
1394
+ $result_display = str_replace( '%FB_RESULT_ID%', $unique_id, $result_display );
1395
+
1396
+ // Prepares data to be sent back to front-end.
1397
+ $return_array = array(
1398
+ 'display' => htmlspecialchars_decode( $result_display ),
1399
+ 'redirect' => apply_filters( 'mlw_qmn_template_variable_results_page', $results_pages['redirect'], $qmn_array_for_variables ),
1400
+ );
1401
+
1402
+ return $return_array;
1403
+ }
1404
+
1405
+ /**
1406
+ * Scores User Answers
1407
+ *
1408
+ * Calculates the users scores for the quiz
1409
+ *
1410
+ * @since 4.0.0
1411
+ * @param array $options The database row of the quiz
1412
+ * @param array $quiz_data The array of results for the quiz
1413
+ * @uses QMNPluginHelper:display_review() Scores the question
1414
+ * @return array The results of the user's score
1415
+ */
1416
+ public function check_answers( $options, $quiz_data ) {
1417
+
1418
+ global $mlwQuizMasterNext;
1419
+
1420
+ // Load the pages and questions
1421
+ $pages = $mlwQuizMasterNext->pluginHelper->get_quiz_setting( 'pages', array() );
1422
+ $questions = QSM_Questions::load_questions_by_pages( $options->quiz_id );
1423
+
1424
+ // Retrieve data from submission
1425
+ $total_questions = isset( $_POST['total_questions'] ) ? sanitize_text_field( intval( $_POST['total_questions'] ) ) : 0;
1426
+ $question_list = array();
1427
+ if ( isset( $_POST['qmn_question_list'] ) ) {
1428
+ $qmn_question_list = sanitize_text_field( $_POST['qmn_question_list'] );
1429
+ $question_list = explode( 'Q', $qmn_question_list );
1430
+ }
1431
+
1432
+ // Prepare variables
1433
+ $points_earned = 0;
1434
+ $total_correct = 0;
1435
+ $total_score = 0;
1436
+ $user_answer = '';
1437
+ $correct_answer = '';
1438
+ $correct_status = 'incorrect';
1439
+ $answer_points = 0;
1440
+ $question_data = array();
1441
+ $total_possible_points = 0;
1442
+ $attempted_question = 0;
1443
+
1444
+ // Question types to calculate result on
1445
+ $result_question_types = array(
1446
+ 0, // Multiple Choice
1447
+ 1, // Horizontal Multiple Choice
1448
+ 2, // Drop Down
1449
+ 4, // Multiple Response
1450
+ 10, // Horizontal Multiple Response
1451
+ 12, // Date
1452
+ 3, // Small Open Answer
1453
+ 5, // Large Open Answer
1454
+ 7, // Number
1455
+ 14, // Fill In The Blank
1456
+ 13, // Polar.
1457
+ );
1458
+
1459
+ // If deprecated pagination setting is not used, use new system...
1460
+ if ( 0 == $options->question_from_total && 0 !== count( $pages ) ) {
1461
+
1462
+ // Cycle through each page in quiz.
1463
+ foreach ( $pages as $page ) {
1464
+
1465
+ // Cycle through each question on a page
1466
+ foreach ( $page as $page_question_id ) {
1467
+
1468
+ // Cycle through each question that appeared to the user
1469
+ foreach ( $question_list as $question_id ) {
1470
+
1471
+ // When the questions are the same...
1472
+ if ( $page_question_id == $question_id ) {
1473
+
1474
+ $question = $questions[ $page_question_id ];
1475
+ // Ignore non points questions from result
1476
+ $question_type_new = $question['question_type_new'];
1477
+ $hidden_questions = is_array( $quiz_data['hidden_questions'] ) ? $quiz_data['hidden_questions'] : array();
1478
+
1479
+ // Reset question-specific variables
1480
+ $user_answer = '';
1481
+ $correct_answer = '';
1482
+ $correct_status = 'incorrect';
1483
+ $answer_points = 0;
1484
+
1485
+ // Get total correct points
1486
+ if ( ( $options->system == 3 || $options->system == 1 ) && isset( $question['answers'] ) && ! empty( $question['answers'] ) ) {
1487
+ if ( ! in_array( $question_id, $hidden_questions ) ) {
1488
+ if ( $question_type_new == 4 || $question_type_new == 10 ) {
1489
+ foreach ( $question['answers'] as $single_answerk_key => $single_answer_arr ) {
1490
+ if ( $options->system == 1 && isset( $single_answer_arr[1] ) ) {
1491
+ $total_possible_points = $total_possible_points + $single_answer_arr[1];
1492
+ }
1493
+ if ( $options->system == 3 && isset( $single_answer_arr[2] ) && $single_answer_arr[2] == 1 ) {
1494
+ $total_possible_points = $total_possible_points + $single_answer_arr[1];
1495
+ }
1496
+ }
1497
+ } else {
1498
+ $max_value = max( array_column( $question['answers'], '1' ) );
1499
+ $total_possible_points = $total_possible_points + $max_value;
1500
+ }
1501
+ }
1502
+ }
1503
+
1504
+ // Send question to our grading function
1505
+ $results_array = apply_filters( 'qmn_results_array', $mlwQuizMasterNext->pluginHelper->display_review( $question['question_type_new'], $question['question_id'] ) );
1506
+ if ( isset( $results_array['question_type'] ) && $results_array['question_type'] == 'file_upload' ) {
1507
+ $results_array['user_text'] = '<a target="_blank" href="' . $results_array['user_text'] . '">' . __( 'Click here to view', 'quiz-master-next' ) . '</a>';
1508
+ }
1509
+ // If question was graded correctly.
1510
+ if ( ! isset( $results_array['null_review'] ) ) {
1511
+ if ( in_array( $question_type_new, $result_question_types ) ) {
1512
+ if ( ! in_array( $question_id, $hidden_questions ) ) {
1513
+ $points_earned += $results_array['points'];
1514
+ $answer_points += $results_array['points'];
1515
+ }
1516
+ }
1517
+
1518
+ // If the user's answer was correct
1519
+ if ( 'correct' == $results_array['correct'] ) {
1520
+ if ( in_array( $question_type_new, $result_question_types ) ) {
1521
+ if ( ! in_array( $question_id, $hidden_questions ) ) {
1522
+ $total_correct += 1;
1523
+ $correct_status = 'correct';
1524
+ }
1525
+ }
1526
+ }
1527
+ $user_answer = $results_array['user_text'];
1528
+ $correct_answer = $results_array['correct_text'];
1529
+ $user_compare_text = isset( $results_array['user_compare_text'] ) ? $results_array['user_compare_text'] : '';
1530
+
1531
+ if ( trim( $user_answer ) != '' ) {
1532
+ if ( $user_answer != 'No Answer Provided' ) {
1533
+ $attempted_question++;
1534
+ }
1535
+ }
1536
+
1537
+ // If a comment was submitted
1538
+ if ( isset( $_POST[ 'mlwComment' . $question['question_id'] ] ) ) {
1539
+ $comment = sanitize_textarea_field( htmlspecialchars( stripslashes( $_POST[ 'mlwComment' . $question['question_id'] ] ), ENT_QUOTES ) );
1540
+ } else {
1541
+ $comment = '';
1542
+ }
1543
+
1544
+ // Get text for question
1545
+ $question_text = $question['question_name'];
1546
+ if ( isset( $results_array['question_text'] ) ) {
1547
+ $question_text = $results_array['question_text'];
1548
+ }
1549
+
1550
+ // Save question data into new array in our array
1551
+ $question_data[] = apply_filters(
1552
+ 'qmn_answer_array',
1553
+ array(
1554
+ $question_text,
1555
+ htmlspecialchars( $user_answer, ENT_QUOTES ),
1556
+ htmlspecialchars( $correct_answer, ENT_QUOTES ),
1557
+ $comment,
1558
+ 'correct' => $correct_status,
1559
+ 'id' => $question['question_id'],
1560
+ 'points' => $answer_points,
1561
+ 'category' => $question['category'],
1562
+ 'question_type' => $question['question_type_new'],
1563
+ 'question_title' => isset( $question['settings']['question_title'] ) ? $question['settings']['question_title'] : '',
1564
+ 'user_compare_text' => $user_compare_text,
1565
+ ),
1566
+ $options,
1567
+ $quiz_data
1568
+ );
1569
+ }
1570
+ break;
1571
+ }
1572
+ }
1573
+ }
1574
+ }
1575
+ } else {
1576
+ // Cycle through each page in quiz.
1577
+ foreach ( $questions as $question ) {
1578
+
1579
+ // Cycle through each question that appeared to the user
1580
+ foreach ( $question_list as $question_id ) {
1581
+
1582
+ // When the questions are the same...
1583
+ if ( $question['question_id'] == $question_id ) {
1584
+
1585
+ // Reset question-specific variables
1586
+ $user_answer = '';
1587
+ $correct_answer = '';
1588
+ $correct_status = 'incorrect';
1589
+ $answer_points = 0;
1590
+
1591
+ // Get total correct points
1592
+ if ( ( $options->system == 3 || $options->system == 1 ) && isset( $question['answers'] ) && ! empty( $question['answers'] ) ) {
1593
+ if ( $question_type_new == 4 || $question_type_new == 10 ) {
1594
+ foreach ( $question['answers'] as $single_answerk_key => $single_answer_arr ) {
1595
+ if ( $options->system == 1 && isset( $single_answer_arr[1] ) ) {
1596
+ $total_possible_points = $total_possible_points + $single_answer_arr[1];
1597
+ }
1598
+ if ( $options->system == 3 && isset( $single_answer_arr[2] ) && $single_answer_arr[2] == 1 ) {
1599
+ $total_possible_points = $total_possible_points + $single_answer_arr[1];
1600
+ }
1601
+ }
1602
+ } else {
1603
+ $max_value = max( array_column( $question['answers'], '1' ) );
1604
+ $total_possible_points = $total_possible_points + $max_value;
1605
+ }
1606
+ }
1607
+
1608
+ // Send question to our grading function
1609
+ $results_array = apply_filters( 'qmn_results_array', $mlwQuizMasterNext->pluginHelper->display_review( $question['question_type_new'], $question['question_id'] ) );
1610
+
1611
+ // If question was graded correctly.
1612
+ if ( ! isset( $results_array['null_review'] ) ) {
1613
+ $points_earned += $results_array['points'];
1614
+ $answer_points += $results_array['points'];
1615
+
1616
+ // If the user's answer was correct
1617
+ if ( 'correct' == $results_array['correct'] ) {
1618
+ $total_correct += 1;
1619
+ $correct_status = 'correct';
1620
+ }
1621
+ $user_answer = $results_array['user_text'];
1622
+ $correct_answer = $results_array['correct_text'];
1623
+ $user_compare_text = isset( $results_array['user_compare_text'] ) ? $results_array['user_compare_text'] : '';
1624
+ if ( trim( $user_answer ) != '' ) {
1625
+ if ( $user_answer != 'No Answer Provided' ) {
1626
+ $attempted_question++;
1627
+ }
1628
+ }
1629
+ // If a comment was submitted
1630
+ if ( isset( $_POST[ 'mlwComment' . $question['question_id'] ] ) ) {
1631
+ $comment = sanitize_textarea_field( htmlspecialchars( stripslashes( $_POST[ 'mlwComment' . $question['question_id'] ] ), ENT_QUOTES ) );
1632
+ } else {
1633
+ $comment = '';
1634
+ }
1635
+
1636
+ // Get text for question
1637
+ $question_text = $question['question_name'];
1638
+ if ( isset( $results_array['question_text'] ) ) {
1639
+ $question_text = $results_array['question_text'];
1640
+ }
1641
+
1642
+ // Save question data into new array in our array
1643
+ $question_data[] = apply_filters(
1644
+ 'qmn_answer_array',
1645
+ array(
1646
+ $question_text,
1647
+ htmlspecialchars( $user_answer, ENT_QUOTES ),
1648
+ htmlspecialchars( $correct_answer, ENT_QUOTES ),
1649
+ $comment,
1650
+ 'correct' => $correct_status,
1651
+ 'id' => $question['question_id'],
1652
+ 'points' => $answer_points,
1653
+ 'category' => $question['category'],
1654
+ 'question_type' => $question['question_type_new'],
1655
+ 'question_title' => isset( $question['settings']['question_title'] ) ? $question['settings']['question_title'] : '',
1656
+ 'user_compare_text' => $user_compare_text,
1657
+ ),
1658
+ $options,
1659
+ $quiz_data
1660
+ );
1661
+ }
1662
+ break;
1663
+ }
1664
+ }
1665
+ }
1666
+ }
1667
+
1668
+ // Calculate Total Percent Score And Average Points Only If Total Questions Doesn't Equal Zero To Avoid Division By Zero Error
1669
+ if ( 0 !== $total_questions ) {
1670
+ $total_score = round( ( ( $total_correct / $total_questions ) * 100 ), 2 );
1671
+ } else {
1672
+ $total_score = 0;
1673
+ }
1674
+
1675
+ // Return array to be merged with main user response array
1676
+ return array(
1677
+ 'total_points' => $points_earned,
1678
+ 'total_score' => $total_score,
1679
+ 'total_correct' => $total_correct,
1680
+ 'total_questions' => $total_questions,
1681
+ 'question_answers_display' => '', // Kept for backwards compatibility
1682
+ 'question_answers_array' => $question_data,
1683
+ 'total_possible_points' => $total_possible_points,
1684
+ 'total_attempted_questions' => $attempted_question,
1685
+ );
1686
+ }
1687
+
1688
+ /**
1689
+ * Retrieves User's Comments
1690
+ *
1691
+ * Checks to see if the user left a comment and returns the comment
1692
+ *
1693
+ * @since 4.0.0
1694
+ * @param array $qmn_quiz_options The database row of the quiz
1695
+ * @param array $qmn_array_for_variables The array of results for the quiz
1696
+ * @return string The user's comments
1697
+ */
1698
+ public function check_comment_section( $qmn_quiz_options, $qmn_array_for_variables ) {
1699
+ $qmn_quiz_comments = '';
1700
+ if ( isset( $_POST['mlwQuizComments'] ) ) {
1701
+ $qmn_quiz_comments = esc_textarea( stripslashes( $_POST['mlwQuizComments'] ) );
1702
+ }
1703
+ return apply_filters( 'qmn_returned_comments', $qmn_quiz_comments, $qmn_quiz_options, $qmn_array_for_variables );
1704
+ }
1705
+
1706
+ /**
1707
+ * Displays Results Text
1708
+ *
1709
+ * @since 4.0.0
1710
+ * @deprecated 6.1.0 Use the newer results page class instead.
1711
+ * @param array $options The quiz settings.
1712
+ * @param array $response_data The array of results for the quiz.
1713
+ * @return string The contents for the results text
1714
+ */
1715
+ public function display_results_text( $options, $response_data ) {
1716
+ return QSM_Results_Pages::generate_pages( $response_data );
1717
+ }
1718
+
1719
+ /**
1720
+ * Displays social media buttons
1721
+ *
1722
+ * @deprecated 6.1.0 Use the social media template variables instead.
1723
+ * @since 4.0.0
1724
+ * @param array $qmn_quiz_options The database row of the quiz.
1725
+ * @param array $qmn_array_for_variables The array of results for the quiz.
1726
+ * @return string The content of the social media button section
1727
+ */
1728
+ public function display_social( $qmn_quiz_options, $qmn_array_for_variables ) {
1729
+ $social_display = '';
1730
+ if ( $qmn_quiz_options->social_media == 1 ) {
1731
+ $settings = (array) get_option( 'qmn-settings' );
1732
+ $facebook_app_id = '594986844960937';
1733
+ if ( isset( $settings['facebook_app_id'] ) ) {
1734
+ $facebook_app_id = esc_js( $settings['facebook_app_id'] );
1735
+ }
1736
+
1737
+ // Loads Social Media Text.
1738
+ $qmn_social_media_text = '';
1739
+ if ( is_serialized( $qmn_quiz_options->social_media_text ) && is_array( @unserialize( $qmn_quiz_options->social_media_text ) ) ) {
1740
+ $qmn_social_media_text = @unserialize( $qmn_quiz_options->social_media_text );
1741
+ } else {
1742
+ $qmn_social_media_text = array(
1743
+ 'twitter' => $qmn_quiz_options->social_media_text,
1744
+ 'facebook' => $qmn_quiz_options->social_media_text,
1745
+ );
1746
+ }
1747
+ $qmn_social_media_text['twitter'] = apply_filters( 'mlw_qmn_template_variable_results_page', $qmn_social_media_text['twitter'], $qmn_array_for_variables );
1748
+ $qmn_social_media_text['facebook'] = apply_filters( 'mlw_qmn_template_variable_results_page', $qmn_social_media_text['facebook'], $qmn_array_for_variables );
1749
+ $social_display .= "<br /><a class=\"mlw_qmn_quiz_link\" onclick=\"qmnSocialShare('facebook', '" . esc_js( $qmn_social_media_text['facebook'] ) . "', '" . esc_js( $qmn_quiz_options->quiz_name ) . "', '$facebook_app_id');\">Facebook</a><a class=\"mlw_qmn_quiz_link\" onclick=\"qmnSocialShare('twitter', '" . esc_js( $qmn_social_media_text['twitter'] ) . "', '" . esc_js( $qmn_quiz_options->quiz_name ) . "');\">Twitter</a><br />";
1750
+ }
1751
+ return apply_filters( 'qmn_returned_social_buttons', $social_display, $qmn_quiz_options, $qmn_array_for_variables );
1752
+ }
1753
+
1754
+ /**
1755
+ * Send User Email
1756
+ *
1757
+ * Prepares the email to the user and then sends the email
1758
+ *
1759
+ * @deprecated 6.2.0 Use the newer QSM_Emails class instead.
1760
+ * @since 4.0.0
1761
+ * @param array $qmn_quiz_options The database row of the quiz
1762
+ * @param array $qmn_array_for_variables The array of results for the quiz
1763
+ */
1764
+ public function send_user_email( $qmn_quiz_options, $qmn_array_for_variables ) {
1765
+ add_filter( 'wp_mail_content_type', 'mlw_qmn_set_html_content_type' );
1766
+ $mlw_message = '';
1767
+
1768
+ // Check if this quiz has user emails turned on
1769
+ if ( $qmn_quiz_options->send_user_email == '0' ) {
1770
+
1771
+ // Make sure that the user filled in the email field
1772
+ if ( $qmn_array_for_variables['user_email'] != '' ) {
1773
+
1774
+ // Prepare from email and name
1775
+ $from_email_array = maybe_unserialize( $qmn_quiz_options->email_from_text );
1776
+ if ( ! isset( $from_email_array['from_email'] ) ) {
1777
+ $from_email_array = array(
1778
+ 'from_name' => $qmn_quiz_options->email_from_text,
1779
+ 'from_email' => $qmn_quiz_options->admin_email,
1780
+ 'reply_to' => 1,
1781
+ );
1782
+ }
1783
+
1784
+ if ( ! is_email( $from_email_array['from_email'] ) ) {
1785
+ if ( is_email( $qmn_quiz_options->admin_email ) ) {
1786
+ $from_email_array['from_email'] = $qmn_quiz_options->admin_email;
1787
+ } else {
1788
+ $from_email_array['from_email'] = get_option( 'admin_email ', 'test@example.com' );
1789
+ }
1790
+ }
1791
+
1792
+ // Prepare email attachments
1793
+ $attachments = array();
1794
+ $attachments = apply_filters( 'qsm_user_email_attachments', $attachments, $qmn_array_for_variables );
1795
+
1796
+ if ( is_serialized( $qmn_quiz_options->user_email_template ) && is_array( @unserialize( $qmn_quiz_options->user_email_template ) ) ) {
1797
+
1798
+ $mlw_user_email_array = @unserialize( $qmn_quiz_options->user_email_template );
1799
+
1800
+ // Cycle through emails
1801
+ foreach ( $mlw_user_email_array as $mlw_each ) {
1802
+
1803
+ // Generate Email Subject
1804
+ if ( ! isset( $mlw_each[3] ) ) {
1805
+ $mlw_each[3] = 'Quiz Results For %QUIZ_NAME';
1806
+ }
1807
+ $mlw_each[3] = apply_filters( 'mlw_qmn_template_variable_results_page', $mlw_each[3], $qmn_array_for_variables );
1808
+
1809
+ // Check to see if default
1810
+ if ( $mlw_each[0] == 0 && $mlw_each[1] == 0 ) {
1811
+ $mlw_message = htmlspecialchars_decode( $mlw_each[2], ENT_QUOTES );
1812
+ $mlw_message = apply_filters( 'mlw_qmn_template_variable_results_page', $mlw_message, $qmn_array_for_variables );
1813
+ $mlw_message = str_replace( "\n", '<br>', $mlw_message );
1814
+ $mlw_message = str_replace( '<br/>', '<br>', $mlw_message );
1815
+ $mlw_message = str_replace( '<br />', '<br>', $mlw_message );
1816
+ $mlw_headers = 'From: ' . $from_email_array['from_name'] . ' <' . $from_email_array['from_email'] . '>' . "\r\n";
1817
+ wp_mail( $qmn_array_for_variables['user_email'], $mlw_each[3], $mlw_message, $mlw_headers, $attachments );
1818
+ break;
1819
+ } else {
1820
+
1821
+ // Check to see if this quiz uses points and check if the points earned falls in the point range for this email
1822
+ if ( $qmn_quiz_options->system == 1 && $qmn_array_for_variables['total_points'] >= $mlw_each[0] && $qmn_array_for_variables['total_points'] <= $mlw_each[1] ) {
1823
+ $mlw_message = htmlspecialchars_decode( $mlw_each[2], ENT_QUOTES );
1824
+ $mlw_message = apply_filters( 'mlw_qmn_template_variable_results_page', $mlw_message, $qmn_array_for_variables );
1825
+ $mlw_message = str_replace( "\n", '<br>', $mlw_message );
1826
+ $mlw_message = str_replace( '<br/>', '<br>', $mlw_message );
1827
+ $mlw_message = str_replace( '<br />', '<br>', $mlw_message );
1828
+ $mlw_headers = 'From: ' . $from_email_array['from_name'] . ' <' . $from_email_array['from_email'] . '>' . "\r\n";
1829
+ wp_mail( $qmn_array_for_variables['user_email'], $mlw_each[3], $mlw_message, $mlw_headers, $attachments );
1830
+ break;
1831
+ }
1832
+
1833
+ // Check to see if score fall in correct range
1834
+ if ( $qmn_quiz_options->system == 0 && $qmn_array_for_variables['total_score'] >= $mlw_each[0] && $qmn_array_for_variables['total_score'] <= $mlw_each[1] ) {
1835
+ $mlw_message = htmlspecialchars_decode( $mlw_each[2], ENT_QUOTES );
1836
+ $mlw_message = apply_filters( 'mlw_qmn_template_variable_results_page', $mlw_message, $qmn_array_for_variables );
1837
+ $mlw_message = str_replace( "\n", '<br>', $mlw_message );
1838
+ $mlw_message = str_replace( '<br/>', '<br>', $mlw_message );
1839
+ $mlw_message = str_replace( '<br />', '<br>', $mlw_message );
1840
+ $mlw_headers = 'From: ' . $from_email_array['from_name'] . ' <' . $from_email_array['from_email'] . '>' . "\r\n";
1841
+ wp_mail( $qmn_array_for_variables['user_email'], $mlw_each[3], $mlw_message, $mlw_headers, $attachments );
1842
+ break;
1843
+ }
1844
+ }
1845
+ }
1846
+ } else {
1847
+
1848
+ // Uses older email system still which was before different emails were created.
1849
+ $mlw_message = htmlspecialchars_decode( $qmn_quiz_options->user_email_template, ENT_QUOTES );
1850
+ $mlw_message = apply_filters( 'mlw_qmn_template_variable_results_page', $mlw_message, $qmn_array_for_variables );
1851
+ $mlw_message = str_replace( "\n", '<br>', $mlw_message );
1852
+ $mlw_message = str_replace( '<br/>', '<br>', $mlw_message );
1853
+ $mlw_message = str_replace( '<br />', '<br>', $mlw_message );
1854
+ $mlw_headers = 'From: ' . $from_email_array['from_name'] . ' <' . $from_email_array['from_email'] . '>' . "\r\n";
1855
+ wp_mail( $qmn_array_for_variables['user_email'], 'Quiz Results For ' . $qmn_quiz_options->quiz_name, $mlw_message, $mlw_headers, $attachments );
1856
+ }
1857
+ }
1858
+ }
1859
+ remove_filter( 'wp_mail_content_type', 'mlw_qmn_set_html_content_type' );
1860
+ }
1861
+
1862
+ /**
1863
+ * Send Admin Email
1864
+ *
1865
+ * Prepares the email to the admin and then sends the email
1866
+ *
1867
+ * @deprecated 6.2.0 Use the newer QSM_Emails class instead.
1868
+ * @since 4.0.0
1869
+ * @param array $qmn_quiz_options The database row of the quiz
1870
+ * @param arrar $qmn_array_for_variables The array of results for the quiz
1871
+ */
1872
+ public function send_admin_email( $qmn_quiz_options, $qmn_array_for_variables ) {
1873
+ // Switch email type to HTML
1874
+ add_filter( 'wp_mail_content_type', 'mlw_qmn_set_html_content_type' );
1875
+
1876
+ $mlw_message = '';
1877
+ if ( $qmn_quiz_options->send_admin_email == '0' ) {
1878
+ if ( $qmn_quiz_options->admin_email != '' ) {
1879
+ $from_email_array = maybe_unserialize( $qmn_quiz_options->email_from_text );
1880
+ if ( ! isset( $from_email_array['from_email'] ) ) {
1881
+ $from_email_array = array(
1882
+ 'from_name' => $qmn_quiz_options->email_from_text,
1883
+ 'from_email' => $qmn_quiz_options->admin_email,
1884
+ 'reply_to' => 1,
1885
+ );
1886
+ }
1887
+
1888
+ if ( ! is_email( $from_email_array['from_email'] ) ) {
1889
+ if ( is_email( $qmn_quiz_options->admin_email ) ) {
1890
+ $from_email_array['from_email'] = $qmn_quiz_options->admin_email;
1891
+ } else {
1892
+ $from_email_array['from_email'] = get_option( 'admin_email ', 'test@example.com' );
1893
+ }
1894
+ }
1895
+
1896
+ $mlw_message = '';
1897
+ $mlw_subject = '';
1898
+ if ( is_serialized( $qmn_quiz_options->admin_email_template ) && is_array( @unserialize( $qmn_quiz_options->admin_email_template ) ) ) {
1899
+ $mlw_admin_email_array = @unserialize( $qmn_quiz_options->admin_email_template );
1900
+
1901
+ // Cycle through landing pages
1902
+ foreach ( $mlw_admin_email_array as $mlw_each ) {
1903
+
1904
+ // Generate Email Subject
1905
+ if ( ! isset( $mlw_each['subject'] ) ) {
1906
+ $mlw_each['subject'] = 'Quiz Results For %QUIZ_NAME';
1907
+ }
1908
+ $mlw_each['subject'] = apply_filters( 'mlw_qmn_template_variable_results_page', $mlw_each['subject'], $qmn_array_for_variables );
1909
+
1910
+ // Check to see if default
1911
+ if ( $mlw_each['begin_score'] == 0 && $mlw_each['end_score'] == 0 ) {
1912
+ $mlw_message = htmlspecialchars_decode( $mlw_each['message'], ENT_QUOTES );
1913
+ $mlw_message = apply_filters( 'mlw_qmn_template_variable_results_page', $mlw_message, $qmn_array_for_variables );
1914
+ $mlw_message = str_replace( "\n", '<br>', $mlw_message );
1915
+ $mlw_message = str_replace( '<br/>', '<br>', $mlw_message );
1916
+ $mlw_message = str_replace( '<br />', '<br>', $mlw_message );
1917
+ $mlw_subject = $mlw_each['subject'];
1918
+ break;
1919
+ } else {
1920
+ // Check to see if points fall in correct range
1921
+ if ( $qmn_quiz_options->system == 1 && $qmn_array_for_variables['total_points'] >= $mlw_each['begin_score'] && $qmn_array_for_variables['total_points'] <= $mlw_each['end_score'] ) {
1922
+ $mlw_message = htmlspecialchars_decode( $mlw_each['message'], ENT_QUOTES );
1923
+ $mlw_message = apply_filters( 'mlw_qmn_template_variable_results_page', $mlw_message, $qmn_array_for_variables );
1924
+ $mlw_message = str_replace( "\n", '<br>', $mlw_message );
1925
+ $mlw_message = str_replace( '<br/>', '<br>', $mlw_message );
1926
+ $mlw_message = str_replace( '<br />', '<br>', $mlw_message );
1927
+ $mlw_subject = $mlw_each['subject'];
1928
+ break;
1929
+ }
1930
+
1931
+ // Check to see if score fall in correct range
1932
+ if ( $qmn_quiz_options->system == 0 && $qmn_array_for_variables['total_score'] >= $mlw_each['begin_score'] && $qmn_array_for_variables['total_score'] <= $mlw_each['end_score'] ) {
1933
+ $mlw_message = htmlspecialchars_decode( $mlw_each['message'], ENT_QUOTES );
1934
+ $mlw_message = apply_filters( 'mlw_qmn_template_variable_results_page', $mlw_message, $qmn_array_for_variables );
1935
+ $mlw_message = str_replace( "\n", '<br>', $mlw_message );
1936
+ $mlw_message = str_replace( '<br/>', '<br>', $mlw_message );
1937
+ $mlw_message = str_replace( '<br />', '<br>', $mlw_message );
1938
+ $mlw_subject = $mlw_each['subject'];
1939
+ break;
1940
+ }
1941
+ }
1942
+ }
1943
+ } else {
1944
+ $mlw_message = htmlspecialchars_decode( $qmn_quiz_options->admin_email_template, ENT_QUOTES );
1945
+ $mlw_message = apply_filters( 'mlw_qmn_template_variable_results_page', $mlw_message, $qmn_array_for_variables );
1946
+ $mlw_message = str_replace( "\n", '<br>', $mlw_message );
1947
+ $mlw_message = str_replace( '<br/>', '<br>', $mlw_message );
1948
+ $mlw_message = str_replace( '<br />', '<br>', $mlw_message );
1949
+ $mlw_subject = 'Quiz Results For ' . $qmn_quiz_options->quiz_name;
1950
+ }
1951
+ }
1952
+ if ( get_option( 'mlw_advert_shows' ) == 'true' ) {
1953
+ $mlw_message .= '<br>This email was generated by the Quiz And Survey Master plugin';
1954
+ }
1955
+ $headers = array(
1956
+ 'From: ' . $from_email_array['from_name'] . ' <' . $from_email_array['from_email'] . '>',
1957
+ );
1958
+ if ( $from_email_array['reply_to'] == 0 ) {
1959
+ $headers[] = 'Reply-To: ' . $qmn_array_for_variables['user_name'] . ' <' . $qmn_array_for_variables['user_email'] . '>';
1960
+ }
1961
+ $admin_emails = explode( ',', $qmn_quiz_options->admin_email );
1962
+ foreach ( $admin_emails as $admin_email ) {
1963
+ if ( is_email( $admin_email ) ) {
1964
+ wp_mail( $admin_email, $mlw_subject, $mlw_message, $headers );
1965
+ }
1966
+ }
1967
+ }
1968
+
1969
+ // Remove HTML type for emails
1970
+ remove_filter( 'wp_mail_content_type', 'mlw_qmn_set_html_content_type' );
1971
+ }
1972
+
1973
+ /**
1974
+ * Returns the quiz taker's IP if IP collection is enabled
1975
+ *
1976
+ * @since 5.3.0
1977
+ * @return string The IP address or a phrase if not collected
1978
+ */
1979
+ private function get_user_ip() {
1980
+ $ip = __( 'Not collected', 'quiz-master-next' );
1981
+ $settings = (array) get_option( 'qmn-settings' );
1982
+ $ip_collection = '0';
1983
+ if ( isset( $settings['ip_collection'] ) ) {
1984
+ $ip_collection = $settings['ip_collection'];
1985
+ }
1986
+ if ( '1' != $ip_collection ) {
1987
+ if ( $_SERVER['REMOTE_ADDR'] ) {
1988
+ $ip = $_SERVER['REMOTE_ADDR'];
1989
+ } else {
1990
+ $ip = __( 'Unknown', 'quiz-master-next' );
1991
+ }
1992
+
1993
+ if ( getenv( 'HTTP_CLIENT_IP' ) ) {
1994
+ $ip = getenv( 'HTTP_CLIENT_IP' );
1995
+ } elseif ( getenv( 'HTTP_X_FORWARDED_FOR' ) ) {
1996
+ $ip = getenv( 'HTTP_X_FORWARDED_FOR' );
1997
+ } elseif ( getenv( 'HTTP_X_FORWARDED' ) ) {
1998
+ $ip = getenv( 'HTTP_X_FORWARDED' );
1999
+ } elseif ( getenv( 'HTTP_FORWARDED_FOR' ) ) {
2000
+ $ip = getenv( 'HTTP_FORWARDED_FOR' );
2001
+ } elseif ( getenv( 'HTTP_FORWARDED' ) ) {
2002
+ $ip = getenv( 'HTTP_FORWARDED' );
2003
+ } elseif ( getenv( 'REMOTE_ADDR' ) ) {
2004
+ $ip = getenv( 'REMOTE_ADDR' );
2005
+ } else {
2006
+ $ip = $_SERVER['REMOTE_ADDR'];
2007
+ }
2008
+ }
2009
+ return $ip;
2010
+ }
2011
+
2012
+ /**
2013
+ * Determines whether a plugin is active.
2014
+ *
2015
+ * @since 6.4.11
2016
+ *
2017
+ * @param string $plugin Path to the plugin file relative to the plugins directory.
2018
+ * @return bool True, if in the active plugins list. False, not in the list.
2019
+ */
2020
+ private function qsm_plugin_active( $plugin ) {
2021
+ return in_array( $plugin, (array) get_option( 'active_plugins', array() ) ) || $this->qsm_plugin_active_for_network( $plugin );
2022
+ }
2023
+
2024
+ /**
2025
+ * Determines whether the plugin is active for the entire network.
2026
+ *
2027
+ * @since 6.4.11
2028
+ *
2029
+ * @param string $plugin Path to the plugin file relative to the plugins directory.
2030
+ * @return bool True if active for the network, otherwise false.
2031
+ */
2032
+ private function qsm_plugin_active_for_network() {
2033
+ if ( ! is_multisite() ) {
2034
+ return false;
2035
+ }
2036
+
2037
+ $plugins = get_site_option( 'active_sitewide_plugins' );
2038
+ if ( isset( $plugins[ $plugin ] ) ) {
2039
+ return true;
2040
+ }
2041
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2042
  return false;
2043
  }
2044
 
2045
+ /**
2046
+ * Include background process files
2047
+ *
2048
+ * @singce 7.0
2049
+ */
2050
+ public function qsm_process_background_email() {
2051
+ require_once plugin_dir_path( __FILE__ ) . 'class-qmn-background-process.php';
2052
+ $this->qsm_background_email = new QSM_Background_Request();
2053
+ }
2054
+
2055
+ /**
2056
+ * Convert editor text into respective shortcodes
2057
+ *
2058
+ * @since 7.0.2
2059
+ * @param string $editor_text
2060
+ */
2061
+ public function qsm_convert_editor_text_to_shortcode( $editor_text ) {
2062
+ global $wp_embed;
2063
+ $editor_text = $wp_embed->run_shortcode( $editor_text );
2064
+ $editor_text = preg_replace( '/\s*[a-zA-Z\/\/:\.]*youtube.com\/watch\?v=([a-zA-Z0-9\-_]+)([a-zA-Z0-9\/\*\-\_\?\&\;\%\=\.]*)/i', '<iframe width="420" height="315" src="//www.youtube.com/embed/$1" frameborder="0" allowfullscreen></iframe>', $editor_text );
2065
+ $allowed_html = wp_kses_allowed_html( 'post' );
2066
+ return do_shortcode( wp_kses( $editor_text, $allowed_html ) );
2067
  }
2068
 
2069
+ /**
2070
+ * Get attachment id from attachment url
2071
+ *
2072
+ * @since 7.1.2
2073
+ *
2074
+ * @global obj $wpdb
2075
+ * @param url $attachment_url
2076
+ * @return int
2077
+ */
2078
+ public function qsm_get_attachment_id_from_url( $attachment_url = '' ) {
2079
+
2080
+ global $wpdb;
2081
+ $attachment_id = false;
2082
+
2083
+ // If there is no url, return.
2084
+ if ( '' == $attachment_url ) {
2085
+ return;
2086
+ }
2087
+
2088
+ // Get the upload directory paths
2089
+ $upload_dir_paths = wp_upload_dir();
2090
+
2091
+ // Make sure the upload path base directory exists in the attachment URL, to verify that we're working with a media library image
2092
+ if ( false !== strpos( $attachment_url, $upload_dir_paths['baseurl'] ) ) {
2093
+
2094
+ // If this is the URL of an auto-generated thumbnail, get the URL of the original image
2095
+ $attachment_url = preg_replace( '/-\d+x\d+(?=\.(jpg|jpeg|png|gif)$)/i', '', $attachment_url );
2096
+
2097
+ // Remove the upload path base directory from the attachment URL
2098
+ $attachment_url = str_replace( $upload_dir_paths['baseurl'] . '/', '', $attachment_url );
2099
+
2100
+ // Finally, run a custom database query to get the attachment ID from the modified attachment URL
2101
+ $attachment_id = $wpdb->get_var( $wpdb->prepare( "SELECT wposts.ID FROM $wpdb->posts wposts, $wpdb->postmeta wpostmeta WHERE wposts.ID = wpostmeta.post_id AND wpostmeta.meta_key = '_wp_attached_file' AND wpostmeta.meta_value = '%s' AND wposts.post_type = 'attachment'", $attachment_url ) );
2102
+
2103
+ }
2104
+
2105
+ return $attachment_id;
2106
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2107
  }
2108
 
2109
  global $qmnQuizManager;
2110
  $qmnQuizManager = new QMNQuizManager();
2111
 
2112
+ add_filter( 'qmn_begin_shortcode', 'qmn_require_login_check', 10, 3 );
2113
+
2114
+ function qmn_require_login_check( $display, $qmn_quiz_options, $qmn_array_for_variables ) {
2115
+ global $qmn_allowed_visit;
2116
+ if ( $qmn_quiz_options->require_log_in == 1 && ! is_user_logged_in() ) {
2117
+ $qmn_allowed_visit = false;
2118
+ if ( isset( $qmn_quiz_options->require_log_in_text ) && $qmn_quiz_options->require_log_in_text != '' ) {
2119
+ $mlw_message = wpautop( htmlspecialchars_decode( $qmn_quiz_options->require_log_in_text, ENT_QUOTES ) );
2120
+ } else {
2121
+ $mlw_message = wpautop( htmlspecialchars_decode( $qmn_quiz_options->require_log_in_text, ENT_QUOTES ) );
2122
+ }
2123
+ $mlw_message = apply_filters( 'mlw_qmn_template_variable_quiz_page', $mlw_message, $qmn_array_for_variables );
2124
+ $mlw_message = str_replace( "\n", '<br>', $mlw_message );
2125
+ // $display .= do_shortcode($mlw_message);
2126
+ $display .= do_shortcode( $mlw_message );
2127
+ $display .= wp_login_form( array( 'echo' => false ) );
2128
+ }
2129
+ return $display;
2130
  }
2131
 
2132
+ add_filter( 'qmn_begin_shortcode', 'qsm_scheduled_timeframe_check', 99, 3 );
2133
 
2134
  /**
2135
  * @since 7.0.0 Added the condition for start time ( end time blank ) and end time ( start time blank ).
2136
  *
2137
  * @global boolean $qmn_allowed_visit
2138
+ * @param HTML $display
2139
  * @param Object $options
2140
+ * @param Array $variable_data
2141
  * @return HTML This function check the time frame of quiz.
2142
  */
2143
+ function qsm_scheduled_timeframe_check( $display, $options, $variable_data ) {
2144
+ global $qmn_allowed_visit;
2145
+
2146
+ $checked_pass = false;
2147
+ // Checks if the start and end dates have data
2148
+ if ( ! empty( $options->scheduled_time_start ) && ! empty( $options->scheduled_time_end ) ) {
2149
+ $start = strtotime( $options->scheduled_time_start );
2150
+ $end = strtotime( $options->scheduled_time_end );
2151
+ if ( strpos( $options->scheduled_time_end, ':' ) === false || strpos( $options->scheduled_time_end, '00:00' ) !== false ) {
2152
+ $end = strtotime( $options->scheduled_time_end ) + 86399;
2153
+ }
2154
+
2155
+ $current_time = strtotime( current_time( 'm/d/Y H:i' ) );
2156
+ // Checks if the current timestamp is outside of scheduled timeframe
2157
+ if ( $current_time < $start || $current_time > $end ) {
2158
+ $checked_pass = true;
2159
+ }
2160
+ }
2161
+ if ( ! empty( $options->scheduled_time_start ) && empty( $options->scheduled_time_end ) ) {
2162
+ $start = new DateTime( $options->scheduled_time_start );
2163
+ $current_datetime = new DateTime( current_time( 'm/d/Y H:i' ) );
2164
+ if ( $current_datetime < $start ) {
2165
+ $checked_pass = true;
2166
+ }
2167
+ }
2168
+ if ( empty( $options->scheduled_time_start ) && ! empty( $options->scheduled_time_end ) ) {
2169
+ $end = new DateTime( $options->scheduled_time_end );
2170
+ $current_datetime = new DateTime( current_time( 'm/d/Y H:i' ) );
2171
+ if ( $current_datetime > $end ) {
2172
+ $checked_pass = true;
2173
+ }
2174
+ }
2175
+ if ( $checked_pass == true ) {
2176
+ $qmn_allowed_visit = false;
2177
+ $message = wpautop( htmlspecialchars_decode( $options->scheduled_timeframe_text, ENT_QUOTES ) );
2178
+ $message = apply_filters( 'mlw_qmn_template_variable_quiz_page', $message, $variable_data );
2179
+ $display .= str_replace( "\n", '<br>', $message );
2180
+ }
2181
+ return $display;
2182
  }
2183
 
2184
+ add_filter( 'qmn_begin_shortcode', 'qmn_total_user_tries_check', 10, 3 );
2185
 
2186
  /**
2187
  * Checks if user has already reach the user limit of the quiz
2188
  *
2189
  * @since 5.0.0
2190
  * @param string $display The HTML displayed for the quiz
2191
+ * @param array $qmn_quiz_options The settings for the quiz
2192
+ * @param array $qmn_array_for_variables The array of data by the quiz
2193
  * @return string The altered HTML display for the quiz
2194
  */
2195
+ function qmn_total_user_tries_check( $display, $qmn_quiz_options, $qmn_array_for_variables ) {
2196
+
2197
+ global $qmn_allowed_visit;
2198
+ if ( $qmn_quiz_options->total_user_tries != 0 ) {
2199
+
2200
+ // Prepares the variables
2201
+ global $wpdb;
2202
+ $mlw_qmn_user_try_count = 0;
2203
+
2204
+ // Checks if the user is logged in. If so, check by user id. If not, check by IP.
2205
+ if ( is_user_logged_in() ) {
2206
+ $current_user = wp_get_current_user();
2207
+ $mlw_qmn_user_try_count = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM {$wpdb->prefix}mlw_results WHERE user=%d AND deleted=0 AND quiz_id=%d", $current_user->ID, $qmn_array_for_variables['quiz_id'] ) );
2208
+ } else {
2209
+ $mlw_qmn_user_try_count = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM {$wpdb->prefix}mlw_results WHERE user_ip=%s AND deleted=0 AND quiz_id=%d", $qmn_array_for_variables['user_ip'], $qmn_array_for_variables['quiz_id'] ) );
2210
+ }
2211
+
2212
+ // If user has already reached the limit for this quiz
2213
+ if ( $mlw_qmn_user_try_count >= $qmn_quiz_options->total_user_tries ) {
2214
+
2215
+ // Stops the quiz and prepares entered text
2216
+ $qmn_allowed_visit = false;
2217
+ $mlw_message = wpautop( htmlspecialchars_decode( $qmn_quiz_options->total_user_tries_text, ENT_QUOTES ) );
2218
+ $mlw_message = apply_filters( 'mlw_qmn_template_variable_quiz_page', $mlw_message, $qmn_array_for_variables );
2219
+ $display .= $mlw_message;
2220
+ }
2221
+ }
2222
+ return $display;
2223
  }
2224
 
2225
+ add_filter( 'qmn_begin_quiz', 'qmn_total_tries_check', 10, 3 );
2226
+
2227
+ function qmn_total_tries_check( $display, $qmn_quiz_options, $qmn_array_for_variables ) {
2228
+ global $qmn_allowed_visit;
2229
+ if ( $qmn_quiz_options->limit_total_entries != 0 ) {
2230
+ global $wpdb;
2231
+ $mlw_qmn_entries_count = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(quiz_id) FROM {$wpdb->prefix}mlw_results WHERE deleted=0 AND quiz_id=%d", $qmn_array_for_variables['quiz_id'] ) );
2232
+ if ( $mlw_qmn_entries_count >= $qmn_quiz_options->limit_total_entries ) {
2233
+ $mlw_message = wpautop( htmlspecialchars_decode( $qmn_quiz_options->limit_total_entries_text, ENT_QUOTES ) );
2234
+ $mlw_message = apply_filters( 'mlw_qmn_template_variable_quiz_page', $mlw_message, $qmn_array_for_variables );
2235
+ $display .= $mlw_message;
2236
+ $qmn_allowed_visit = false;
2237
+ }
2238
+ }
2239
+ return $display;
2240
  }
2241
 
2242
+ add_filter( 'qmn_begin_quiz', 'qmn_pagination_check', 10, 3 );
2243
+
2244
+ function qmn_pagination_check( $display, $qmn_quiz_options, $qmn_array_for_variables ) {
2245
+ if ( $qmn_quiz_options->pagination != 0 ) {
2246
+ global $wpdb;
2247
+ global $qmn_json_data;
2248
+ $total_questions = 0;
2249
+ if ( $qmn_quiz_options->question_from_total != 0 ) {
2250
+ $total_questions = $qmn_quiz_options->question_from_total;
2251
+ } else {
2252
+ $questions = QSM_Questions::load_questions_by_pages( $qmn_quiz_options->quiz_id );
2253
+ $total_questions = count( $questions );
2254
+ }
2255
+ // $display .= "<style>.quiz_section { display: none; }</style>";
2256
+
2257
+ $qmn_json_data['pagination'] = array(
2258
+ 'amount' => $qmn_quiz_options->pagination,
2259
+ 'section_comments' => $qmn_quiz_options->comment_section,
2260
+ 'total_questions' => $total_questions,
2261
+ 'previous_text' => $qmn_quiz_options->previous_button_text,
2262
+ 'next_text' => $qmn_quiz_options->next_button_text,
2263
+ );
2264
+ }
2265
+ return $display;
2266
  }
2267
 
2268
+ add_filter( 'qmn_begin_quiz_form', 'qmn_timer_check', 15, 3 );
2269
 
2270
+ function qmn_timer_check( $display, $qmn_quiz_options, $qmn_array_for_variables ) {
2271
+ global $qmn_allowed_visit;
2272
+ global $qmn_json_data;
2273
+ if ( $qmn_allowed_visit && $qmn_quiz_options->timer_limit != 0 ) {
2274
+ $qmn_json_data['timer_limit'] = $qmn_quiz_options->timer_limit;
2275
+ $display .= '<div style="display:none;" id="mlw_qmn_timer" class="mlw_qmn_timer"></div>';
2276
+ }
2277
+ return $display;
2278
  }
2279
 
2280
+ add_filter( 'qmn_begin_quiz', 'qmn_update_views', 10, 3 );
2281
+
2282
+ function qmn_update_views( $display, $qmn_quiz_options, $qmn_array_for_variables ) {
2283
+ global $wpdb;
2284
+ $mlw_views = $qmn_quiz_options->quiz_views;
2285
+ $mlw_views += 1;
2286
+ $results = $wpdb->update(
2287
+ $wpdb->prefix . 'mlw_quizzes',
2288
+ array(
2289
+ 'quiz_views' => $mlw_views,
2290
+ ),
2291
+ array( 'quiz_id' => $qmn_array_for_variables['quiz_id'] ),
2292
+ array(
2293
+ '%d',
2294
+ ),
2295
+ array( '%d' )
2296
+ );
2297
+ return $display;
2298
  }
2299
 
2300
+ add_filter( 'qmn_begin_results', 'qmn_update_taken', 10, 3 );
2301
+
2302
+ function qmn_update_taken( $display, $qmn_quiz_options, $qmn_array_for_variables ) {
2303
+ global $wpdb;
2304
+ $mlw_taken = $qmn_quiz_options->quiz_taken;
2305
+ $mlw_taken += 1;
2306
+ $results = $wpdb->update(
2307
+ $wpdb->prefix . 'mlw_quizzes',
2308
+ array(
2309
+ 'quiz_taken' => $mlw_taken,
2310
+ ),
2311
+ array( 'quiz_id' => $qmn_array_for_variables['quiz_id'] ),
2312
+ array(
2313
+ '%d',
2314
+ ),
2315
+ array( '%d' )
2316
+ );
2317
+ return $display;
2318
  }
2319
 
2320
  /*
2323
 
2324
  function mlw_qmn_set_html_content_type() {
2325
 
2326
+ return 'text/html';
2327
  }
2328
 
2329
  function qsm_time_in_milliseconds() {
2330
+ return round( microtime( true ) * 1000 );
2331
  }
2332
 
2333
+ add_filter(
2334
+ 'wp_video_extensions',
2335
+ function( $exts ) {
2336
+ $exts[] = 'mov';
2337
+ $exts[] = 'avi';
2338
+ $exts[] = 'wmv';
2339
+ return $exts;
2340
+ }
2341
+ );
php/shortcodes.php CHANGED
@@ -4,41 +4,55 @@
4
  * Displays a link to a quiz using ID. Used [qsm_link id=1]Click Here[/qsm_link]
5
  *
6
  * @since 5.1.0
7
- * @param array $atts Attributes from add_shortcode function
8
  * @param string $content The text to be used for the link
9
  * @return string The HTML the shortcode will be replaced with
10
  */
11
- function qsm_quiz_link_shortcode($atts, $content = '') {
12
- extract(shortcode_atts(array(
13
- 'id' => 0,
14
- 'class' => '',
15
- 'target' => ''
16
- ), $atts));
17
- $id = intval($id);
18
-
19
- // Find the permalink by finding the post with the meta_key 'quiz_id' of supplied quiz
20
- $permalink = '';
21
- $my_query = new WP_Query(array('post_type' => 'qsm_quiz', 'meta_key' => 'quiz_id', 'meta_value' => $id, 'posts_per_page' => 1, 'post_status' => 'publish'));
22
- if ($my_query->have_posts()) {
23
- while ($my_query->have_posts()) {
24
- $my_query->the_post();
25
- $permalink = get_permalink();
26
- }
27
- }
28
- wp_reset_postdata();
29
-
30
- // Craft the target attribute if one is passed to shortcode
31
- $target_html = '';
32
- if (!empty($target)) {
33
- $target_html = "target='" . esc_attr($target) . "'";
34
- }
35
- return "<a href='" . esc_url($permalink) . "' class='" . esc_attr($class) . "' $target_html>" . esc_html($content) . "</a>";
 
 
 
 
 
 
 
 
 
 
 
 
 
36
  }
37
 
38
- add_shortcode('qsm_link', 'qsm_quiz_link_shortcode');
39
 
40
  /**
41
  * Displays a list of most recently created quizes [qsm_recent_quizzes]
 
42
  * @param - attrs - array of shortcode attributes - no_of_quizzes, include_future_quizzes
43
  * @param - no_of_quizzes - Number of most recent quizzes to be displayed (default 10)
44
  * @param - include_future_quizzes - Whether to display future scheduled quizzes or not - yes/no (default yes)
@@ -46,34 +60,34 @@ add_shortcode('qsm_link', 'qsm_quiz_link_shortcode');
46
  * @return string - list of quizzes
47
  * Shortcode call - [qsm_recent_quizzes no_of_quizzes=5 include_future_quizzes='no' ]
48
  */
49
- function qsm_display_recent_quizzes($attrs) {
50
-
51
- $no_of_quizzes = isset($attrs['no_of_quizzes']) ? $attrs['no_of_quizzes'] : 10;
52
- $include_future_quizzes = isset($attrs['include_future_quizzes']) ? $attrs['include_future_quizzes'] : true;
53
- global $wpdb;
54
- wp_enqueue_style('quizzes-list', plugins_url('../css/quizzes-list.css', __FILE__));
55
-
56
- $query = "SELECT quiz_id, quiz_name, quiz_settings FROM {$wpdb->prefix}mlw_quizzes WHERE deleted=0 ORDER BY quiz_id DESC";
57
- $quizzes = $wpdb->get_results($query);
58
- $result = '<div class="outer-con">';
59
- $i = 0;
60
- foreach ($quizzes as $quiz) {
61
- if ($i < $no_of_quizzes) {
62
- $setting = unserialize($quiz->quiz_settings);
63
- $options = unserialize($setting['quiz_options']);
64
-
65
- $start_date = $options['scheduled_time_start'];
66
- $end_date = $options['scheduled_time_end'];
67
- $today = date('m/d/Y');
68
- if ($end_date != '' && $end_date < $today)
69
- continue;
70
- else if ($include_future_quizzes == 'no' && $start_date > $today)
71
- continue;
72
- else {
73
- $title = $quiz->quiz_name;
74
- $id = $quiz->quiz_id;
75
- $url = do_shortcode("[qsm_link id='$id'] Take Quiz [/qsm_link]");
76
- $result .= "<div class='ind-quiz'>
77
  <div class='quiz-heading'>
78
  {$title}
79
  </div>
@@ -81,162 +95,164 @@ function qsm_display_recent_quizzes($attrs) {
81
  {$url}
82
  </div>
83
  </div>";
84
- $result .= "<div class='clear'></div>";
85
- $i++;
86
- }
87
- }
88
- }
89
- if ($i == 0)
90
- $result .= __("No quiz found", 'quiz-master-next');
91
- $result .= "</div>";
92
- return $result;
 
93
  }
94
 
95
- add_shortcode('qsm_recent_quizzes', 'qsm_display_recent_quizzes');
96
 
97
  /**
98
  * @since 6.4.1
99
  */
100
  function qsm_load_main_scripts() {
101
- wp_enqueue_script('jquery');
102
  }
103
 
104
- add_action('wp_enqueue_scripts', 'qsm_load_main_scripts');
105
 
106
  /**
107
  * Add Meta data for facebook share
 
108
  * @global obj $mlwQuizMasterNext
109
  * @global obj $wpdb
110
  * @global obj $wp_query
111
  */
112
  function qsm_generate_fb_header_metadata() {
113
- if (isset($_GET['result_id']) && $_GET['result_id'] != '') {
114
- $settings = (array) get_option('qmn-settings');
115
- $facebook_app_id = '594986844960937';
116
- if (isset($settings['facebook_app_id'])) {
117
- $facebook_app_id = esc_js($settings['facebook_app_id']);
118
- }
119
- global $mlwQuizMasterNext, $wpdb, $wp_query;
120
- $result_id = sanitize_text_field($_GET['result_id']);
121
- $results_data = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}mlw_results WHERE unique_id = %s", $result_id ) );
122
- if ($results_data) {
123
- // Prepare responses array.
124
- if (is_serialized($results_data->quiz_results) && is_array(@unserialize($results_data->quiz_results))) {
125
- $results = unserialize($results_data->quiz_results);
126
- if (!isset($results["contact"])) {
127
- $results["contact"] = array();
128
- }
129
- } else {
130
- $template = str_replace("%QUESTIONS_ANSWERS%", $results_data->quiz_results, $template);
131
- $template = str_replace("%TIMER%", '', $template);
132
- $template = str_replace("%COMMENT_SECTION%", '', $template);
133
- $results = array(
134
- 0,
135
- array(),
136
- '',
137
- 'contact' => array()
138
- );
139
- }
140
- // Prepare full results array.
141
- $results_array = array(
142
- 'quiz_id' => $results_data->quiz_id,
143
- 'quiz_name' => $results_data->quiz_name,
144
- 'quiz_system' => $results_data->quiz_system,
145
- 'user_name' => $results_data->name,
146
- 'user_business' => $results_data->business,
147
- 'user_email' => $results_data->email,
148
- 'user_phone' => $results_data->phone,
149
- 'user_id' => $results_data->user,
150
- 'timer' => $results[0],
151
- 'time_taken' => $results_data->time_taken,
152
- 'total_points' => $results_data->point_score,
153
- 'total_score' => $results_data->correct_score,
154
- 'total_correct' => $results_data->correct,
155
- 'total_questions' => $results_data->total,
156
- 'comments' => $results[2],
157
- 'question_answers_array' => $results[1],
158
- 'contact' => $results["contact"],
159
- 'results' => $results,
160
- );
161
-
162
- $mlwQuizMasterNext->pluginHelper->prepare_quiz($results_data->quiz_id);
163
- $sharing_page_id = qsm_get_post_id_from_quiz_id($results_data->quiz_id);
164
-
165
- //Fb share description
166
- $sharing = $mlwQuizMasterNext->pluginHelper->get_section_setting('quiz_text', 'facebook_sharing_text', '');
167
- $sharing = apply_filters('mlw_qmn_template_variable_results_page', $sharing, $results_array);
168
- $default_fb_image = QSM_PLUGIN_URL . 'assets/icon-200x200.png';
169
- $get_fb_sharing_image = $mlwQuizMasterNext->pluginHelper->get_section_setting('quiz_options', 'result_page_fb_image', '');
170
- if( empty( $get_fb_sharing_image ) ) {
171
- $get_fb_sharing_image = $mlwQuizMasterNext->pluginHelper->get_section_setting('quiz_text', 'result_page_fb_image', '');
172
- }
173
- if ($get_fb_sharing_image !== '') {
174
- $default_fb_image = $get_fb_sharing_image;
175
- }
176
- $post = $wp_query->get_queried_object();
177
- $pagename = $post->post_title;
178
- ?>
179
- <meta property="og:url" content="<?php echo $sharing_page_id . '?result_id=' . $_GET['result_id']; ?>" />
180
- <meta property="og:type" content="article" />
181
- <meta property="og:title" content="<?php echo $pagename; ?>" />
182
- <meta property="og:description" content="<?php echo $sharing; ?>" />
183
- <meta property="og:image" content="<?php echo $default_fb_image; ?>" />
184
- <meta property="fb:app_id" content="<?php echo $facebook_app_id; ?>" />
185
- <?php
186
- }
187
- }
188
  }
189
 
190
- add_action('wp_head', 'qsm_generate_fb_header_metadata');
191
 
192
 
193
  /**
194
  * @since QSM 6.4.6
195
  * @param int $quiz_id
196
- *
197
  * Get the post id from quiz id
198
  */
199
- function qsm_get_post_id_from_quiz_id($quiz_id){
200
- $args = array(
201
- 'posts_per_page' => 1,
202
- 'post_type' => 'qsm_quiz',
203
- 'meta_query' => array(
204
- array(
205
- 'key' => 'quiz_id',
206
- 'value' => $quiz_id,
207
- 'compare' => '=',
208
- ),
209
- ),
210
- );
211
- $the_query = new WP_Query($args);
212
-
213
- // The Loop
214
- $post_permalink = '';
215
- if ($the_query->have_posts()) {
216
- while ($the_query->have_posts()) {
217
- $the_query->the_post();
218
- $post_permalink = get_the_permalink(get_the_ID());
219
- }
220
- /* Restore original Post Data */
221
- wp_reset_postdata();
222
- }
223
- return $post_permalink;
224
  }
225
 
226
- add_filter('qmn_end_shortcode', 'qsm_display_popup_div', 10, 3);
227
- function qsm_display_popup_div( $return_display, $qmn_quiz_options, $qmn_array_for_variables ){
228
- if($qmn_quiz_options->enable_result_after_timer_end == 0){
229
- $return_display .= '<div style="display: none;" class="qsm-popup qsm-popup-slide" id="modal-3" aria-hidden="false">';
230
- $return_display .= '<div class="qsm-popup__overlay" tabindex="-1" data-micromodal-close="">';
231
- $return_display .= '<div class="qsm-popup__container qmn_quiz_container" role="dialog" aria-modal="true">';
232
- $return_display .= '<div class="qsm-popup__content">';
233
- $return_display .= '<img src="' . QSM_PLUGIN_URL . 'assets/clock.png' .'" alt="clock.png"/>';
234
- $return_display .= '<p class="qsm-time-up-text">Time is Up!</p>';
235
- $return_display .= '</div>';
236
- $return_display .= '<footer class="qsm-popup__footer"><button class="qsm-popup-secondary-button qmn_btn" data-micromodal-close="" aria-label="Close this dialog window">Cancel</button><button data-quiz_id="'. $qmn_quiz_options->quiz_id .'" class="submit-the-form qmn_btn">Submit Quiz</button></footer>';
237
- $return_display .= '</div>';
238
- $return_display .= '</div>';
239
- $return_display .= '</div>';
240
- }
241
- return $return_display;
242
  }
4
  * Displays a link to a quiz using ID. Used [qsm_link id=1]Click Here[/qsm_link]
5
  *
6
  * @since 5.1.0
7
+ * @param array $atts Attributes from add_shortcode function
8
  * @param string $content The text to be used for the link
9
  * @return string The HTML the shortcode will be replaced with
10
  */
11
+ function qsm_quiz_link_shortcode( $atts, $content = '' ) {
12
+ extract(
13
+ shortcode_atts(
14
+ array(
15
+ 'id' => 0,
16
+ 'class' => '',
17
+ 'target' => '',
18
+ ),
19
+ $atts
20
+ )
21
+ );
22
+ $id = intval( $id );
23
+
24
+ // Find the permalink by finding the post with the meta_key 'quiz_id' of supplied quiz
25
+ $permalink = '';
26
+ $my_query = new WP_Query(
27
+ array(
28
+ 'post_type' => 'qsm_quiz',
29
+ 'meta_key' => 'quiz_id',
30
+ 'meta_value' => $id,
31
+ 'posts_per_page' => 1,
32
+ 'post_status' => 'publish',
33
+ )
34
+ );
35
+ if ( $my_query->have_posts() ) {
36
+ while ( $my_query->have_posts() ) {
37
+ $my_query->the_post();
38
+ $permalink = get_permalink();
39
+ }
40
+ }
41
+ wp_reset_postdata();
42
+
43
+ // Craft the target attribute if one is passed to shortcode
44
+ $target_html = '';
45
+ if ( ! empty( $target ) ) {
46
+ $target_html = "target='" . esc_attr( $target ) . "'";
47
+ }
48
+ return "<a href='" . esc_url( $permalink ) . "' class='" . esc_attr( $class ) . "' $target_html>" . esc_html( $content ) . '</a>';
49
  }
50
 
51
+ add_shortcode( 'qsm_link', 'qsm_quiz_link_shortcode' );
52
 
53
  /**
54
  * Displays a list of most recently created quizes [qsm_recent_quizzes]
55
+ *
56
  * @param - attrs - array of shortcode attributes - no_of_quizzes, include_future_quizzes
57
  * @param - no_of_quizzes - Number of most recent quizzes to be displayed (default 10)
58
  * @param - include_future_quizzes - Whether to display future scheduled quizzes or not - yes/no (default yes)
60
  * @return string - list of quizzes
61
  * Shortcode call - [qsm_recent_quizzes no_of_quizzes=5 include_future_quizzes='no' ]
62
  */
63
+ function qsm_display_recent_quizzes( $attrs ) {
64
+
65
+ $no_of_quizzes = isset( $attrs['no_of_quizzes'] ) ? $attrs['no_of_quizzes'] : 10;
66
+ $include_future_quizzes = isset( $attrs['include_future_quizzes'] ) ? $attrs['include_future_quizzes'] : true;
67
+ global $wpdb;
68
+ wp_enqueue_style( 'quizzes-list', plugins_url( '../css/quizzes-list.css', __FILE__ ) );
69
+
70
+ $query = "SELECT quiz_id, quiz_name, quiz_settings FROM {$wpdb->prefix}mlw_quizzes WHERE deleted=0 ORDER BY quiz_id DESC";
71
+ $quizzes = $wpdb->get_results( $query );
72
+ $result = '<div class="outer-con">';
73
+ $i = 0;
74
+ foreach ( $quizzes as $quiz ) {
75
+ if ( $i < $no_of_quizzes ) {
76
+ $setting = unserialize( $quiz->quiz_settings );
77
+ $options = unserialize( $setting['quiz_options'] );
78
+
79
+ $start_date = $options['scheduled_time_start'];
80
+ $end_date = $options['scheduled_time_end'];
81
+ $today = date( 'm/d/Y' );
82
+ if ( $end_date != '' && $end_date < $today ) {
83
+ continue;
84
+ } elseif ( $include_future_quizzes == 'no' && $start_date > $today ) {
85
+ continue;
86
+ } else {
87
+ $title = $quiz->quiz_name;
88
+ $id = $quiz->quiz_id;
89
+ $url = do_shortcode( "[qsm_link id='$id'] Take Quiz [/qsm_link]" );
90
+ $result .= "<div class='ind-quiz'>
91
  <div class='quiz-heading'>
92
  {$title}
93
  </div>
95
  {$url}
96
  </div>
97
  </div>";
98
+ $result .= "<div class='clear'></div>";
99
+ $i++;
100
+ }
101
+ }
102
+ }
103
+ if ( $i == 0 ) {
104
+ $result .= __( 'No quiz found', 'quiz-master-next' );
105
+ }
106
+ $result .= '</div>';
107
+ return $result;
108
  }
109
 
110
+ add_shortcode( 'qsm_recent_quizzes', 'qsm_display_recent_quizzes' );
111
 
112
  /**
113
  * @since 6.4.1
114
  */
115
  function qsm_load_main_scripts() {
116
+ wp_enqueue_script( 'jquery' );
117
  }
118
 
119
+ add_action( 'wp_enqueue_scripts', 'qsm_load_main_scripts' );
120
 
121
  /**
122
  * Add Meta data for facebook share
123
+ *
124
  * @global obj $mlwQuizMasterNext
125
  * @global obj $wpdb
126
  * @global obj $wp_query
127
  */
128
  function qsm_generate_fb_header_metadata() {
129
+ if ( isset( $_GET['result_id'] ) && $_GET['result_id'] != '' ) {
130
+ $settings = (array) get_option( 'qmn-settings' );
131
+ $facebook_app_id = '594986844960937';
132
+ if ( isset( $settings['facebook_app_id'] ) ) {
133
+ $facebook_app_id = esc_js( $settings['facebook_app_id'] );
134
+ }
135
+ global $mlwQuizMasterNext, $wpdb, $wp_query;
136
+ $result_id = sanitize_text_field( $_GET['result_id'] );
137
+ $results_data = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}mlw_results WHERE unique_id = %s", $result_id ) );
138
+ if ( $results_data ) {
139
+ // Prepare responses array.
140
+ if ( is_serialized( $results_data->quiz_results ) && is_array( @unserialize( $results_data->quiz_results ) ) ) {
141
+ $results = unserialize( $results_data->quiz_results );
142
+ if ( ! isset( $results['contact'] ) ) {
143
+ $results['contact'] = array();
144
+ }
145
+ } else {
146
+ $template = str_replace( '%QUESTIONS_ANSWERS%', $results_data->quiz_results, $template );
147
+ $template = str_replace( '%TIMER%', '', $template );
148
+ $template = str_replace( '%COMMENT_SECTION%', '', $template );
149
+ $results = array(
150
+ 0,
151
+ array(),
152
+ '',
153
+ 'contact' => array(),
154
+ );
155
+ }
156
+ // Prepare full results array.
157
+ $results_array = array(
158
+ 'quiz_id' => $results_data->quiz_id,
159
+ 'quiz_name' => $results_data->quiz_name,
160
+ 'quiz_system' => $results_data->quiz_system,
161
+ 'user_name' => $results_data->name,
162
+ 'user_business' => $results_data->business,
163
+ 'user_email' => $results_data->email,
164
+ 'user_phone' => $results_data->phone,
165
+ 'user_id' => $results_data->user,
166
+ 'timer' => $results[0],
167
+ 'time_taken' => $results_data->time_taken,
168
+ 'total_points' => $results_data->point_score,
169
+ 'total_score' => $results_data->correct_score,
170
+ 'total_correct' => $results_data->correct,
171
+ 'total_questions' => $results_data->total,
172
+ 'comments' => $results[2],
173
+ 'question_answers_array' => $results[1],
174
+ 'contact' => $results['contact'],
175
+ 'results' => $results,
176
+ );
177
+
178
+ $mlwQuizMasterNext->pluginHelper->prepare_quiz( $results_data->quiz_id );
179
+ $sharing_page_id = qsm_get_post_id_from_quiz_id( $results_data->quiz_id );
180
+
181
+ // Fb share description
182
+ $sharing = $mlwQuizMasterNext->pluginHelper->get_section_setting( 'quiz_text', 'facebook_sharing_text', '' );
183
+ $sharing = apply_filters( 'mlw_qmn_template_variable_results_page', $sharing, $results_array );
184
+ $default_fb_image = QSM_PLUGIN_URL . 'assets/icon-200x200.png';
185
+ $get_fb_sharing_image = $mlwQuizMasterNext->pluginHelper->get_section_setting( 'quiz_options', 'result_page_fb_image', '' );
186
+ if ( empty( $get_fb_sharing_image ) ) {
187
+ $get_fb_sharing_image = $mlwQuizMasterNext->pluginHelper->get_section_setting( 'quiz_text', 'result_page_fb_image', '' );
188
+ }
189
+ if ( $get_fb_sharing_image !== '' ) {
190
+ $default_fb_image = $get_fb_sharing_image;
191
+ }
192
+ $post = $wp_query->get_queried_object();
193
+ $pagename = $post->post_title;
194
+ ?>
195
+ <meta property="og:url" content="<?php echo $sharing_page_id . '?result_id=' . esc_attr( $_GET['result_id'] ); ?>" />
196
+ <meta property="og:type" content="article" />
197
+ <meta property="og:title" content="<?php echo $pagename; ?>" />
198
+ <meta property="og:description" content="<?php echo $sharing; ?>" />
199
+ <meta property="og:image" content="<?php echo $default_fb_image; ?>" />
200
+ <meta property="fb:app_id" content="<?php echo $facebook_app_id; ?>" />
201
+ <?php
202
+ }
203
+ }
204
  }
205
 
206
+ add_action( 'wp_head', 'qsm_generate_fb_header_metadata' );
207
 
208
 
209
  /**
210
  * @since QSM 6.4.6
211
  * @param int $quiz_id
212
+ *
213
  * Get the post id from quiz id
214
  */
215
+ function qsm_get_post_id_from_quiz_id( $quiz_id ) {
216
+ $args = array(
217
+ 'posts_per_page' => 1,
218
+ 'post_type' => 'qsm_quiz',
219
+ 'meta_query' => array(
220
+ array(
221
+ 'key' => 'quiz_id',
222
+ 'value' => $quiz_id,
223
+ 'compare' => '=',
224
+ ),
225
+ ),
226
+ );
227
+ $the_query = new WP_Query( $args );
228
+
229
+ // The Loop
230
+ $post_permalink = '';
231
+ if ( $the_query->have_posts() ) {
232
+ while ( $the_query->have_posts() ) {
233
+ $the_query->the_post();
234
+ $post_permalink = get_the_permalink( get_the_ID() );
235
+ }
236
+ /* Restore original Post Data */
237
+ wp_reset_postdata();
238
+ }
239
+ return $post_permalink;
240
  }
241
 
242
+ add_filter( 'qmn_end_shortcode', 'qsm_display_popup_div', 10, 3 );
243
+ function qsm_display_popup_div( $return_display, $qmn_quiz_options, $qmn_array_for_variables ) {
244
+ if ( $qmn_quiz_options->enable_result_after_timer_end == 0 ) {
245
+ $return_display .= '<div style="display: none;" class="qsm-popup qsm-popup-slide" id="modal-3" aria-hidden="false">';
246
+ $return_display .= '<div class="qsm-popup__overlay" tabindex="-1" data-micromodal-close="">';
247
+ $return_display .= '<div class="qsm-popup__container qmn_quiz_container" role="dialog" aria-modal="true">';
248
+ $return_display .= '<div class="qsm-popup__content">';
249
+ $return_display .= '<img src="' . QSM_PLUGIN_URL . 'assets/clock.png' . '" alt="clock.png"/>';
250
+ $return_display .= '<p class="qsm-time-up-text">Time is Up!</p>';
251
+ $return_display .= '</div>';
252
+ $return_display .= '<footer class="qsm-popup__footer"><button class="qsm-popup-secondary-button qmn_btn" data-micromodal-close="" aria-label="Close this dialog window">Cancel</button><button data-quiz_id="' . $qmn_quiz_options->quiz_id . '" class="submit-the-form qmn_btn">Submit Quiz</button></footer>';
253
+ $return_display .= '</div>';
254
+ $return_display .= '</div>';
255
+ $return_display .= '</div>';
256
+ }
257
+ return $return_display;
258
  }
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.17
8
  License: GPLv2
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
@@ -140,6 +140,9 @@ This is usually a theme conflict. You can [checkout out our common conflict solu
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.
4
  Requires at least: 4.9
5
  Tested up to: 5.7
6
  Requires PHP: 5.4
7
+ Stable tag: 7.1.18
8
  License: GPLv2
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
140
 
141
  == Changelog ==
142
 
143
+ = 7.1.18 (May 31, 2021) =
144
+ * Bug: Fixed recently discovered security issues.
145
+
146
  = 7.1.17 (May 28, 2021) =
147
  * Bug: Fixed the issue where page title shows Nan:Nan:Nan on reload.
148
  * Bug: Fixed the issue when editing duplicate questions updates original questions.