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

Version Description

(April 07, 2020)= * Bug: Solved jquery UI error * Bug: Customized text using the "Text tab" and remove from "Options Tab" for user is not logged in * Bug: Fixed share Quizz's results on Social Media ( https://wordpress.org/support/topic/sharing-to-social-media/ ) * Bug: For polar question type added the validation while creating option * Bug: Solved phone number field validation * Bug: Solved User Dashboard addon issue for first row * Feature: Special capabilities #810 ( https://github.com/QuizandSurveyMaster/quiz_master_next/issues/810 ) * Feature: Added Show JS Error library to show the JS Error in quiz page * Feature: Changed type of quiz_results to MEDIUMTEXT (16M size) ( https://github.com/QuizandSurveyMaster/quiz_master_next/issues/522 )

Download this release

Release Info

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

Code changes from version 6.4.5 to 6.4.7

assets/icon-200x200.png ADDED
Binary file
css/show-js-error.css ADDED
@@ -0,0 +1,120 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .show-js-error {
2
+ font-family: Arial, sans-serif;
3
+ font-size: 12px;
4
+ position: fixed;
5
+ z-index: 16000000;
6
+ bottom: 15px;
7
+ left: 15px;
8
+ visibility: hidden;
9
+ min-width: 15em;
10
+ max-width: 40em;
11
+ transition: all 0.2s ease-out;
12
+ opacity: 0;
13
+ color: #000;
14
+ background: #ffc1cc;
15
+ }
16
+ .show-js-error_visible {
17
+ visibility: visible;
18
+ opacity: 1;
19
+ }
20
+ .show-js-error input {
21
+ padding: 1px 2px;
22
+ }
23
+ .show-js-error__title {
24
+ font-weight: bold;
25
+ padding: 4px 7px;
26
+ color: #fff;
27
+ background: #f66;
28
+ }
29
+ .show-js-error__message {
30
+ display: inline;
31
+ cursor: pointer;
32
+ border-bottom: 1px dotted #000;
33
+ }
34
+ .show-js-error a,
35
+ .show-js-error a:visited {
36
+ text-decoration: underline;
37
+ color: #000;
38
+ }
39
+ .show-js-error a:hover {
40
+ text-decoration: underline;
41
+ }
42
+ .show-js-error__close {
43
+ font-size: 20px;
44
+ line-height: 20px;
45
+ position: absolute;
46
+ top: -1px;
47
+ right: 2px;
48
+ padding: 3px;
49
+ cursor: pointer;
50
+ color: #fff;
51
+ }
52
+ .show-js-error__body {
53
+ line-height: 19px;
54
+ padding: 5px 8px 5px 8px;
55
+ }
56
+ .show-js-error .show-js-error__filename,
57
+ .show-js-error .show-js-error__ua,
58
+ .show-js-error .show-js-error__help {
59
+ display: none;
60
+ }
61
+ .show-js-error__body_detailed .show-js-error__filename,
62
+ .show-js-error__body_detailed .show-js-error__ua,
63
+ .show-js-error__body_detailed .show-js-error__help {
64
+ display: block;
65
+ }
66
+ .show-js-error .show-js-error__additional-text {
67
+ color: #666;
68
+ }
69
+ .show-js-error .show-js-error__filename {
70
+ overflow-y: auto;
71
+ max-height: 15em;
72
+ margin: 3px 0 3px -2px;
73
+ padding: 5px;
74
+ white-space: pre-wrap;
75
+ border: 1px solid #faa;
76
+ background: #ffe1ec;
77
+ }
78
+ .show-js-error__help a {
79
+ font-size: 11px;
80
+ margin-right: 6px;
81
+ }
82
+ .show-js-error__actions {
83
+ padding: 3px 5px;
84
+ border-top: 1px solid #faa;
85
+ }
86
+ .show-js-error__actions::after {
87
+ font-size: 0;
88
+ display: block;
89
+ visibility: hidden;
90
+ clear: both;
91
+ height: 0;
92
+ content: ' ';
93
+ }
94
+ .show-js-error__arrows {
95
+ display: none;
96
+ float: left;
97
+ margin-left: 8px;
98
+ }
99
+ .show-js-error__arrows_visible {
100
+ display: block;
101
+ }
102
+ .show-js-error__copy,
103
+ .show-js-error__send,
104
+ .show-js-error__prev,
105
+ .show-js-error__next,
106
+ .show-js-error__num {
107
+ font-size: 11px;
108
+ }
109
+ .show-js-error__next {
110
+ margin-left: 1px;
111
+ }
112
+ .show-js-error__num {
113
+ margin-right: 5px;
114
+ margin-left: 5px;
115
+ }
116
+ .show-js-error__copy,
117
+ .show-js-error__send {
118
+ float: left;
119
+ margin-right: 3px;
120
+ }
js/qsm-admin-question.js CHANGED
@@ -512,6 +512,10 @@ var import_button;
512
  $( '#new-answer-button' ).on( 'click', function( event ) {
513
  event.preventDefault();
514
  var answer_length = $( '#answers' ).find('.answers-single').length;
 
 
 
 
515
  var question_id = $('#edit_question_id').val();
516
  var answerType = $('#change-answer-editor').val();
517
  var answer = [ '', '', 0, answer_length + 1, question_id, answerType];
@@ -639,7 +643,7 @@ var import_button;
639
  jQuery('#file-upload-type-div').hide();
640
  jQuery('#file-upload-limit').hide();
641
  }
642
- });
643
  });
644
  var decodeEntities = (function () {
645
  //create a new html document (doesn't execute script tags in child elements)
512
  $( '#new-answer-button' ).on( 'click', function( event ) {
513
  event.preventDefault();
514
  var answer_length = $( '#answers' ).find('.answers-single').length;
515
+ if( answer_length > 1 && $('#question_type').val() == 13 ){
516
+ alert('You can not add more than 2 answer for Polar Question type');
517
+ return;
518
+ }
519
  var question_id = $('#edit_question_id').val();
520
  var answerType = $('#change-answer-editor').val();
521
  var answer = [ '', '', 0, answer_length + 1, question_id, answerType];
643
  jQuery('#file-upload-type-div').hide();
644
  jQuery('#file-upload-limit').hide();
645
  }
646
+ });
647
  });
648
  var decodeEntities = (function () {
649
  //create a new html document (doesn't execute script tags in child elements)
js/qsm-quiz.js CHANGED
@@ -6,6 +6,7 @@
6
  * This object contains the newer functions. All global functions under are slowly
7
  * being deprecated and replaced with rewritten newer functions
8
  **************************/
 
9
  var QSM;
10
  (function ($) {
11
  QSM = {
@@ -342,7 +343,11 @@ var QSM;
342
  // Call main initialization.
343
  QSM.init();
344
  });
345
-
 
 
 
 
346
  }(jQuery));
347
 
348
  // Global Variables
@@ -372,6 +377,12 @@ function qsmEndTimeTakenTimer() {
372
  clearInterval( qsmTimerInterval );
373
  }
374
 
 
 
 
 
 
 
375
  function qmnClearField( field ) {
376
  if ( field.defaultValue == field.value ) field.value = '';
377
  }
@@ -487,6 +498,12 @@ function qmnFormSubmit( quiz_form_id ) {
487
  var quiz_id = +jQuery( '#' + quiz_form_id ).find( '.qmn_quiz_id' ).val();
488
  var $container = jQuery( '#' + quiz_form_id ).closest( '.qmn_quiz_container' );
489
  var result = qmnValidation( '#' + quiz_form_id + ' *', quiz_form_id );
 
 
 
 
 
 
490
 
491
  if ( ! result ) { return result; }
492
 
@@ -769,12 +786,12 @@ function qmnInitPagination( quiz_id ) {
769
  }
770
  }
771
 
772
- function qmnSocialShare( network, mlw_qmn_social_text, mlw_qmn_title, facebook_id ) {
773
  var sTop = window.screen.height / 2 - ( 218 );
774
  var sLeft = window.screen.width / 2 - ( 313 );
775
  var sqShareOptions = "height=400,width=580,toolbar=0,status=0,location=0,menubar=0,directories=0,scrollbars=0,top=" + sTop + ",left=" + sLeft;
776
  var pageUrl = window.location.href;
777
- var pageUrlEncoded = encodeURIComponent( pageUrl );
778
  var url = '';
779
  if ( network == 'facebook' ) {
780
  url = "https://www.facebook.com/dialog/feed?" + "display=popup&" + "app_id="+facebook_id +
@@ -788,7 +805,7 @@ function qmnSocialShare( network, mlw_qmn_social_text, mlw_qmn_title, facebook_i
788
  return false;
789
  }
790
 
791
- jQuery(function() {
792
  jQuery( '.qmn_quiz_container' ).tooltip();
793
 
794
  jQuery( '.qmn_quiz_container input' ).on( 'keypress', function ( e ) {
6
  * This object contains the newer functions. All global functions under are slowly
7
  * being deprecated and replaced with rewritten newer functions
8
  **************************/
9
+
10
  var QSM;
11
  (function ($) {
12
  QSM = {
343
  // Call main initialization.
344
  QSM.init();
345
  });
346
+
347
+ jQuery("input[name='timer_ms']").each(function(){
348
+ var timems = qsmTimeInMS();
349
+ jQuery(this).val(timems);
350
+ });
351
  }(jQuery));
352
 
353
  // Global Variables
377
  clearInterval( qsmTimerInterval );
378
  }
379
 
380
+ function qsmTimeInMS() {
381
+ var d = new Date();
382
+ var n = d.getTime();
383
+ return n;
384
+ }
385
+
386
  function qmnClearField( field ) {
387
  if ( field.defaultValue == field.value ) field.value = '';
388
  }
498
  var quiz_id = +jQuery( '#' + quiz_form_id ).find( '.qmn_quiz_id' ).val();
499
  var $container = jQuery( '#' + quiz_form_id ).closest( '.qmn_quiz_container' );
500
  var result = qmnValidation( '#' + quiz_form_id + ' *', quiz_form_id );
501
+ /**
502
+ * Update Timer in MS
503
+ */
504
+ var timer_ms = jQuery('#' + quiz_form_id).find("input[name='timer_ms']").val();
505
+ var new_timer_ms = qsmTimeInMS();
506
+ jQuery('#' + quiz_form_id).find("input[name='timer_ms']").val(Math.abs(new_timer_ms - timer_ms));
507
 
508
  if ( ! result ) { return result; }
509
 
786
  }
787
  }
788
 
789
+ function qmnSocialShare( network, mlw_qmn_social_text, mlw_qmn_title, facebook_id, share_url ) {
790
  var sTop = window.screen.height / 2 - ( 218 );
791
  var sLeft = window.screen.width / 2 - ( 313 );
792
  var sqShareOptions = "height=400,width=580,toolbar=0,status=0,location=0,menubar=0,directories=0,scrollbars=0,top=" + sTop + ",left=" + sLeft;
793
  var pageUrl = window.location.href;
794
+ var pageUrlEncoded = encodeURIComponent( share_url );
795
  var url = '';
796
  if ( network == 'facebook' ) {
797
  url = "https://www.facebook.com/dialog/feed?" + "display=popup&" + "app_id="+facebook_id +
805
  return false;
806
  }
807
 
808
+ jQuery(function() {
809
  jQuery( '.qmn_quiz_container' ).tooltip();
810
 
811
  jQuery( '.qmn_quiz_container input' ).on( 'keypress', function ( e ) {
js/show-js-error.custom.js ADDED
@@ -0,0 +1,541 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*! show-js-error | © 2020 Denis Seleznev | MIT License */
2
+ (function (global, factory) {
3
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
4
+ typeof define === 'function' && define.amd ? define(factory) :
5
+ (global = global || self, global.showJSError = factory());
6
+ }(this, (function () { 'use strict';
7
+
8
+ var showJSError = { // eslint-disable-line no-unused-vars
9
+ /**
10
+ * Initialize.
11
+ *
12
+ * @param {Object} [settings]
13
+ * @param {String} [settings.title]
14
+ * @param {String} [settings.userAgent]
15
+ * @param {String} [settings.copyText]
16
+ * @param {String} [settings.sendText]
17
+ * @param {String} [settings.sendUrl]
18
+ * @param {String} [settings.additionalText]
19
+ * @param {Boolean} [settings.helpLinks]
20
+ */
21
+ init: function(settings) {
22
+ if (this._inited) {
23
+ return;
24
+ }
25
+
26
+ var that = this,
27
+ isAndroidOrIOS = /(Android|iPhone|iPod|iPad)/i.test(navigator.userAgent);
28
+
29
+ this.settings = settings || {};
30
+
31
+ this._inited = true;
32
+ this._isLast = true;
33
+ this._i = 0;
34
+ this._buffer = [];
35
+
36
+ this._onerror = function(e) {
37
+ if (isAndroidOrIOS && e && e.message === 'Script error.' && !e.lineno && !e.filename) {
38
+ return;
39
+ }
40
+
41
+ that._buffer.push(e);
42
+ if (that._isLast) {
43
+ that._i = that._buffer.length - 1;
44
+ }
45
+
46
+ that._update();
47
+ };
48
+
49
+ if (window.addEventListener) {
50
+ window.addEventListener('error', this._onerror, false);
51
+ } else {
52
+ this._oldOnError = window.onerror;
53
+
54
+ window.onerror = function(message, filename, lineno, colno, error) {
55
+ that._onerror({
56
+ message: message,
57
+ filename: filename,
58
+ lineno: lineno,
59
+ colno: colno,
60
+ error: error
61
+ });
62
+
63
+ if (typeof that._oldOnError === 'function') {
64
+ that._oldOnError.apply(window, arguments);
65
+ }
66
+ };
67
+ }
68
+ },
69
+ /**
70
+ * Destructor.
71
+ */
72
+ destruct: function() {
73
+ if (!this._inited) { return; }
74
+
75
+ if (window.addEventListener) {
76
+ window.removeEventListener('error', this._onerror, false);
77
+ } else {
78
+ window.onerror = this._oldOnError || null;
79
+ delete this._oldOnError;
80
+ }
81
+
82
+ if (document.body && this._container) {
83
+ document.body.removeChild(this._container);
84
+ }
85
+
86
+ this._buffer = [];
87
+
88
+ this._inited = false;
89
+ },
90
+ /**
91
+ * Show error message.
92
+ *
93
+ * @param {String|Object|Error} err
94
+ */
95
+ show: function(err) {
96
+ if (typeof err !== 'undefined') {
97
+ this._buffer.push(typeof err === 'object' ? err : new Error(err));
98
+ }
99
+
100
+ this._update();
101
+ this._show();
102
+ },
103
+ /**
104
+ * Hide error message.
105
+ */
106
+ hide: function() {
107
+ if (this._container) {
108
+ this._container.className = this.elemClass('');
109
+ }
110
+ },
111
+ /**
112
+ * Copy error message to clipboard.
113
+ */
114
+ copyText: function() {
115
+ var err = this._buffer[this._i],
116
+ text = this._getDetailedMessage(err),
117
+ body = document.body,
118
+ textarea = this.elem({
119
+ name: 'textarea',
120
+ tag: 'textarea',
121
+ props: {
122
+ innerHTML: text
123
+ },
124
+ container: body
125
+ });
126
+
127
+ try {
128
+ textarea.select();
129
+ document.execCommand('copy');
130
+ } catch (e) {
131
+ alert('Copying text is not supported in this browser.');
132
+ }
133
+
134
+ body.removeChild(textarea);
135
+ },
136
+ /**
137
+ * Create a elem.
138
+ *
139
+ * @param {Object} data
140
+ * @param {String} data.name
141
+ * @param {DOMElement} data.container
142
+ * @param {String} [data.tag]
143
+ * @param {Object} [data.props]
144
+ * @returns {DOMElement}
145
+ */
146
+ elem: function(data) {
147
+ var el = document.createElement(data.tag || 'div'),
148
+ props = data.props;
149
+
150
+ for (var i in props) {
151
+ // eslint-disable-next-line no-prototype-builtins
152
+ if (props.hasOwnProperty(i)) {
153
+ el[i] = props[i];
154
+ }
155
+ }
156
+
157
+ el.className = this.elemClass(data.name);
158
+
159
+ data.container.appendChild(el);
160
+
161
+ return el;
162
+ },
163
+ /**
164
+ * Build className for elem.
165
+ *
166
+ * @param {String} [name]
167
+ * @param {String} [mod]
168
+ * @returns {String}
169
+ */
170
+ elemClass: function(name, mod) {
171
+ var cl = 'show-js-error';
172
+ if (name) {
173
+ cl += '__' + name;
174
+ }
175
+
176
+ if (mod) {
177
+ cl += ' ' + cl + '_' + mod;
178
+ }
179
+
180
+ return cl;
181
+ },
182
+ /**
183
+ * Escape HTML.
184
+ *
185
+ * @param {String} text
186
+ * @returns {String}
187
+ */
188
+ escapeHTML: function(text) {
189
+ return (text || '').replace(/[&<>"'/]/g, function(sym) {
190
+ return {
191
+ '&': '&amp;',
192
+ '<': '&lt;',
193
+ '>': '&gt;',
194
+ '"': '&quot;',
195
+ '\'': '&#39;',
196
+ '/': '&#x2F;'
197
+ }[sym];
198
+ });
199
+ },
200
+ /**
201
+ * Toggle view (shortly/detail).
202
+ */
203
+ toggleDetailed: function() {
204
+ var body = this._body;
205
+ if (body) {
206
+ if (this._toggleDetailed) {
207
+ this._toggleDetailed = false;
208
+ body.className = this.elemClass('body');
209
+ } else {
210
+ this._toggleDetailed = true;
211
+ body.className = this.elemClass('body', 'detailed');
212
+ }
213
+ }
214
+ },
215
+ _append: function() {
216
+ var that = this;
217
+
218
+ this._container = document.createElement('div');
219
+ this._container.className = this.elemClass('');
220
+
221
+ this._title = this.elem({
222
+ name: 'title',
223
+ props: {
224
+ innerHTML: this._getTitle()
225
+ },
226
+ container: this._container
227
+ });
228
+
229
+ this._body = this.elem({
230
+ name: 'body',
231
+ container: this._container
232
+ });
233
+
234
+ this._message = this.elem({
235
+ name: 'message',
236
+ props: {
237
+ onclick: function() {
238
+ that.toggleDetailed();
239
+ }
240
+ },
241
+ container: this._body
242
+ });
243
+
244
+ if (this.settings.helpLinks) {
245
+ this._helpLinks = this.elem({
246
+ name: 'help',
247
+ container: this._body
248
+ });
249
+
250
+ this._mdn = this.elem({
251
+ tag: 'a',
252
+ name: 'mdn',
253
+ props: {
254
+ target: '_blank',
255
+ innerHTML: 'MDN'
256
+ },
257
+ container: this._helpLinks
258
+ });
259
+
260
+ this._stackoverflow = this.elem({
261
+ tag: 'a',
262
+ name: 'stackoverflow',
263
+ props: {
264
+ target: '_blank',
265
+ innerHTML: 'Stack Overflow'
266
+ },
267
+ container: this._helpLinks
268
+ });
269
+ }
270
+
271
+ this._filename = this.elem({
272
+ name: 'filename',
273
+ container: this._body
274
+ });
275
+
276
+ if (this.settings.userAgent) {
277
+ this._ua = this.elem({
278
+ name: 'ua',
279
+ container: this._body
280
+ });
281
+ }
282
+
283
+ if (this.settings.additionalText) {
284
+ this._additionalText = this.elem({
285
+ name: 'additional-text',
286
+ container: this._body
287
+ });
288
+ }
289
+
290
+ this.elem({
291
+ name: 'close',
292
+ props: {
293
+ innerHTML: '×',
294
+ onclick: function() {
295
+ that.hide();
296
+ }
297
+ },
298
+ container: this._container
299
+ });
300
+
301
+ this._actions = this.elem({
302
+ name: 'actions',
303
+ container: this._container
304
+ });
305
+
306
+ this.elem({
307
+ tag: 'input',
308
+ name: 'copy',
309
+ props: {
310
+ type: 'button',
311
+ value: this.settings.copyText || 'Copy',
312
+ onclick: function() {
313
+ that.copyText();
314
+ }
315
+ },
316
+ container: this._actions
317
+ });
318
+
319
+ if (this.settings.sendUrl) {
320
+ this._sendLink = this.elem({
321
+ tag: 'a',
322
+ name: 'send-link',
323
+ props: {
324
+ href: '',
325
+ target: '_blank'
326
+ },
327
+ container: this._actions
328
+ });
329
+
330
+ this._send = this.elem({
331
+ tag: 'input',
332
+ name: 'send',
333
+ props: {
334
+ type: 'button',
335
+ value: this.settings.sendText || 'Send'
336
+ },
337
+ container: this._sendLink
338
+ });
339
+ }
340
+
341
+ this._arrows = this.elem({
342
+ tag: 'span',
343
+ name: 'arrows',
344
+ container: this._actions
345
+ });
346
+
347
+ this._prev = this.elem({
348
+ tag: 'input',
349
+ name: 'prev',
350
+ props: {
351
+ type: 'button',
352
+ value: '←',
353
+ onclick: function() {
354
+ that._isLast = false;
355
+ if (that._i) {
356
+ that._i--;
357
+ }
358
+
359
+ that._update();
360
+ }
361
+ },
362
+ container: this._arrows
363
+ });
364
+
365
+ this._next = this.elem({
366
+ tag: 'input',
367
+ name: 'next',
368
+ props: {
369
+ type: 'button',
370
+ value: '→',
371
+ onclick: function() {
372
+ that._isLast = false;
373
+ if (that._i < that._buffer.length - 1) {
374
+ that._i++;
375
+ }
376
+
377
+ that._update();
378
+ }
379
+ },
380
+ container: this._arrows
381
+ });
382
+
383
+ this._num = this.elem({
384
+ tag: 'span',
385
+ name: 'num',
386
+ props: {
387
+ innerHTML: this._i + 1
388
+ },
389
+ container: this._arrows
390
+ });
391
+
392
+ var append = function() {
393
+ document.body.appendChild(that._container);
394
+ };
395
+
396
+ if (document.body) {
397
+ append();
398
+ } else {
399
+ if (document.addEventListener) {
400
+ document.addEventListener('DOMContentLoaded', append, false);
401
+ } else if (document.attachEvent) {
402
+ document.attachEvent('onload', append);
403
+ }
404
+ }
405
+ },
406
+ _getDetailedMessage: function(err) {
407
+ var settings = this.settings,
408
+ screen = typeof window.screen === 'object' ? window.screen : {},
409
+ orientation = screen.orientation || screen.mozOrientation || screen.msOrientation || '',
410
+ props = [
411
+ ['Title', err.title || this._getTitle()],
412
+ ['Message', this._getMessage(err)],
413
+ ['Filename', this._getFilenameWithPosition(err)],
414
+ ['Stack', this._getStack(err)],
415
+ ['Page url', window.location.href],
416
+ ['Refferer', document.referrer],
417
+ ['User-agent', settings.userAgent || navigator.userAgent],
418
+ ['Screen size', [screen.width, screen.height, screen.colorDepth].join('×')],
419
+ ['Screen orientation', typeof orientation === 'string' ? orientation : orientation.type],
420
+ ['Cookie enabled', navigator.cookieEnabled]
421
+ ];
422
+
423
+ var text = '';
424
+ for (var i = 0; i < props.length; i++) {
425
+ var item = props[i];
426
+ text += item[0] + ': ' + item[1] + '\n';
427
+ }
428
+
429
+ if (settings.templateDetailedMessage) {
430
+ text = settings.templateDetailedMessage.replace(/\{message\}/, text);
431
+ }
432
+
433
+ return text;
434
+ },
435
+ _getExtFilename: function(e) {
436
+ var filename = e.filename,
437
+ html = this.escapeHTML(this._getFilenameWithPosition(e));
438
+
439
+ if (filename && filename.search(/^(https?|file):/) > -1) {
440
+ return '<a target="_blank" href="' +
441
+ this.escapeHTML(filename) + '">' + html + '</a>';
442
+ } else {
443
+ return html;
444
+ }
445
+ },
446
+ _get: function(value, defaultValue) {
447
+ return typeof value !== 'undefined' ? value : defaultValue;
448
+ },
449
+ _getFilenameWithPosition: function(e) {
450
+ var text = e.filename || '';
451
+ if (typeof e.lineno !== 'undefined') {
452
+ text += ':' + this._get(e.lineno, '');
453
+ if (typeof e.colno !== 'undefined') {
454
+ text += ':' + this._get(e.colno, '');
455
+ }
456
+ }
457
+
458
+ return text;
459
+ },
460
+ _getMessage: function(e) {
461
+ var msg = e.message;
462
+
463
+ // IE
464
+ if (e.error && e.error.name && 'number' in e.error) {
465
+ msg = e.error.name + ': ' + msg;
466
+ }
467
+
468
+ return msg;
469
+ },
470
+ _getStack: function(err) {
471
+ return (err.error && err.error.stack) || err.stack || '';
472
+ },
473
+ _getTitle: function() {
474
+ return this.settings.title || 'JavaScript error';
475
+ },
476
+ _show: function() {
477
+ this._container.className = this.elemClass('', 'visible');
478
+ },
479
+ _highlightLinks: function(text) {
480
+ return text.replace(/(at | \(|@)(https?|file)(:.*?)(?=:\d+:\d+\)?$)/gm, function($0, $1, $2, $3) {
481
+ var url = $2 + $3;
482
+
483
+ return $1 + '<a target="_blank" href="' + url + '">' + url + '</a>';
484
+ });
485
+ },
486
+ _update: function() {
487
+ if (!this._appended) {
488
+ this._append();
489
+ this._appended = true;
490
+ }
491
+
492
+ var e = this._buffer[this._i],
493
+ stack = this._getStack(e),
494
+ filename;
495
+
496
+ if (stack) {
497
+ filename = this._highlightLinks(this.escapeHTML(stack));
498
+ } else {
499
+ filename = this._getExtFilename(e);
500
+ }
501
+
502
+ this._title.innerHTML = this.escapeHTML(e.title || this._getTitle());
503
+
504
+ this._message.innerHTML = this.escapeHTML(this._getMessage(e));
505
+
506
+ this._filename.innerHTML = filename;
507
+
508
+ if (this._ua) {
509
+ this._ua.innerHTML = this.escapeHTML(this.settings.userAgent);
510
+ }
511
+
512
+ if (this._additionalText) {
513
+ this._additionalText.innerHTML = this.escapeHTML(this.settings.additionalText);
514
+ }
515
+
516
+ if (this._sendLink) {
517
+ this._sendLink.href = this.settings.sendUrl
518
+ .replace(/\{title\}/, encodeURIComponent(this._getMessage(e)))
519
+ .replace(/\{body\}/, encodeURIComponent(this._getDetailedMessage(e)));
520
+ }
521
+
522
+ if (this._buffer.length > 1) {
523
+ this._arrows.className = this.elemClass('arrows', 'visible');
524
+ }
525
+
526
+ if (this._helpLinks) {
527
+ this._mdn.href = 'https://developer.mozilla.org/en-US/search?q=' + encodeURIComponent(e.message || e.stack || '');
528
+ this._stackoverflow.href = 'https://stackoverflow.com/search?q=' + encodeURIComponent('[js] ' + (e.message || e.stack || ''));
529
+ }
530
+
531
+ this._prev.disabled = !this._i;
532
+ this._num.innerHTML = (this._i + 1) + '&thinsp;/&thinsp;' + this._buffer.length;
533
+ this._next.disabled = this._i === this._buffer.length - 1;
534
+
535
+ this._show();
536
+ }
537
+ };
538
+
539
+ return showJSError;
540
+
541
+ })));
mlw_quizmaster2.php CHANGED
@@ -2,14 +2,14 @@
2
  /**
3
  * Plugin Name: Quiz And Survey Master
4
  * Description: Easily and quickly add quizzes and surveys to your website.
5
- * Version: 6.4.5
6
  * Author: ExpressTech
7
  * Author URI: https://quizandsurveymaster.com/
8
  * Plugin URI: https://expresstech.io/
9
  * Text Domain: quiz-master-next
10
  *
11
  * @author QSM Team
12
- * @version 6.4.5
13
  * @package QSM
14
  */
15
 
@@ -37,7 +37,7 @@ class MLWQuizMasterNext {
37
  * @var string
38
  * @since 4.0.0
39
  */
40
- public $version = '6.4.5';
41
 
42
  /**
43
  * QSM Alert Manager Object
@@ -272,8 +272,8 @@ class MLWQuizMasterNext {
272
  */
273
  public function setup_admin_menu() {
274
  if ( function_exists( 'add_menu_page' ) ) {
275
- add_menu_page( 'Quiz And Survey Master', __( 'Quizzes/Surveys', 'quiz-master-next' ), 'moderate_comments', __FILE__, 'qsm_generate_quizzes_surveys_page', 'dashicons-feedback' );
276
- add_submenu_page( NULL, __( 'Settings', 'quiz-master-next' ), __( 'Settings', 'quiz-master-next' ), 'moderate_comments', 'mlw_quiz_options', 'qsm_generate_quiz_options' );
277
  add_submenu_page( __FILE__, __( 'Results', 'quiz-master-next' ), __( 'Results', 'quiz-master-next' ), 'moderate_comments', 'mlw_quiz_results', 'qsm_generate_admin_results_page' );
278
  add_submenu_page( NULL, __( 'Result Details', 'quiz-master-next' ), __( 'Result Details', 'quiz-master-next' ), 'moderate_comments', 'qsm_quiz_result_details', 'qsm_generate_result_details' );
279
  add_submenu_page( __FILE__, __( 'Settings', 'quiz-master-next' ), __( 'Settings', 'quiz-master-next' ), 'manage_options', 'qmn_global_settings', array( 'QMNGlobalSettingsPage', 'display_page' ) );
2
  /**
3
  * Plugin Name: Quiz And Survey Master
4
  * Description: Easily and quickly add quizzes and surveys to your website.
5
+ * Version: 6.4.7
6
  * Author: ExpressTech
7
  * Author URI: https://quizandsurveymaster.com/
8
  * Plugin URI: https://expresstech.io/
9
  * Text Domain: quiz-master-next
10
  *
11
  * @author QSM Team
12
+ * @version 6.4.7
13
  * @package QSM
14
  */
15
 
37
  * @var string
38
  * @since 4.0.0
39
  */
40
+ public $version = '6.4.7';
41
 
42
  /**
43
  * QSM Alert Manager Object
272
  */
273
  public function setup_admin_menu() {
274
  if ( function_exists( 'add_menu_page' ) ) {
275
+ add_menu_page( 'Quiz And Survey Master', __( 'Quizzes/Surveys', 'quiz-master-next' ), 'edit_posts', __FILE__, 'qsm_generate_quizzes_surveys_page', 'dashicons-feedback' );
276
+ add_submenu_page( NULL, __( 'Settings', 'quiz-master-next' ), __( 'Settings', 'quiz-master-next' ), 'edit_posts', 'mlw_quiz_options', 'qsm_generate_quiz_options' );
277
  add_submenu_page( __FILE__, __( 'Results', 'quiz-master-next' ), __( 'Results', 'quiz-master-next' ), 'moderate_comments', 'mlw_quiz_results', 'qsm_generate_admin_results_page' );
278
  add_submenu_page( NULL, __( 'Result Details', 'quiz-master-next' ), __( 'Result Details', 'quiz-master-next' ), 'moderate_comments', 'qsm_quiz_result_details', 'qsm_generate_result_details' );
279
  add_submenu_page( __FILE__, __( 'Settings', 'quiz-master-next' ), __( 'Settings', 'quiz-master-next' ), 'manage_options', 'qmn_global_settings', array( 'QMNGlobalSettingsPage', 'display_page' ) );
php/admin/functions.php CHANGED
@@ -23,4 +23,24 @@ function qsm_redirect_to_edit_page($quiz_id){
23
  window.location.href = '<?php echo $url; ?>';
24
  </script>
25
  <?php
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
26
  }
23
  window.location.href = '<?php echo $url; ?>';
24
  </script>
25
  <?php
26
+ }
27
+
28
+ add_action('admin_init','qsm_add_author_column_in_db');
29
+ /**
30
+ * @since 6.4.6
31
+ * Insert new column in quiz table
32
+ */
33
+ function qsm_add_author_column_in_db(){
34
+ global $wpdb;
35
+ $quiz_table_name = $wpdb->prefix . "mlw_quizzes";
36
+ $row = $wpdb->get_results("SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name = '$quiz_table_name' AND column_name = 'quiz_author_id'");
37
+ if (empty($row)) {
38
+ $wpdb->query("ALTER TABLE $quiz_table_name ADD quiz_author_id INT NOT NULL");
39
+ }
40
+ $result_table_name = $wpdb->prefix . "mlw_results";
41
+ $row = $wpdb->get_results("SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name = '$result_table_name' AND column_name = 'unique_id'");
42
+ if (empty($row)) {
43
+ $wpdb->query("ALTER TABLE $result_table_name ADD unique_id varchar(255) NOT NULL");
44
+ }
45
+
46
  }
php/admin/quiz-options-page.php CHANGED
@@ -18,12 +18,21 @@ if ( ! defined( 'ABSPATH' ) ) {
18
  function qsm_generate_quiz_options() {
19
 
20
  // Checks if current user can.
21
- if ( ! current_user_can( 'moderate_comments' ) ) {
22
  return;
23
  }
24
-
25
- global $wpdb;
26
  global $mlwQuizMasterNext;
 
 
 
 
 
 
 
 
 
 
27
 
28
  $quiz_name = '';
29
 
18
  function qsm_generate_quiz_options() {
19
 
20
  // Checks if current user can.
21
+ if ( ! current_user_can( 'edit_posts' ) ) {
22
  return;
23
  }
24
+ global $wpdb;
 
25
  global $mlwQuizMasterNext;
26
+
27
+ //Check user capability
28
+ $user = wp_get_current_user();
29
+ if ( in_array( 'author', (array) $user->roles ) ) {
30
+ $quiz_id = isset( $_GET['quiz_id'] ) ? intval( $_GET['quiz_id'] ) : 0;
31
+ $quiz_author_id = $wpdb->get_var( $wpdb->prepare( "SELECT quiz_author_id FROM {$wpdb->prefix}mlw_quizzes WHERE quiz_id=%d AND quiz_author_id=%d LIMIT 1", $quiz_id, $user->ID ) );
32
+ if(!$quiz_author_id){
33
+ wp_die('You are not allow to edit this quiz, You need higher permission!');
34
+ }
35
+ }
36
 
37
  $quiz_name = '';
38
 
php/admin/quizzes-page.php CHANGED
@@ -17,7 +17,7 @@ if ( ! defined( 'ABSPATH' ) ) {
17
  function qsm_generate_quizzes_surveys_page() {
18
 
19
  // Only let admins and editors see this page.
20
- if ( ! current_user_can( 'moderate_comments' ) ) {
21
  return;
22
  }
23
 
@@ -83,19 +83,24 @@ function qsm_generate_quizzes_surveys_page() {
83
  'posts_per_page' => -1,
84
  'post_status' => array('publish', 'pending', 'draft', 'auto-draft', 'future', 'private')
85
  );
 
 
 
 
 
86
  if(isset($_GET['order']) && $_GET['order'] == 'asc'){
87
  $post_arr['orderby'] = isset($_GET['orderby']) && $_GET['orderby'] == 'title' ? 'title' : 'last_activity';
88
  $post_arr['order'] = 'ASC';
89
  // Load our quizzes.
90
- $quizzes = $mlwQuizMasterNext->pluginHelper->get_quizzes(false, $post_arr['orderby'], 'ASC');
91
  }else if( isset($_GET['order']) && $_GET['order'] == 'desc' ){
92
  $post_arr['orderby'] = isset($_GET['orderby']) && $_GET['orderby'] == 'title' ? 'title' : 'last_activity';
93
  $post_arr['order'] = 'DESC';
94
  // Load our quizzes.
95
- $quizzes = $mlwQuizMasterNext->pluginHelper->get_quizzes(false, $post_arr['orderby'], 'DESC');
96
  } else{
97
  // Load our quizzes.
98
- $quizzes = $mlwQuizMasterNext->pluginHelper->get_quizzes();
99
  }
100
 
101
  // Load quiz posts.
17
  function qsm_generate_quizzes_surveys_page() {
18
 
19
  // Only let admins and editors see this page.
20
+ if ( ! current_user_can( 'edit_posts' ) ) {
21
  return;
22
  }
23
 
83
  'posts_per_page' => -1,
84
  'post_status' => array('publish', 'pending', 'draft', 'auto-draft', 'future', 'private')
85
  );
86
+ //Check user role and fetch the quiz
87
+ $user = wp_get_current_user();
88
+ if ( in_array( 'author', (array) $user->roles ) ) {
89
+ $post_arr['author__in'] = [$user->ID];
90
+ }
91
  if(isset($_GET['order']) && $_GET['order'] == 'asc'){
92
  $post_arr['orderby'] = isset($_GET['orderby']) && $_GET['orderby'] == 'title' ? 'title' : 'last_activity';
93
  $post_arr['order'] = 'ASC';
94
  // Load our quizzes.
95
+ $quizzes = $mlwQuizMasterNext->pluginHelper->get_quizzes(false, $post_arr['orderby'], 'ASC', (array) $user->roles, $user->ID);
96
  }else if( isset($_GET['order']) && $_GET['order'] == 'desc' ){
97
  $post_arr['orderby'] = isset($_GET['orderby']) && $_GET['orderby'] == 'title' ? 'title' : 'last_activity';
98
  $post_arr['order'] = 'DESC';
99
  // Load our quizzes.
100
+ $quizzes = $mlwQuizMasterNext->pluginHelper->get_quizzes(false, $post_arr['orderby'], 'DESC',(array) $user->roles, $user->ID);
101
  } else{
102
  // Load our quizzes.
103
+ $quizzes = $mlwQuizMasterNext->pluginHelper->get_quizzes(false, '', '',(array) $user->roles, $user->ID);
104
  }
105
 
106
  // Load quiz posts.
php/classes/class-qmn-plugin-helper.php CHANGED
@@ -107,9 +107,11 @@ class QMNPluginHelper {
107
  * @param bool $include_deleted If set to true, returned array will include all deleted quizzes
108
  * @param string $order_by The column the quizzes should be ordered by
109
  * @param string $order whether the $order_by should be ordered as ascending or decending. Can be "ASC" or "DESC"
 
 
110
  * @return array All of the quizzes as a numerical array of objects
111
  */
112
- public function get_quizzes( $include_deleted = false, $order_by = 'quiz_id', $order = 'DESC' ) {
113
  global $wpdb;
114
 
115
  // Set order direction
@@ -146,9 +148,17 @@ class QMNPluginHelper {
146
  if ( $include_deleted ) {
147
  $delete = '';
148
  }
 
 
 
 
 
 
 
 
149
 
150
  // Get quizzes and return them
151
- $quizzes = $wpdb->get_results( "SELECT * FROM {$wpdb->prefix}mlw_quizzes $delete ORDER BY $order_field $order_direction" );
152
  return $quizzes;
153
  }
154
 
107
  * @param bool $include_deleted If set to true, returned array will include all deleted quizzes
108
  * @param string $order_by The column the quizzes should be ordered by
109
  * @param string $order whether the $order_by should be ordered as ascending or decending. Can be "ASC" or "DESC"
110
+ * @param arr $user_role role of current user
111
+ * @param int $user_id Get the quiz based on user id
112
  * @return array All of the quizzes as a numerical array of objects
113
  */
114
+ public function get_quizzes( $include_deleted = false, $order_by = 'quiz_id', $order = 'DESC', $user_role = array(), $user_id = '' ) {
115
  global $wpdb;
116
 
117
  // Set order direction
148
  if ( $include_deleted ) {
149
  $delete = '';
150
  }
151
+ $user_str = '';
152
+ if ( in_array( 'author', (array) $user_role ) ) {
153
+ if( $user_id && $delete == '' ){
154
+ $user_str = "WHERE quiz_author_id = '$user_id'";
155
+ }else if( $user_id && $delete !== '' ){
156
+ $user_str = " AND quiz_author_id = '$user_id'";
157
+ }
158
+ }
159
 
160
  // Get quizzes and return them
161
+ $quizzes = $wpdb->get_results( "SELECT * FROM {$wpdb->prefix}mlw_quizzes $delete $user_str ORDER BY $order_field $order_direction" );
162
  return $quizzes;
163
  }
164
 
php/classes/class-qmn-quiz-creator.php CHANGED
@@ -70,6 +70,7 @@ class QMNQuizCreator {
70
  public function create_quiz( $quiz_name ) {
71
  global $mlwQuizMasterNext;
72
  global $wpdb;
 
73
  $results = $wpdb->insert(
74
  $wpdb->prefix . 'mlw_quizzes',
75
  array(
@@ -125,6 +126,7 @@ class QMNQuizCreator {
125
  'quiz_views' => 0,
126
  'quiz_taken' => 0,
127
  'deleted' => 0,
 
128
  ),
129
  array(
130
  '%s',
@@ -179,11 +181,11 @@ class QMNQuizCreator {
179
  '%d',
180
  '%d',
181
  '%d',
 
182
  )
183
  );
184
  if ( false !== $results ) {
185
- $new_quiz = $wpdb->insert_id;
186
- $current_user = wp_get_current_user();
187
  $quiz_post = array(
188
  'post_title' => $quiz_name,
189
  'post_content' => "[mlw_quizmaster quiz=$new_quiz]",
@@ -192,7 +194,7 @@ class QMNQuizCreator {
192
  'post_type' => 'quiz',
193
  );
194
  $quiz_post_id = wp_insert_post( $quiz_post );
195
- add_post_meta( $quiz_post_id, 'quiz_id', $new_quiz );
196
 
197
  $mlwQuizMasterNext->alertManager->newAlert(__('Your new quiz or survey has been created successfully. To begin editing, click the Edit link.', 'quiz-master-next'), 'success');
198
  $mlwQuizMasterNext->audit_manager->new_audit( "New Quiz/Survey Has Been Created: $quiz_name" );
70
  public function create_quiz( $quiz_name ) {
71
  global $mlwQuizMasterNext;
72
  global $wpdb;
73
+ $current_user = wp_get_current_user();
74
  $results = $wpdb->insert(
75
  $wpdb->prefix . 'mlw_quizzes',
76
  array(
126
  'quiz_views' => 0,
127
  'quiz_taken' => 0,
128
  'deleted' => 0,
129
+ 'quiz_author_id' => $current_user->ID,
130
  ),
131
  array(
132
  '%s',
181
  '%d',
182
  '%d',
183
  '%d',
184
+ '%d',
185
  )
186
  );
187
  if ( false !== $results ) {
188
+ $new_quiz = $wpdb->insert_id;
 
189
  $quiz_post = array(
190
  'post_title' => $quiz_name,
191
  'post_content' => "[mlw_quizmaster quiz=$new_quiz]",
194
  'post_type' => 'quiz',
195
  );
196
  $quiz_post_id = wp_insert_post( $quiz_post );
197
+ add_post_meta( $quiz_post_id, 'quiz_id', $new_quiz );
198
 
199
  $mlwQuizMasterNext->alertManager->newAlert(__('Your new quiz or survey has been created successfully. To begin editing, click the Edit link.', 'quiz-master-next'), 'success');
200
  $mlwQuizMasterNext->audit_manager->new_audit( "New Quiz/Survey Has Been Created: $quiz_name" );
php/classes/class-qmn-quiz-manager.php CHANGED
@@ -189,92 +189,105 @@ class QMNQuizManager {
189
  ), $atts));
190
 
191
  ob_start();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
192
 
193
- global $wpdb;
194
- global $mlwQuizMasterNext;
195
- global $qmn_allowed_visit;
196
- global $qmn_json_data;
197
- $qmn_json_data = array();
198
- $qmn_allowed_visit = true;
199
- $success = $mlwQuizMasterNext->pluginHelper->prepare_quiz($quiz);
200
- if (false === $success) {
201
- return __('It appears that this quiz is not set up correctly', 'quiz-master-next');
202
- }
203
- $question_amount = intval($question_amount);
204
-
205
- // Legacy variable.
206
- global $mlw_qmn_quiz;
207
- $mlw_qmn_quiz = $quiz;
208
 
209
- $return_display = '';
210
- $qmn_quiz_options = $mlwQuizMasterNext->quiz_settings->get_quiz_options();
211
 
212
- // If quiz options isn't found, stop function.
213
- if (is_null($qmn_quiz_options) || empty($qmn_quiz_options->quiz_name)) {
214
- return __('It appears that this quiz is not set up correctly', 'quiz-master-next');
215
- }
216
 
217
- // Loads Quiz Template.
218
- // The quiz_stye is misspelled because it has always been misspelled and fixing it would break many sites :(.
219
- if ('default' == $qmn_quiz_options->theme_selected) {
220
- $return_display .= '<style type="text/css">' . $qmn_quiz_options->quiz_stye . '</style>';
221
- wp_enqueue_style('qmn_quiz_style', plugins_url('../../css/qmn_quiz.css', __FILE__));
222
- } else {
223
- $registered_template = $mlwQuizMasterNext->pluginHelper->get_quiz_templates($qmn_quiz_options->theme_selected);
224
- // Check direct file first, then check templates folder in plugin, then check templates file in theme.
225
- // If all fails, then load custom styling instead.
226
- if ($registered_template && file_exists($registered_template['path'])) {
227
- wp_enqueue_style('qmn_quiz_template', $registered_template['path'], array(), $mlwQuizMasterNext->version);
228
- } elseif ($registered_template && file_exists(plugin_dir_path(__FILE__) . '../../templates/' . $registered_template['path'])) {
229
- wp_enqueue_style('qmn_quiz_template', plugins_url('../../templates/' . $registered_template['path'], __FILE__), array(), $mlwQuizMasterNext->version);
230
- } elseif ($registered_template && file_exists(get_stylesheet_directory_uri() . '/templates/' . $registered_template['path'])) {
231
- wp_enqueue_style('qmn_quiz_template', get_stylesheet_directory_uri() . '/templates/' . $registered_template['path'], array(), $mlwQuizMasterNext->version);
232
  } else {
233
- echo "<style type='text/css'>{$qmn_quiz_options->quiz_stye}</style>";
 
 
 
 
 
 
 
 
 
 
 
234
  }
235
- }
236
- wp_enqueue_style('qmn_quiz_animation_style', plugins_url('../../css/animate.css', __FILE__));
237
- wp_enqueue_style('qmn_quiz_common_style', plugins_url('../../css/common.css', __FILE__));
238
- wp_enqueue_style('dashicons');
239
-
240
- // Starts to prepare variable array for filters.
241
- $qmn_array_for_variables = array(
242
- 'quiz_id' => $qmn_quiz_options->quiz_id,
243
- 'quiz_name' => $qmn_quiz_options->quiz_name,
244
- 'quiz_system' => $qmn_quiz_options->system,
245
- 'user_ip' => $this->get_user_ip(),
246
- );
247
 
248
- $return_display .= "<script>
249
- if (window.qmn_quiz_data === undefined) {
250
- window.qmn_quiz_data = new Object();
251
- }
252
- </script>";
253
- $qmn_json_data = array(
254
- 'quiz_id' => $qmn_array_for_variables['quiz_id'],
255
- 'quiz_name' => $qmn_array_for_variables['quiz_name'],
256
- 'disable_answer' => $qmn_quiz_options->disable_answer_onselect,
257
- 'ajax_show_correct' => $qmn_quiz_options->ajax_show_correct,
258
- 'progress_bar' => $qmn_quiz_options->progress_bar,
259
- );
260
 
261
- $return_display = apply_filters('qmn_begin_shortcode', $return_display, $qmn_quiz_options, $qmn_array_for_variables);
262
 
263
- // Checks if we should be showing quiz or results page.
264
- if ($qmn_allowed_visit && !isset($_POST["complete_quiz"]) && !empty($qmn_quiz_options->quiz_name)) {
265
- $return_display .= $this->display_quiz($qmn_quiz_options, $qmn_array_for_variables, $question_amount);
266
- } elseif (isset($_POST["complete_quiz"]) && 'confirmation' == $_POST["complete_quiz"] && $_POST["qmn_quiz_id"] == $qmn_array_for_variables["quiz_id"]) {
267
- $return_display .= $this->display_results($qmn_quiz_options, $qmn_array_for_variables);
268
- }
269
 
270
- $qmn_filtered_json = apply_filters('qmn_json_data', $qmn_json_data, $qmn_quiz_options, $qmn_array_for_variables);
271
 
272
- $return_display .= '<script>
273
- window.qmn_quiz_data["' . $qmn_json_data["quiz_id"] . '"] = ' . json_encode($qmn_json_data) . '
274
- </script>';
275
 
276
- $return_display .= ob_get_clean();
277
- $return_display = apply_filters('qmn_end_shortcode', $return_display, $qmn_quiz_options, $qmn_array_for_variables);
 
278
  return $return_display;
279
  }
280
 
@@ -283,6 +296,9 @@ class QMNQuizManager {
283
  'id' => 0,
284
  ), $atts));
285
  ob_start();
 
 
 
286
  global $wpdb;
287
  $result_data = $wpdb->get_row("SELECT * FROM {$wpdb->prefix}mlw_results WHERE result_id = {$id}", ARRAY_A);
288
  $quiz_result = unserialize($result_data['quiz_results']);
@@ -306,7 +322,7 @@ class QMNQuizManager {
306
  'total_questions' => $result_data['total'],
307
  'question_answers_array' => $quiz_result[1],
308
  'comments' => ''
309
- );
310
  $data = QSM_Results_Pages::generate_pages($response_data);
311
  echo htmlspecialchars_decode($data['display']);
312
  $content = ob_get_clean();
@@ -467,8 +483,8 @@ class QMNQuizManager {
467
  wp_enqueue_script('progress-bar', plugins_url('../../js/progressbar.min.js', __FILE__));
468
  wp_enqueue_script( 'jquery-ui-slider-js', '//code.jquery.com/ui/1.12.1/jquery-ui.js' );
469
  wp_enqueue_script( 'jquery-ui-slider-rtl-js', plugins_url('../../js/jquery.ui.slider-rtl.js', __FILE__) );
470
- wp_enqueue_script( 'jquery-ui-slider-rtl-css', plugins_url('../../css/jquery.ui.slider-rtl.css', __FILE__) );
471
- wp_enqueue_script( 'jqueryui-touch-js', '//cdnjs.cloudflare.com/ajax/libs/jqueryui-touch-punch/0.2.3/jquery.ui.touch-punch.min.js' );
472
  wp_enqueue_script('qsm_quiz', plugins_url('../../js/qsm-quiz.js', __FILE__), array('wp-util', 'underscore', 'jquery', 'jquery-ui-tooltip', 'progress-bar'), $mlwQuizMasterNext->version);
473
  wp_localize_script('qsm_quiz', 'qmn_ajax_object', array('ajaxurl' => admin_url('admin-ajax.php'), 'enable_quick_result_mc' => isset($options->enable_quick_result_mc) ? $options->enable_quick_result_mc : '','enable_result_after_timer_end' => isset($options->enable_result_after_timer_end) ? $options->enable_result_after_timer_end : ''));
474
  wp_enqueue_script( 'math_jax', '//cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.2/MathJax.js?config=TeX-MML-AM_CHTML' );
@@ -527,6 +543,7 @@ class QMNQuizManager {
527
  $quiz_display .= "<div name='mlw_error_message_bottom' id='mlw_error_message_bottom' class='qsm-error-message qmn_error_message_section'></div>";
528
  $quiz_display .= "<input type='hidden' name='total_questions' id='total_questions' value='$qmn_total_questions'/>";
529
  $quiz_display .= "<input type='hidden' name='timer' id='timer' value='0'/>";
 
530
  $quiz_display .= "<input type='hidden' class='qmn_quiz_id' name='qmn_quiz_id' id='qmn_quiz_id' value='{$quiz_data['quiz_id']}'/>";
531
  $quiz_display .= "<input type='hidden' name='complete_quiz' value='confirmation' />";
532
  if (isset($_GET['payment_id']) && $_GET['payment_id'] != '') {
@@ -551,7 +568,7 @@ class QMNQuizManager {
551
  public function display_pages($options, $quiz_data) {
552
  global $mlwQuizMasterNext;
553
  global $qmn_json_data;
554
- ob_start();
555
  $pages = $mlwQuizMasterNext->pluginHelper->get_quiz_setting('pages', array());
556
  $questions = QSM_Questions::load_questions_by_pages($options->quiz_id);
557
  $question_list = '';
@@ -934,7 +951,7 @@ class QMNQuizManager {
934
  'quiz_id' => $options->quiz_id,
935
  'quiz_name' => $options->quiz_name,
936
  'quiz_system' => $options->system,
937
- 'quiz_payment_id' => isset($_POST['main_payment_id']) ? sanitize_text_field(intval($_POST['main_payment_id'])) : ''
938
  );
939
  $post_data = array(
940
  'g-recaptcha-response' => isset($_POST['g-recaptcha-response']) ? sanitize_textarea_field($_POST['g-recaptcha-response']) : ''
@@ -951,7 +968,7 @@ class QMNQuizManager {
951
  exit;
952
  }
953
  }
954
- }
955
  echo json_encode($this->submit_results($options, $data));
956
  die();
957
  }
@@ -1017,8 +1034,10 @@ class QMNQuizManager {
1017
  }
1018
 
1019
  $mlw_qmn_timer = isset($_POST["timer"]) ? sanitize_text_field(intval($_POST["timer"])) : 0;
 
1020
  $qmn_array_for_variables['user_id'] = get_current_user_id();
1021
  $qmn_array_for_variables['timer'] = $mlw_qmn_timer;
 
1022
  $qmn_array_for_variables['time_taken'] = current_time('h:i:s A m/d/Y');
1023
  $qmn_array_for_variables['contact'] = $contact_responses;
1024
 
@@ -1039,6 +1058,7 @@ class QMNQuizManager {
1039
  if ( is_plugin_active( 'qsm-save-resume/qsm-save-resume.php' ) != 1 && $qmn_quiz_options->enable_retake_quiz_button == 1 ) {
1040
  $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') .'</a>';
1041
  }
 
1042
  // If the store responses in database option is set to Yes.
1043
  if (0 != $qmn_quiz_options->store_responses) {
1044
 
@@ -1048,6 +1068,7 @@ class QMNQuizManager {
1048
  $qmn_array_for_variables['question_answers_array'],
1049
  htmlspecialchars(stripslashes($qmn_array_for_variables['comments']), ENT_QUOTES),
1050
  'contact' => $contact_responses,
 
1051
  );
1052
  $results_array = apply_filters('qsm_results_array', $results_array, $qmn_array_for_variables);
1053
  $serialized_results = serialize($results_array);
@@ -1055,6 +1076,7 @@ class QMNQuizManager {
1055
  // Inserts the responses in the database.
1056
  global $wpdb;
1057
  $table_name = $wpdb->prefix . "mlw_results";
 
1058
  $results_insert = $wpdb->insert(
1059
  $table_name, array(
1060
  'quiz_id' => $qmn_array_for_variables['quiz_id'],
@@ -1074,6 +1096,7 @@ class QMNQuizManager {
1074
  'time_taken_real' => date('Y-m-d H:i:s', strtotime($qmn_array_for_variables['time_taken'])),
1075
  'quiz_results' => $serialized_results,
1076
  'deleted' => 0,
 
1077
  ), array(
1078
  '%d',
1079
  '%s',
@@ -1092,6 +1115,7 @@ class QMNQuizManager {
1092
  '%s',
1093
  '%s',
1094
  '%d',
 
1095
  )
1096
  );
1097
  }
@@ -1121,7 +1145,9 @@ class QMNQuizManager {
1121
  } else {
1122
  $result_display .= 'Thank you.';
1123
  }
1124
-
 
 
1125
  // Prepares data to be sent back to front-end.
1126
  $return_array = array(
1127
  'display' => htmlspecialchars_decode($result_display),
@@ -1649,17 +1675,18 @@ $qmnQuizManager = new QMNQuizManager();
1649
 
1650
  add_filter('qmn_begin_shortcode', 'qmn_require_login_check', 10, 3);
1651
 
1652
- function qmn_require_login_check($display, $qmn_quiz_options, $qmn_array_for_variables) {
1653
  global $qmn_allowed_visit;
1654
  if ($qmn_quiz_options->require_log_in == 1 && !is_user_logged_in()) {
1655
  $qmn_allowed_visit = false;
1656
- if(isset($qmn_quiz_options->require_log_in_text_msg) && $qmn_quiz_options->require_log_in_text_msg != ''){
1657
- $mlw_message = wpautop(htmlspecialchars_decode($qmn_quiz_options->require_log_in_text_msg, ENT_QUOTES));
1658
  }else{
1659
  $mlw_message = wpautop(htmlspecialchars_decode($qmn_quiz_options->require_log_in_text, ENT_QUOTES));
1660
  }
1661
  $mlw_message = apply_filters('mlw_qmn_template_variable_quiz_page', $mlw_message, $qmn_array_for_variables);
1662
  $mlw_message = str_replace("\n", "<br>", $mlw_message);
 
1663
  $display .= $mlw_message;
1664
  $display .= wp_login_form(array('echo' => false));
1665
  }
@@ -1823,4 +1850,7 @@ function mlw_qmn_set_html_content_type() {
1823
 
1824
  return 'text/html';
1825
  }
1826
- ?>
 
 
 
189
  ), $atts));
190
 
191
  ob_start();
192
+ if(isset($_GET['result_id']) && $_GET['result_id'] != ''){
193
+ global $wpdb;
194
+ $result_unique_id = $_GET['result_id'];
195
+ $query = $wpdb->prepare("SELECT result_id FROM {$wpdb->prefix}mlw_results WHERE unique_id = %s",$result_unique_id);
196
+ $result = $wpdb->get_row($query,ARRAY_A);
197
+ if( !empty($result) && isset($result['result_id']) ){
198
+ $result_id = $result['result_id'];
199
+ $return_display = do_shortcode( '[qsm_result id="'. $result_id .'"]' );
200
+ }else{
201
+ $return_display = 'Result id is wrong!';
202
+ }
203
+ $return_display .= ob_get_clean();
204
+ }else{
205
+ global $wpdb;
206
+ global $mlwQuizMasterNext;
207
+ global $qmn_allowed_visit;
208
+ global $qmn_json_data;
209
+ $qmn_json_data = array();
210
+ $qmn_allowed_visit = true;
211
+ $success = $mlwQuizMasterNext->pluginHelper->prepare_quiz($quiz);
212
+ if (false === $success) {
213
+ return __('It appears that this quiz is not set up correctly', 'quiz-master-next');
214
+ }
215
+ $question_amount = intval($question_amount);
216
 
217
+ // Legacy variable.
218
+ global $mlw_qmn_quiz;
219
+ $mlw_qmn_quiz = $quiz;
 
 
 
 
 
 
 
 
 
 
 
 
220
 
221
+ $return_display = '';
222
+ $qmn_quiz_options = $mlwQuizMasterNext->quiz_settings->get_quiz_options();
223
 
224
+ // If quiz options isn't found, stop function.
225
+ if (is_null($qmn_quiz_options) || empty($qmn_quiz_options->quiz_name)) {
226
+ return __('It appears that this quiz is not set up correctly', 'quiz-master-next');
227
+ }
228
 
229
+ // Loads Quiz Template.
230
+ // The quiz_stye is misspelled because it has always been misspelled and fixing it would break many sites :(.
231
+ if ('default' == $qmn_quiz_options->theme_selected) {
232
+ $return_display .= '<style type="text/css">' . $qmn_quiz_options->quiz_stye . '</style>';
233
+ wp_enqueue_style('qmn_quiz_style', plugins_url('../../css/qmn_quiz.css', __FILE__));
 
 
 
 
 
 
 
 
 
 
234
  } else {
235
+ $registered_template = $mlwQuizMasterNext->pluginHelper->get_quiz_templates($qmn_quiz_options->theme_selected);
236
+ // Check direct file first, then check templates folder in plugin, then check templates file in theme.
237
+ // If all fails, then load custom styling instead.
238
+ if ($registered_template && file_exists($registered_template['path'])) {
239
+ wp_enqueue_style('qmn_quiz_template', $registered_template['path'], array(), $mlwQuizMasterNext->version);
240
+ } elseif ($registered_template && file_exists(plugin_dir_path(__FILE__) . '../../templates/' . $registered_template['path'])) {
241
+ wp_enqueue_style('qmn_quiz_template', plugins_url('../../templates/' . $registered_template['path'], __FILE__), array(), $mlwQuizMasterNext->version);
242
+ } elseif ($registered_template && file_exists(get_stylesheet_directory_uri() . '/templates/' . $registered_template['path'])) {
243
+ wp_enqueue_style('qmn_quiz_template', get_stylesheet_directory_uri() . '/templates/' . $registered_template['path'], array(), $mlwQuizMasterNext->version);
244
+ } else {
245
+ echo "<style type='text/css'>{$qmn_quiz_options->quiz_stye}</style>";
246
+ }
247
  }
248
+ wp_enqueue_style('qmn_quiz_animation_style', plugins_url('../../css/animate.css', __FILE__));
249
+ wp_enqueue_style('qmn_quiz_common_style', plugins_url('../../css/common.css', __FILE__));
250
+ wp_enqueue_style('dashicons');
251
+
252
+ // Starts to prepare variable array for filters.
253
+ $qmn_array_for_variables = array(
254
+ 'quiz_id' => $qmn_quiz_options->quiz_id,
255
+ 'quiz_name' => $qmn_quiz_options->quiz_name,
256
+ 'quiz_system' => $qmn_quiz_options->system,
257
+ 'user_ip' => $this->get_user_ip(),
258
+ );
 
259
 
260
+ $return_display .= "<script>
261
+ if (window.qmn_quiz_data === undefined) {
262
+ window.qmn_quiz_data = new Object();
263
+ }
264
+ </script>";
265
+ $qmn_json_data = array(
266
+ 'quiz_id' => $qmn_array_for_variables['quiz_id'],
267
+ 'quiz_name' => $qmn_array_for_variables['quiz_name'],
268
+ 'disable_answer' => $qmn_quiz_options->disable_answer_onselect,
269
+ 'ajax_show_correct' => $qmn_quiz_options->ajax_show_correct,
270
+ 'progress_bar' => $qmn_quiz_options->progress_bar,
271
+ );
272
 
273
+ $return_display = apply_filters('qmn_begin_shortcode', $return_display, $qmn_quiz_options, $qmn_array_for_variables);
274
 
275
+ // Checks if we should be showing quiz or results page.
276
+ if ($qmn_allowed_visit && !isset($_POST["complete_quiz"]) && !empty($qmn_quiz_options->quiz_name)) {
277
+ $return_display .= $this->display_quiz($qmn_quiz_options, $qmn_array_for_variables, $question_amount);
278
+ } elseif (isset($_POST["complete_quiz"]) && 'confirmation' == $_POST["complete_quiz"] && $_POST["qmn_quiz_id"] == $qmn_array_for_variables["quiz_id"]) {
279
+ $return_display .= $this->display_results($qmn_quiz_options, $qmn_array_for_variables);
280
+ }
281
 
282
+ $qmn_filtered_json = apply_filters('qmn_json_data', $qmn_json_data, $qmn_quiz_options, $qmn_array_for_variables);
283
 
284
+ $return_display .= '<script>
285
+ window.qmn_quiz_data["' . $qmn_json_data["quiz_id"] . '"] = ' . json_encode($qmn_json_data) . '
286
+ </script>';
287
 
288
+ $return_display .= ob_get_clean();
289
+ $return_display = apply_filters('qmn_end_shortcode', $return_display, $qmn_quiz_options, $qmn_array_for_variables);
290
+ }
291
  return $return_display;
292
  }
293
 
296
  'id' => 0,
297
  ), $atts));
298
  ob_start();
299
+ if($id == 0){
300
+ $id = isset($_GET['result_id']) ? $_GET['result_id'] : 0;
301
+ }
302
  global $wpdb;
303
  $result_data = $wpdb->get_row("SELECT * FROM {$wpdb->prefix}mlw_results WHERE result_id = {$id}", ARRAY_A);
304
  $quiz_result = unserialize($result_data['quiz_results']);
322
  'total_questions' => $result_data['total'],
323
  'question_answers_array' => $quiz_result[1],
324
  'comments' => ''
325
+ );
326
  $data = QSM_Results_Pages::generate_pages($response_data);
327
  echo htmlspecialchars_decode($data['display']);
328
  $content = ob_get_clean();
483
  wp_enqueue_script('progress-bar', plugins_url('../../js/progressbar.min.js', __FILE__));
484
  wp_enqueue_script( 'jquery-ui-slider-js', '//code.jquery.com/ui/1.12.1/jquery-ui.js' );
485
  wp_enqueue_script( 'jquery-ui-slider-rtl-js', plugins_url('../../js/jquery.ui.slider-rtl.js', __FILE__) );
486
+ wp_enqueue_style( 'jquery-ui-slider-rtl-css', plugins_url('../../css/jquery.ui.slider-rtl.css', __FILE__) );
487
+ wp_enqueue_script( 'jqueryui-touch-js', '//cdnjs.cloudflare.com/ajax/libs/jqueryui-touch-punch/0.2.3/jquery.ui.touch-punch.min.js' );
488
  wp_enqueue_script('qsm_quiz', plugins_url('../../js/qsm-quiz.js', __FILE__), array('wp-util', 'underscore', 'jquery', 'jquery-ui-tooltip', 'progress-bar'), $mlwQuizMasterNext->version);
489
  wp_localize_script('qsm_quiz', 'qmn_ajax_object', array('ajaxurl' => admin_url('admin-ajax.php'), 'enable_quick_result_mc' => isset($options->enable_quick_result_mc) ? $options->enable_quick_result_mc : '','enable_result_after_timer_end' => isset($options->enable_result_after_timer_end) ? $options->enable_result_after_timer_end : ''));
490
  wp_enqueue_script( 'math_jax', '//cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.2/MathJax.js?config=TeX-MML-AM_CHTML' );
543
  $quiz_display .= "<div name='mlw_error_message_bottom' id='mlw_error_message_bottom' class='qsm-error-message qmn_error_message_section'></div>";
544
  $quiz_display .= "<input type='hidden' name='total_questions' id='total_questions' value='$qmn_total_questions'/>";
545
  $quiz_display .= "<input type='hidden' name='timer' id='timer' value='0'/>";
546
+ $quiz_display .= "<input type='hidden' name='timer_ms' id='timer_ms' value='0'/>";
547
  $quiz_display .= "<input type='hidden' class='qmn_quiz_id' name='qmn_quiz_id' id='qmn_quiz_id' value='{$quiz_data['quiz_id']}'/>";
548
  $quiz_display .= "<input type='hidden' name='complete_quiz' value='confirmation' />";
549
  if (isset($_GET['payment_id']) && $_GET['payment_id'] != '') {
568
  public function display_pages($options, $quiz_data) {
569
  global $mlwQuizMasterNext;
570
  global $qmn_json_data;
571
+ ob_start();
572
  $pages = $mlwQuizMasterNext->pluginHelper->get_quiz_setting('pages', array());
573
  $questions = QSM_Questions::load_questions_by_pages($options->quiz_id);
574
  $question_list = '';
951
  'quiz_id' => $options->quiz_id,
952
  'quiz_name' => $options->quiz_name,
953
  'quiz_system' => $options->system,
954
+ 'quiz_payment_id' => isset($_POST['main_payment_id']) ? sanitize_text_field($_POST['main_payment_id']) : ''
955
  );
956
  $post_data = array(
957
  'g-recaptcha-response' => isset($_POST['g-recaptcha-response']) ? sanitize_textarea_field($_POST['g-recaptcha-response']) : ''
968
  exit;
969
  }
970
  }
971
+ }
972
  echo json_encode($this->submit_results($options, $data));
973
  die();
974
  }
1034
  }
1035
 
1036
  $mlw_qmn_timer = isset($_POST["timer"]) ? sanitize_text_field(intval($_POST["timer"])) : 0;
1037
+ $mlw_qmn_timer_ms = isset($_POST["timer_ms"]) ? sanitize_text_field(intval($_POST["timer_ms"])) : 0;
1038
  $qmn_array_for_variables['user_id'] = get_current_user_id();
1039
  $qmn_array_for_variables['timer'] = $mlw_qmn_timer;
1040
+ $qmn_array_for_variables['timer_ms'] = $mlw_qmn_timer_ms;
1041
  $qmn_array_for_variables['time_taken'] = current_time('h:i:s A m/d/Y');
1042
  $qmn_array_for_variables['contact'] = $contact_responses;
1043
 
1058
  if ( is_plugin_active( 'qsm-save-resume/qsm-save-resume.php' ) != 1 && $qmn_quiz_options->enable_retake_quiz_button == 1 ) {
1059
  $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') .'</a>';
1060
  }
1061
+ $unique_id = md5(date("Y-m-d H:i:s"));
1062
  // If the store responses in database option is set to Yes.
1063
  if (0 != $qmn_quiz_options->store_responses) {
1064
 
1068
  $qmn_array_for_variables['question_answers_array'],
1069
  htmlspecialchars(stripslashes($qmn_array_for_variables['comments']), ENT_QUOTES),
1070
  'contact' => $contact_responses,
1071
+ 'timer_ms' => intval($qmn_array_for_variables['timer_ms']),
1072
  );
1073
  $results_array = apply_filters('qsm_results_array', $results_array, $qmn_array_for_variables);
1074
  $serialized_results = serialize($results_array);
1076
  // Inserts the responses in the database.
1077
  global $wpdb;
1078
  $table_name = $wpdb->prefix . "mlw_results";
1079
+
1080
  $results_insert = $wpdb->insert(
1081
  $table_name, array(
1082
  'quiz_id' => $qmn_array_for_variables['quiz_id'],
1096
  'time_taken_real' => date('Y-m-d H:i:s', strtotime($qmn_array_for_variables['time_taken'])),
1097
  'quiz_results' => $serialized_results,
1098
  'deleted' => 0,
1099
+ 'unique_id' => $unique_id,
1100
  ), array(
1101
  '%d',
1102
  '%s',
1115
  '%s',
1116
  '%s',
1117
  '%d',
1118
+ '%s',
1119
  )
1120
  );
1121
  }
1145
  } else {
1146
  $result_display .= 'Thank you.';
1147
  }
1148
+
1149
+ $result_display = str_replace('%FB_RESULT_ID%', $unique_id, $result_display);
1150
+
1151
  // Prepares data to be sent back to front-end.
1152
  $return_array = array(
1153
  'display' => htmlspecialchars_decode($result_display),
1675
 
1676
  add_filter('qmn_begin_shortcode', 'qmn_require_login_check', 10, 3);
1677
 
1678
+ function qmn_require_login_check($display, $qmn_quiz_options, $qmn_array_for_variables) {
1679
  global $qmn_allowed_visit;
1680
  if ($qmn_quiz_options->require_log_in == 1 && !is_user_logged_in()) {
1681
  $qmn_allowed_visit = false;
1682
+ if(isset($qmn_quiz_options->require_log_in_text) && $qmn_quiz_options->require_log_in_text != ''){
1683
+ $mlw_message = wpautop(htmlspecialchars_decode($qmn_quiz_options->require_log_in_text, ENT_QUOTES));
1684
  }else{
1685
  $mlw_message = wpautop(htmlspecialchars_decode($qmn_quiz_options->require_log_in_text, ENT_QUOTES));
1686
  }
1687
  $mlw_message = apply_filters('mlw_qmn_template_variable_quiz_page', $mlw_message, $qmn_array_for_variables);
1688
  $mlw_message = str_replace("\n", "<br>", $mlw_message);
1689
+ $display .= do_shortcode($mlw_message);
1690
  $display .= $mlw_message;
1691
  $display .= wp_login_form(array('echo' => false));
1692
  }
1850
 
1851
  return 'text/html';
1852
  }
1853
+
1854
+ function qsm_time_in_milliseconds() {
1855
+ return round(microtime(true) * 1000);
1856
+ }
php/classes/class-qsm-contact-manager.php CHANGED
@@ -97,12 +97,12 @@ class QSM_Contact_Manager {
97
  }
98
  ?>
99
  <span class='mlw_qmn_question qsm_question'><?php echo htmlspecialchars_decode( $options->phone_field_text, ENT_QUOTES ); ?></span>
100
- <input <?php if($contact_disable_autofill){ echo "autocomplete='off'"; } ?> type='text' class='<?php echo esc_attr( $class ); ?>' x-webkit-speech name='mlwUserPhone' placeholder="<?php echo htmlspecialchars_decode( $options->phone_field_text, ENT_QUOTES ); ?>" value='' />
101
  <?php
102
  }
103
  } elseif ( ! empty( $fields ) && is_array( $fields ) ) {
104
 
105
- // Cycle through each of the contact fields.
106
  $total_fields = count( $fields );
107
  for ( $i = 0; $i < $total_fields; $i++ ) {
108
 
@@ -124,9 +124,12 @@ class QSM_Contact_Manager {
124
  if ( ( 'true' === $fields[ $i ]["required"] || true === $fields[ $i ]["required"] ) && ! $fields_hidden ) {
125
  $class = 'mlwRequiredText qsm_required_text';
126
  }
 
 
 
127
  ?>
128
  <span class='mlw_qmn_question qsm_question'><?php echo $fields[ $i ]['label']; ?></span>
129
- <input <?php if($contact_disable_autofill){ echo "autocomplete='off'"; } ?> type='text' class='<?php echo esc_attr( $class ); ?>' x-webkit-speech name='contact_field_<?php echo $i; ?>' value='<?php echo esc_attr( $value ); ?>' placeholder="<?php echo $fields[ $i ]['label']; ?>" />
130
  <?php
131
  break;
132
 
97
  }
98
  ?>
99
  <span class='mlw_qmn_question qsm_question'><?php echo htmlspecialchars_decode( $options->phone_field_text, ENT_QUOTES ); ?></span>
100
+ <input <?php if($contact_disable_autofill){ echo "autocomplete='off'"; } ?> type='number' class='<?php echo esc_attr( $class ); ?>' x-webkit-speech name='mlwUserPhone' placeholder="<?php echo htmlspecialchars_decode( $options->phone_field_text, ENT_QUOTES ); ?>" value='' />
101
  <?php
102
  }
103
  } elseif ( ! empty( $fields ) && is_array( $fields ) ) {
104
 
105
+ // Cycle through each of the contact fields.
106
  $total_fields = count( $fields );
107
  for ( $i = 0; $i < $total_fields; $i++ ) {
108
 
124
  if ( ( 'true' === $fields[ $i ]["required"] || true === $fields[ $i ]["required"] ) && ! $fields_hidden ) {
125
  $class = 'mlwRequiredText qsm_required_text';
126
  }
127
+ if($fields[ $i ]['use'] == 'phone'){
128
+ $class = 'mlwRequiredNumber qsm_required_text';
129
+ }
130
  ?>
131
  <span class='mlw_qmn_question qsm_question'><?php echo $fields[ $i ]['label']; ?></span>
132
+ <input <?php if($contact_disable_autofill){ echo "autocomplete='off'"; } ?> type='<?php echo $fields[ $i ]['use'] == 'phone' ? 'number' : 'text'; ?>' class='<?php echo esc_attr( $class ); ?>' x-webkit-speech name='contact_field_<?php echo $i; ?>' value='<?php echo esc_attr( $value ); ?>' placeholder="<?php echo $fields[ $i ]['label']; ?>" />
133
  <?php
134
  break;
135
 
php/classes/class-qsm-fields.php CHANGED
@@ -142,6 +142,26 @@ class QSM_Fields {
142
  </tr>
143
  <?php
144
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
145
 
146
  /**
147
  * Generates a textarea field using the WP Editor
142
  </tr>
143
  <?php
144
  }
145
+
146
+ public static function generate_select_page_field( $field, $value ) {
147
+ ?>
148
+ <tr valign="top">
149
+ <th scope="row"><label for="<?php echo $field["id"]; ?>"><?php echo $field["label"]; ?></label></th>
150
+ <td>
151
+ <select id="<?php echo $field["id"]; ?>" name="<?php echo $field["id"]; ?>">
152
+ <option value="">Select Page</option>
153
+ <?php
154
+ $pages = get_pages();
155
+ foreach ( $pages as $page ) { ?>
156
+ <option value="<?php echo get_page_link( $page->ID ) ?>" <?php selected($value, get_page_link( $page->ID )); ?> ><?php echo $page->post_title ?></option>;
157
+ <?php } ?>
158
+ </select>
159
+ <br/>
160
+ <b style="color: red;">Note: </b><?php echo isset($field['note']) ? $field['note'] : ''; ?>
161
+ </td>
162
+ </tr>
163
+ <?php
164
+ }
165
 
166
  /**
167
  * Generates a textarea field using the WP Editor
php/classes/class-qsm-install.php CHANGED
@@ -100,16 +100,7 @@ class QSM_Install {
100
  ),
101
  'default' => 0
102
  );
103
- $mlwQuizMasterNext->pluginHelper->register_quiz_setting( $field_array, 'quiz_options' );
104
-
105
- // Registers required text setting
106
- $field_array = array(
107
- 'id' => 'require_log_in_text_msg',
108
- 'label' => __('Text for non logged in user. Note: This option will work if above option set to yes', 'quiz-master-next'),
109
- 'type' => 'text',
110
- 'default' => 'This quiz is for logged in users only.'
111
- );
112
- $mlwQuizMasterNext->pluginHelper->register_quiz_setting( $field_array, 'quiz_options' );
113
 
114
  // Registers pagination setting
115
  $field_array = array(
@@ -914,6 +905,15 @@ class QSM_Install {
914
  'type' => 'text',
915
  'default' => 'The entered text is not correct!'
916
  );
 
 
 
 
 
 
 
 
 
917
  $mlwQuizMasterNext->pluginHelper->register_quiz_setting( $field_array, 'quiz_text' );
918
  }
919
 
@@ -1049,7 +1049,7 @@ class QSM_Install {
1049
  user_ip TEXT NOT NULL,
1050
  time_taken TEXT NOT NULL,
1051
  time_taken_real DATETIME NOT NULL,
1052
- quiz_results TEXT NOT NULL,
1053
  deleted INT NOT NULL,
1054
  PRIMARY KEY (result_id)
1055
  ) $charset_collate;";
100
  ),
101
  'default' => 0
102
  );
103
+ $mlwQuizMasterNext->pluginHelper->register_quiz_setting( $field_array, 'quiz_options' );
 
 
 
 
 
 
 
 
 
104
 
105
  // Registers pagination setting
106
  $field_array = array(
905
  'type' => 'text',
906
  'default' => 'The entered text is not correct!'
907
  );
908
+ $mlwQuizMasterNext->pluginHelper->register_quiz_setting( $field_array, 'quiz_text' );
909
+
910
+ // result page for sharing
911
+ $field_array = array(
912
+ 'id' => 'result_page_fb_image',
913
+ 'label' => __('Add image link for facebook sharing', 'quiz-master-next'),
914
+ 'type' => 'text',
915
+ 'default' => QSM_PLUGIN_URL . 'assets/icon-200x200.png',
916
+ );
917
  $mlwQuizMasterNext->pluginHelper->register_quiz_setting( $field_array, 'quiz_text' );
918
  }
919
 
1049
  user_ip TEXT NOT NULL,
1050
  time_taken TEXT NOT NULL,
1051
  time_taken_real DATETIME NOT NULL,
1052
+ quiz_results MEDIUMTEXT NOT NULL,
1053
  deleted INT NOT NULL,
1054
  PRIMARY KEY (result_id)
1055
  ) $charset_collate;";
php/question-types.php CHANGED
@@ -1265,6 +1265,7 @@ function qsm_question_title_func($question,$question_type = ''){
1265
  $question_title = $question;
1266
  global $wp_embed,$mlwQuizMasterNext;
1267
  $question_title = $wp_embed->run_shortcode($question_title);
 
1268
  $polar_extra_class = '';
1269
  if($question_type == 'polar'){
1270
  $polar_extra_class = 'question-type-polar-s';
1265
  $question_title = $question;
1266
  global $wp_embed,$mlwQuizMasterNext;
1267
  $question_title = $wp_embed->run_shortcode($question_title);
1268
+ $question_title = 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>",$question_title);
1269
  $polar_extra_class = '';
1270
  if($question_type == 'polar'){
1271
  $polar_extra_class = 'question-type-polar-s';
php/shortcodes.php CHANGED
@@ -1,4 +1,5 @@
1
  <?php
 
2
  /**
3
  * Displays a link to a quiz using ID. Used [qsm_link id=1]Click Here[/qsm_link]
4
  *
@@ -7,33 +8,34 @@
7
  * @param string $content The text to be used for the link
8
  * @return string The HTML the shortcode will be replaced with
9
  */
10
- function qsm_quiz_link_shortcode( $atts, $content = '' ) {
11
  extract(shortcode_atts(array(
12
  'id' => 0,
13
  'class' => '',
14
  'target' => ''
15
- ), $atts));
16
- $id = intval( $id );
17
 
18
  // Find the permalink by finding the post with the meta_key 'quiz_id' of supplied quiz
19
  $permalink = '';
20
- $my_query = new WP_Query( array( 'post_type' => 'quiz', 'meta_key' => 'quiz_id', 'meta_value' => $id, 'posts_per_page' => 1, 'post_status' => 'publish' ) );
21
- if ( $my_query->have_posts() ) {
22
- while ( $my_query->have_posts() ) {
23
- $my_query->the_post();
24
- $permalink = get_permalink();
25
- }
26
- }
27
  wp_reset_postdata();
28
-
29
  // Craft the target attribute if one is passed to shortcode
30
  $target_html = '';
31
- if ( ! empty( $target ) ) {
32
- $target_html = "target='" . esc_attr( $target ) . "'";
33
  }
34
- return "<a href='" . esc_url( $permalink ) . "' class='" . esc_attr( $class ) . "' $target_html>" . esc_html( $content ) . "</a>";
35
  }
36
- add_shortcode( 'qsm_link', 'qsm_quiz_link_shortcode' );
 
37
 
38
  /**
39
  * Displays a list of most recently created quizes [qsm_recent_quizzes]
@@ -44,31 +46,30 @@ add_shortcode( 'qsm_link', 'qsm_quiz_link_shortcode' );
44
  * @return string - list of quizzes
45
  * Shortcode call - [qsm_recent_quizzes no_of_quizzes=5 include_future_quizzes='no' ]
46
  */
47
-
48
  function qsm_display_recent_quizzes($attrs) {
49
 
50
- $no_of_quizzes = isset($attrs['no_of_quizzes'])? $attrs['no_of_quizzes']:10;
51
- $include_future_quizzes = isset($attrs['include_future_quizzes'])? $attrs['include_future_quizzes']: true;
52
  global $wpdb;
53
  wp_enqueue_style('quizzes-list', plugins_url('../css/quizzes-list.css', __FILE__));
54
 
55
- $quiz_tbl = $wpdb->prefix.'mlw_quizzes';
56
-
57
  $query = "SELECT quiz_id, quiz_name, quiz_settings FROM $quiz_tbl WHERE deleted=0 ORDER BY quiz_id DESC";
58
  $quizzes = $wpdb->get_results($query);
59
  $result = '<div class="outer-con">';
60
  $i = 0;
61
- foreach($quizzes as $quiz) {
62
- if($i < $no_of_quizzes) {
63
  $setting = unserialize($quiz->quiz_settings);
64
  $options = unserialize($setting['quiz_options']);
65
-
66
  $start_date = $options['scheduled_time_start'];
67
  $end_date = $options['scheduled_time_end'];
68
  $today = date('m/d/Y');
69
- if($end_date!='' && $end_date < $today)
70
  continue;
71
- else if($include_future_quizzes == 'no' && $start_date > $today)
72
  continue;
73
  else {
74
  $title = $quiz->quiz_name;
@@ -87,19 +88,158 @@ function qsm_display_recent_quizzes($attrs) {
87
  }
88
  }
89
  }
90
- if($i == 0)
91
  $result .= "No quiz found";
92
  $result .= "</div>";
93
  return $result;
94
-
95
  }
 
96
  add_shortcode('qsm_recent_quizzes', 'qsm_display_recent_quizzes');
97
 
98
  /**
99
  * @since 6.4.1
100
  */
101
-
102
  function qsm_load_main_scripts() {
103
- wp_enqueue_script( 'jquery' );
104
  }
105
- add_action( 'wp_enqueue_scripts', 'qsm_load_main_scripts' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  <?php
2
+
3
  /**
4
  * Displays a link to a quiz using ID. Used [qsm_link id=1]Click Here[/qsm_link]
5
  *
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' => '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]
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
+ $quiz_tbl = $wpdb->prefix . 'mlw_quizzes';
57
+
58
  $query = "SELECT quiz_id, quiz_name, quiz_settings FROM $quiz_tbl WHERE deleted=0 ORDER BY quiz_id DESC";
59
  $quizzes = $wpdb->get_results($query);
60
  $result = '<div class="outer-con">';
61
  $i = 0;
62
+ foreach ($quizzes as $quiz) {
63
+ if ($i < $no_of_quizzes) {
64
  $setting = unserialize($quiz->quiz_settings);
65
  $options = unserialize($setting['quiz_options']);
66
+
67
  $start_date = $options['scheduled_time_start'];
68
  $end_date = $options['scheduled_time_end'];
69
  $today = date('m/d/Y');
70
+ if ($end_date != '' && $end_date < $today)
71
  continue;
72
+ else if ($include_future_quizzes == 'no' && $start_date > $today)
73
  continue;
74
  else {
75
  $title = $quiz->quiz_name;
88
  }
89
  }
90
  }
91
+ if ($i == 0)
92
  $result .= "No quiz found";
93
  $result .= "</div>";
94
  return $result;
 
95
  }
96
+
97
  add_shortcode('qsm_recent_quizzes', 'qsm_display_recent_quizzes');
98
 
99
  /**
100
  * @since 6.4.1
101
  */
 
102
  function qsm_load_main_scripts() {
103
+ wp_enqueue_script('jquery');
104
  }
105
+
106
+ add_action('wp_enqueue_scripts', 'qsm_load_main_scripts');
107
+
108
+ /**
109
+ * Add Meta data for facebook share
110
+ * @global obj $mlwQuizMasterNext
111
+ * @global obj $wpdb
112
+ * @global obj $wp_query
113
+ */
114
+ function qsm_generate_fb_header_metadata() {
115
+ if (isset($_GET['result_id']) && $_GET['result_id'] != '') {
116
+ $settings = (array) get_option('qmn-settings');
117
+ $facebook_app_id = '483815031724529';
118
+ if (isset($settings['facebook_app_id'])) {
119
+ $facebook_app_id = esc_js($settings['facebook_app_id']);
120
+ }
121
+ global $mlwQuizMasterNext, $wpdb, $wp_query;
122
+ $result_id = sanitize_text_field($_GET['result_id']);
123
+ $results_data = $wpdb->get_row("SELECT * FROM {$wpdb->prefix}mlw_results WHERE unique_id = '$result_id'");
124
+ if ($results_data) {
125
+ // Prepare responses array.
126
+ if (is_serialized($results_data->quiz_results) && is_array(@unserialize($results_data->quiz_results))) {
127
+ $results = unserialize($results_data->quiz_results);
128
+ if (!isset($results["contact"])) {
129
+ $results["contact"] = array();
130
+ }
131
+ } else {
132
+ $template = str_replace("%QUESTIONS_ANSWERS%", $results_data->quiz_results, $template);
133
+ $template = str_replace("%TIMER%", '', $template);
134
+ $template = str_replace("%COMMENT_SECTION%", '', $template);
135
+ $results = array(
136
+ 0,
137
+ array(),
138
+ '',
139
+ 'contact' => array()
140
+ );
141
+ }
142
+ // Prepare full results array.
143
+ $results_array = array(
144
+ 'quiz_id' => $results_data->quiz_id,
145
+ 'quiz_name' => $results_data->quiz_name,
146
+ 'quiz_system' => $results_data->quiz_system,
147
+ 'user_name' => $results_data->name,
148
+ 'user_business' => $results_data->business,
149
+ 'user_email' => $results_data->email,
150
+ 'user_phone' => $results_data->phone,
151
+ 'user_id' => $results_data->user,
152
+ 'timer' => $results[0],
153
+ 'time_taken' => $results_data->time_taken,
154
+ 'total_points' => $results_data->point_score,
155
+ 'total_score' => $results_data->correct_score,
156
+ 'total_correct' => $results_data->correct,
157
+ 'total_questions' => $results_data->total,
158
+ 'comments' => $results[2],
159
+ 'question_answers_array' => $results[1],
160
+ 'contact' => $results["contact"],
161
+ 'results' => $results,
162
+ );
163
+
164
+ $mlwQuizMasterNext->pluginHelper->prepare_quiz($results_data->quiz_id);
165
+ $sharing_page_id = qsm_get_post_id_from_quiz_id($results_data->quiz_id);
166
+
167
+ //Fb share description
168
+ $sharing = $mlwQuizMasterNext->pluginHelper->get_section_setting('quiz_text', 'facebook_sharing_text', '');
169
+ $sharing = apply_filters('mlw_qmn_template_variable_results_page', $sharing, $results_array);
170
+ $default_fb_image = QSM_PLUGIN_URL . 'assets/icon-200x200.png';
171
+ $get_fb_sharing_image = $mlwQuizMasterNext->pluginHelper->get_section_setting('quiz_text', 'result_page_fb_image', '');
172
+ if ($get_fb_sharing_image !== '') {
173
+ $default_fb_image = $get_fb_sharing_image;
174
+ }
175
+ $post = $wp_query->get_queried_object();
176
+ $pagename = $post->post_title;
177
+ ?>
178
+ <meta property="og:url" content="<?php echo $sharing_page_id . '?result_id=' . $_GET['result_id']; ?>" />
179
+ <meta property="og:type" content="article" />
180
+ <meta property="og:title" content="<?php echo $pagename; ?>" />
181
+ <meta property="og:description" content="<?php echo $sharing; ?>" />
182
+ <meta property="og:image" content="<?php echo $default_fb_image; ?>" />
183
+ <meta property="fb:app_id" content="<?php echo $facebook_app_id; ?>" />
184
+ <?php
185
+ }
186
+ }
187
+ }
188
+
189
+ add_action('wp_head', 'qsm_generate_fb_header_metadata');
190
+
191
+
192
+ add_action('wp_head', 'qsm_check_script_error');
193
+
194
+ function qsm_check_script_error() {
195
+ if (is_singular('quiz')) {
196
+ ?>
197
+ <script src="<?php echo QSM_PLUGIN_URL . 'js/show-js-error.custom.js'; ?>"></script>
198
+ <link rel='stylesheet' href='<?php echo QSM_PLUGIN_URL . 'css/show-js-error.css'; ?>' type='text/css' media='all' />
199
+ <script>
200
+ //Display JS error
201
+ showJSError.init({
202
+ title: 'Javascript error detected by QSM Plugin',
203
+ copyText: 'Copy to clipboard',
204
+ sendText: 'Create Issue',
205
+ sendUrl: 'https://github.com/QuizandSurveyMaster/quiz_master_next/issues/new?title={title}&body={body}',
206
+ userAgent: navigator.userAgent,
207
+ helpLinks: true
208
+ });
209
+ </script>
210
+ <?php
211
+ }
212
+ }
213
+
214
+ /**
215
+ * @since QSM 6.4.6
216
+ * @param int $quiz_id
217
+ *
218
+ * Get the post id from quiz id
219
+ */
220
+ function qsm_get_post_id_from_quiz_id($quiz_id){
221
+ $args = array(
222
+ 'posts_per_page' => 1,
223
+ 'post_type' => 'quiz',
224
+ 'meta_query' => array(
225
+ array(
226
+ 'key' => 'quiz_id',
227
+ 'value' => $quiz_id,
228
+ 'compare' => '=',
229
+ ),
230
+ ),
231
+ );
232
+ $the_query = new WP_Query($args);
233
+
234
+ // The Loop
235
+ $post_permalink = '';
236
+ if ($the_query->have_posts()) {
237
+ while ($the_query->have_posts()) {
238
+ $the_query->the_post();
239
+ $post_permalink = get_the_permalink(get_the_ID());
240
+ }
241
+ /* Restore original Post Data */
242
+ wp_reset_postdata();
243
+ }
244
+ return $post_permalink;
245
+ }
php/template-variables.php CHANGED
@@ -132,8 +132,8 @@ function qsm_find_key_from_array($search_value,$array){
132
  /**
133
  * Adds Facebook sharing link using the %FACEBOOK_SHARE% variable
134
  */
135
- function qsm_variable_facebook_share( $content, $mlw_quiz_array ) {
136
- while ( false !== strpos($content, '%FACEBOOK_SHARE%') ) {
137
  wp_enqueue_script( 'qmn_quiz_social_share', plugins_url( '../../js/qmn_social_share.js' , __FILE__ ) );
138
  $settings = (array) get_option( 'qmn-settings' );
139
  $facebook_app_id = '483815031724529';
@@ -142,12 +142,13 @@ function qsm_variable_facebook_share( $content, $mlw_quiz_array ) {
142
  }
143
 
144
  global $mlwQuizMasterNext;
145
- $sharing = $mlwQuizMasterNext->pluginHelper->get_section_setting( 'quiz_text', 'facebook_sharing_text', '' );
146
-
147
- $sharing = apply_filters( 'mlw_qmn_template_variable_results_page', $sharing, $mlw_quiz_array);
148
- $fb_image = plugins_url('', dirname(__FILE__) ) . '/assets/facebook.png';
149
- $social_display = "<a class=\"mlw_qmn_quiz_link\" onclick=\"qmnSocialShare('facebook', '".esc_js( $sharing )."', '".esc_js($mlw_quiz_array["quiz_name"])."', '$facebook_app_id');\"><img src='". $fb_image ."' alt='Facebbok Share' /></a>";
150
- $content = str_replace( "%FACEBOOK_SHARE%" , $social_display, $content);
 
151
  }
152
  return $content;
153
  }
@@ -291,7 +292,7 @@ function mlw_qmn_variable_question_answers( $content, $mlw_quiz_array ) {
291
  global $mlwQuizMasterNext;
292
  global $wpdb;
293
  $display = '';
294
- $qmn_question_answer_template = $mlwQuizMasterNext->pluginHelper->get_section_setting( 'quiz_text', 'question_answer_template', '%QUESTION%<br>%USER_ANSWER%' );
295
  $questions = QSM_Questions::load_questions_by_pages( $mlw_quiz_array['quiz_id'] );
296
  $qmn_questions = array();
297
  foreach ( $questions as $question ) {
@@ -596,4 +597,42 @@ function qmn_variable_category_average_points($content, $mlw_quiz_array)
596
  }
597
  return $content;
598
  }
599
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
132
  /**
133
  * Adds Facebook sharing link using the %FACEBOOK_SHARE% variable
134
  */
135
+ function qsm_variable_facebook_share( $content, $mlw_quiz_array ) {
136
+ if ( false !== strpos($content, '%FACEBOOK_SHARE%') ) {
137
  wp_enqueue_script( 'qmn_quiz_social_share', plugins_url( '../../js/qmn_social_share.js' , __FILE__ ) );
138
  $settings = (array) get_option( 'qmn-settings' );
139
  $facebook_app_id = '483815031724529';
142
  }
143
 
144
  global $mlwQuizMasterNext;
145
+ $sharing = $mlwQuizMasterNext->pluginHelper->get_section_setting( 'quiz_text', 'facebook_sharing_text', '' );
146
+ $url = qsm_get_post_id_from_quiz_id($mlw_quiz_array['quiz_id']);
147
+ $page_link = $url . '?result_id=' . '%FB_RESULT_ID%';
148
+ $sharing = apply_filters( 'mlw_qmn_template_variable_results_page', $sharing, $mlw_quiz_array);
149
+ $fb_image = plugins_url('', dirname(__FILE__) ) . '/assets/facebook.png';
150
+ $social_display = "<a class=\"mlw_qmn_quiz_link\" onclick=\"qmnSocialShare('facebook', '".esc_js( $sharing )."', '".esc_js($mlw_quiz_array["quiz_name"])."', '$facebook_app_id', '$page_link');\"><img src='". $fb_image ."' alt='Facebbok Share' /></a>";
151
+ $content = str_replace( "%FACEBOOK_SHARE%" , $social_display, $content);
152
  }
153
  return $content;
154
  }
292
  global $mlwQuizMasterNext;
293
  global $wpdb;
294
  $display = '';
295
+ $qmn_question_answer_template = $mlwQuizMasterNext->pluginHelper->get_section_setting( 'quiz_text', 'question_answer_template', '%QUESTION%<br/>Answer Provided: %USER_ANSWER%<br/>Correct Answer: %CORRECT_ANSWER%<br/>Comments Entered: %USER_COMMENTS%' );
296
  $questions = QSM_Questions::load_questions_by_pages( $mlw_quiz_array['quiz_id'] );
297
  $qmn_questions = array();
298
  foreach ( $questions as $question ) {
597
  }
598
  return $content;
599
  }
600
+
601
+
602
+ add_filter('qmn_end_results', 'qsm_end_results_rank', 9999, 3);
603
+ function qsm_end_results_rank($result_display, $qmn_quiz_options, $qmn_array_for_variables)
604
+ {
605
+ global $wpdb;
606
+ $mlw_quiz_id = $qmn_array_for_variables['quiz_id'];
607
+ $mlw_result_id = $wpdb->get_var("SELECT MAX(`result_id`) FROM `{$wpdb->prefix}mlw_results` WHERE `quiz_id`='{$mlw_quiz_id}' AND `deleted`='0'");
608
+ $mlw_result_data = $wpdb->get_results("SELECT `result_id`, `correct_score`, `point_score`, `quiz_results` FROM `{$wpdb->prefix}mlw_results` WHERE `quiz_id`='{$mlw_quiz_id}' AND `deleted`='0'");
609
+ if (!empty($mlw_result_data)) {
610
+ foreach ($mlw_result_data as $key => $mlw_eaches) {
611
+ $time_taken = 0;
612
+ $mlw_qmn_results_array = @unserialize($mlw_eaches->quiz_results);
613
+ if (is_array($mlw_qmn_results_array)) {
614
+ $time_taken = $mlw_qmn_results_array[0];
615
+ if (isset($mlw_qmn_results_array['timer_ms']) && $mlw_qmn_results_array['timer_ms'] > 0) {
616
+ $time_taken = $mlw_qmn_results_array['timer_ms'];
617
+ } else {
618
+ $time_taken = ($time_taken * 1000);
619
+ }
620
+ }
621
+ $mlw_result_data[$key]->total_time_taken = $time_taken;
622
+ }
623
+ array_multisort(array_column($mlw_result_data, 'correct_score'), SORT_DESC, array_column($mlw_result_data, 'total_time_taken'), SORT_ASC, $mlw_result_data);
624
+ /**
625
+ * Find Rank
626
+ */
627
+ $rank = 0;
628
+ foreach ($mlw_result_data as $mlw_eaches) {
629
+ $rank++;
630
+ if ($mlw_eaches->result_id == $mlw_result_id) {
631
+ $mlw_rank = $rank;
632
+ }
633
+ }
634
+ }
635
+ $result_display = str_replace("%RANK%", $mlw_rank, $result_display);
636
+
637
+ return $result_display;
638
+ }
readme.txt CHANGED
@@ -2,9 +2,9 @@
2
  Contributors: quizsurvey,expresstech
3
  Tags: quiz, survey, lead, test, score, exam, questionnaire, question,wordpress quiz plugin
4
  Requires at least: 4.9
5
- Tested up to: 5.3.2
6
  Requires PHP: 5.4
7
- Stable tag: 6.4.5
8
  License: GPLv2
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
@@ -121,6 +121,17 @@ This is usually a theme conflict. You can [checkout out our common conflict solu
121
 
122
  == Changelog ==
123
 
 
 
 
 
 
 
 
 
 
 
 
124
  = 6.4.5 (March 16, 2020)=
125
  * Bug: Hint not readable
126
  * Bug: Full html of the option is being output in the ID of wrapper div and in the value of the option ( https://github.com/QuizandSurveyMaster/quiz_master_next/issues/849 )
2
  Contributors: quizsurvey,expresstech
3
  Tags: quiz, survey, lead, test, score, exam, questionnaire, question,wordpress quiz plugin
4
  Requires at least: 4.9
5
+ Tested up to: 5.4
6
  Requires PHP: 5.4
7
+ Stable tag: 6.4.7
8
  License: GPLv2
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
121
 
122
  == Changelog ==
123
 
124
+ = 6.4.7 (April 07, 2020)=
125
+ * Bug: Solved jquery UI error
126
+ * Bug: Customized text using the "Text tab" and remove from "Options Tab" for user is not logged in
127
+ * Bug: Fixed share Quizz's results on Social Media ( https://wordpress.org/support/topic/sharing-to-social-media/ )
128
+ * Bug: For polar question type added the validation while creating option
129
+ * Bug: Solved phone number field validation
130
+ * Bug: Solved User Dashboard addon issue for first row
131
+ * Feature: Special capabilities #810 ( https://github.com/QuizandSurveyMaster/quiz_master_next/issues/810 )
132
+ * Feature: Added Show JS Error library to show the JS Error in quiz page
133
+ * Feature: Changed type of quiz_results to MEDIUMTEXT (16M size) ( https://github.com/QuizandSurveyMaster/quiz_master_next/issues/522 )
134
+
135
  = 6.4.5 (March 16, 2020)=
136
  * Bug: Hint not readable
137
  * Bug: Full html of the option is being output in the ID of wrapper div and in the value of the option ( https://github.com/QuizandSurveyMaster/quiz_master_next/issues/849 )