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

Version Description

(May 21, 2018) = * Closed Enhancement: Add user ID to admin results page table - (Issue #682) * Closed Enhancement: Integrate with WordPress 4.9.6 GDPR features - (Issue #681)

Download this release

Release Info

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

Code changes from version 5.3.0 to 5.3.1

js/qmn_quiz.js CHANGED
@@ -88,7 +88,7 @@ var QSM;
88
  },
89
  from: {color: '#3498db'},
90
  to: {color: '#ED6A5A'},
91
- step: (state, bar) => {
92
  bar.setText(Math.round(bar.value() * 100) + ' %');
93
  }
94
  });
88
  },
89
  from: {color: '#3498db'},
90
  to: {color: '#ED6A5A'},
91
+ step: function(state, bar) {
92
  bar.setText(Math.round(bar.value() * 100) + ' %');
93
  }
94
  });
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: 5.3.0
6
  * Author: Frank Corso
7
  * Author URI: https://www.quizandsurveymaster.com/
8
  * Plugin URI: https://www.quizandsurveymaster.com/
9
  * Text Domain: quiz-master-next
10
  *
11
  * @author Frank Corso
12
- * @version 5.3.0
13
  * @package QSM
14
  */
15
 
@@ -33,7 +33,7 @@ class MLWQuizMasterNext {
33
  * @var string
34
  * @since 4.0.0
35
  */
36
- public $version = '5.3.0';
37
 
38
  /**
39
  * QSM Alert Manager Object
@@ -140,6 +140,7 @@ class MLWQuizMasterNext {
140
  include 'php/admin/settings-page.php';
141
  include 'php/classes/class-qsm-tracking.php';
142
  include 'php/classes/class-qmn-review-message.php';
 
143
  }
144
  include 'php/classes/class-qsm-questions.php';
145
  include 'php/classes/class-qsm-contact-manager.php';
2
  /**
3
  * Plugin Name: Quiz And Survey Master
4
  * Description: Easily and quickly add quizzes and surveys to your website.
5
+ * Version: 5.3.1
6
  * Author: Frank Corso
7
  * Author URI: https://www.quizandsurveymaster.com/
8
  * Plugin URI: https://www.quizandsurveymaster.com/
9
  * Text Domain: quiz-master-next
10
  *
11
  * @author Frank Corso
12
+ * @version 5.3.1
13
  * @package QSM
14
  */
15
 
33
  * @var string
34
  * @since 4.0.0
35
  */
36
+ public $version = '5.3.1';
37
 
38
  /**
39
  * QSM Alert Manager Object
140
  include 'php/admin/settings-page.php';
141
  include 'php/classes/class-qsm-tracking.php';
142
  include 'php/classes/class-qmn-review-message.php';
143
+ include 'php/gdpr.php';
144
  }
145
  include 'php/classes/class-qsm-questions.php';
146
  include 'php/classes/class-qsm-contact-manager.php';
php/admin/about-page.php CHANGED
@@ -51,6 +51,7 @@ function mlw_generate_about_page() {
51
  </div>
52
  <div class="qsm-tab-content tab-2" style="display: none;">
53
  <h2>Changelog</h2>
 
54
  <?php QSM_Changelog_Generator::get_changelog_list( 'fpcorso/quiz_master_next', 50 ); ?>
55
  </div>
56
  <div class="qsm-tab-content tab-3" style="display:none;">
51
  </div>
52
  <div class="qsm-tab-content tab-2" style="display: none;">
53
  <h2>Changelog</h2>
54
+ <?php QSM_Changelog_Generator::get_changelog_list( 'fpcorso/quiz_master_next', 51 ); ?>
55
  <?php QSM_Changelog_Generator::get_changelog_list( 'fpcorso/quiz_master_next', 50 ); ?>
56
  </div>
57
  <div class="qsm-tab-content tab-3" style="display:none;">
php/admin/admin-results-page.php CHANGED
@@ -318,6 +318,7 @@ function qsm_results_overview_tab_content() {
318
  <th><?php _e('Business','quiz-master-next'); ?></th>
319
  <th><?php _e('Email','quiz-master-next'); ?></th>
320
  <th><?php _e('Phone','quiz-master-next'); ?></th>
 
321
  <th><?php _e('Time Taken','quiz-master-next'); ?></th>
322
  <th><?php _e('IP Address','quiz-master-next'); ?></th>
323
  </tr>
@@ -368,6 +369,11 @@ function qsm_results_overview_tab_content() {
368
  $quotes_list .= "<td><span style='font-size:16px;'>" . $mlw_quiz_info->business ."</span></td>";
369
  $quotes_list .= "<td><span style='font-size:16px;'>" . $mlw_quiz_info->email ."</span></td>";
370
  $quotes_list .= "<td><span style='font-size:16px;'>" . $mlw_quiz_info->phone ."</span></td>";
 
 
 
 
 
371
  $date = date_i18n( get_option( 'date_format' ), strtotime( $mlw_quiz_info->time_taken ) );
372
  $time = date( "h:i:s A", strtotime( $mlw_quiz_info->time_taken ) );
373
  $quotes_list .= "<td><span style='font-size:16px;'>$date $time</span></td>";
318
  <th><?php _e('Business','quiz-master-next'); ?></th>
319
  <th><?php _e('Email','quiz-master-next'); ?></th>
320
  <th><?php _e('Phone','quiz-master-next'); ?></th>
321
+ <th><?php _e('User','quiz-master-next'); ?></th>
322
  <th><?php _e('Time Taken','quiz-master-next'); ?></th>
323
  <th><?php _e('IP Address','quiz-master-next'); ?></th>
324
  </tr>
369
  $quotes_list .= "<td><span style='font-size:16px;'>" . $mlw_quiz_info->business ."</span></td>";
370
  $quotes_list .= "<td><span style='font-size:16px;'>" . $mlw_quiz_info->email ."</span></td>";
371
  $quotes_list .= "<td><span style='font-size:16px;'>" . $mlw_quiz_info->phone ."</span></td>";
372
+ if ( 0 == $mlw_quiz_info->user ) {
373
+ $quotes_list .= "<td><span style='font-size:16px;'>Visitor</span></td>";
374
+ } else {
375
+ $quotes_list .= "<td><span style='font-size:16px;'><a href='user-edit.php?user_id=" . $mlw_quiz_info->user ."'>" . $mlw_quiz_info->user ."</a></span></td>";
376
+ }
377
  $date = date_i18n( get_option( 'date_format' ), strtotime( $mlw_quiz_info->time_taken ) );
378
  $time = date( "h:i:s A", strtotime( $mlw_quiz_info->time_taken ) );
379
  $quotes_list .= "<td><span style='font-size:16px;'>$date $time</span></td>";
php/admin/help-page.php CHANGED
@@ -16,7 +16,6 @@ function mlw_generate_help_page() {
16
 
17
  ///Creates the widgets
18
  add_meta_box("wpss_mrts", __('Need Help?', 'quiz-master-next'), "qsm_documentation_meta_box_content", "meta_box_help");
19
- add_meta_box("wpss_mrts", __('Support', 'quiz-master-next'), "qsm_support_meta_box_content", "meta_box_support");
20
  add_meta_box("wpss_mrts", __('System Info', 'quiz-master-next'), "qsm_system_meta_box_content", "meta_box_sys_info");
21
  ?>
22
  <div class="wrap">
@@ -24,15 +23,11 @@ function mlw_generate_help_page() {
24
  <?php echo mlw_qmn_show_adverts(); ?>
25
 
26
  <!--Display Widget Boxes-->
27
- <div style="float:left; width:50%;" class="inner-sidebar1">
28
  <?php do_meta_boxes('meta_box_help','advanced',''); ?>
29
  </div>
30
 
31
- <div style="float:left; width:50%;" class="inner-sidebar1">
32
- <?php do_meta_boxes('meta_box_support','advanced',''); ?>
33
- </div>
34
-
35
- <div style="float:left; width:100%;" class="inner-sidebar1">
36
  <?php do_meta_boxes('meta_box_sys_info','advanced',''); ?>
37
  </div>
38
 
@@ -51,117 +46,12 @@ function qsm_documentation_meta_box_content() {
51
  ?>
52
  <p><?php _e('Need help with the plugin? Try any of the following:', 'quiz-master-next'); ?></p>
53
  <ul>
54
- <li>For assistance in using the plugin, read our <a href="http://quizandsurveymaster.com/documentation/?utm_source=qsm-help-page&utm_medium=plugin&utm_campaign=qsm_plugin&utm_content=documentation" target="_blank">documentation</a> or view videos in our <a href="http://quizandsurveymaster.com/online-academy/?utm_source=qsm-help-page&utm_medium=plugin&utm_campaign=qsm_plugin&utm_content=online_academy" target="_blank">online academy</a></li>
55
- <li>For support, fill out the form in the Support widget to send us an email or fill out the form on our <a href="http://quizandsurveymaster.com/contact-us/?utm_source=qsm-help-page&utm_medium=plugin&utm_campaign=qsm_plugin&utm_content=contact_us" target="_blank">Contact Us Page</a></li>
56
  </ul>
57
  <?php
58
  }
59
 
60
- /**
61
- * This function creates the content that is displayed on the help page.
62
- *
63
- * @return void
64
- * @since 4.4.0
65
- */
66
- function qsm_support_meta_box_content() {
67
- $quiz_master_email_message = "";
68
- $mlw_quiz_version = get_option('mlw_quiz_master_version');
69
- if ( isset( $_POST["support_email"] ) && wp_verify_nonce( $_POST['send_support_ticket_nonce'], 'send_support_ticket') )
70
- {
71
- //These variables are not being be used in this site, they are being sent back to my open a support ticket form.
72
- $user_name = sanitize_text_field( $_POST["username"] );
73
- $user_email = sanitize_email( $_POST["email"] );
74
- $user_message = esc_textarea( $_POST["message"] );
75
- $user_quiz_url = esc_url_raw( $_POST["quiz_url"] );
76
- if ( !is_email( $user_email ) ) {
77
- $quiz_master_email_message = "Invalid email address";
78
- } else {
79
- $current_user = wp_get_current_user();
80
- $mlw_site_info = qsm_get_system_info();
81
- $mlw_message = "$user_message<br> Version: $mlw_quiz_version<br> Quiz URL Provided: $user_quiz_url<br> User ".$current_user->display_name." from ".$current_user->user_email."<br> Wordpress Info: $mlw_site_info";
82
- $response = wp_remote_post( "http://quizandsurveymaster.com/contact-us/", array(
83
- 'method' => 'POST',
84
- 'timeout' => 45,
85
- 'redirection' => 5,
86
- 'httpversion' => '1.0',
87
- 'blocking' => true,
88
- 'headers' => array(),
89
- 'body' => array(
90
- 'mlwUserName' => $user_name,
91
- 'mlwUserComp' => '',
92
- 'mlwUserEmail' => $user_email,
93
- 'question3' => 'Other',
94
- 'question72' => 'No',
95
- 'question2' => $mlw_message,
96
- 'qmn_question_list' => '3Q72Q2Q',
97
- 'total_questions' => 3,
98
- 'complete_quiz' => 'confirmation',
99
- 'qmn_quiz_id' => '1'
100
- ),
101
- 'cookies' => array()
102
- )
103
- );
104
- if ( is_wp_error( $response ) ) {
105
- $error_message = $response->get_error_message();
106
- $quiz_master_email_message = "Something went wrong: $error_message";
107
- } else {
108
- $quiz_master_email_message = "**Message Sent**";
109
- }
110
- }
111
- }
112
- ?>
113
- <script>
114
- function mlw_validateForm()
115
- {
116
- var x=document.forms['emailForm']['email'].value;
117
- if (x==null || x=='')
118
- {
119
- document.getElementById('mlw_support_message').innerHTML = '**Email must be filled out!**';
120
- return false;
121
- };
122
- var x=document.forms['emailForm']['username'].value;
123
- if (x==null || x=='')
124
- {
125
- document.getElementById('mlw_support_message').innerHTML = '**Name must be filled out!**';
126
- return false;
127
- };
128
- var x=document.forms['emailForm']['message'].value;
129
- if (x==null || x=='')
130
- {
131
- document.getElementById('mlw_support_message').innerHTML = '**There must be a message to send!**';
132
- return false;
133
- };
134
- var x=document.forms['emailForm']['email'].value;
135
- var atpos=x.indexOf('@');
136
- var dotpos=x.lastIndexOf('.');
137
- if (atpos<1 || dotpos<atpos+2 || dotpos+2>=x.length)
138
- {
139
- document.getElementById('mlw_support_message').innerHTML = '**Not a valid e-mail address!**';
140
- return false;
141
- }
142
- }
143
- </script>
144
- <div class='quiz_email_support'>
145
- <form action="" method='post' name='emailForm' onsubmit='return mlw_validateForm()'>
146
- <input type='hidden' name='support_email' value='confirmation' />
147
- <p><?php _e( 'We would love to hear from you. Fill out the form below and we will contact you shortly.', 'quiz-master-next' ); ?></p>
148
- <p name='mlw_support_message' id='mlw_support_message'><?php echo $quiz_master_email_message; ?></p>
149
- <label>Name (Required):</label><br />
150
- <input type='text' name='username' value='' /><br />
151
- <label>Email (Required):</label><br />
152
- <input type='text' name='email' value='' /><br />
153
- <label>URL To Quiz Or Survey (Not Required):</label><br />
154
- <input type='text' name='quiz_url' value='' /><br />
155
- <label>Message (Required):</label><br />
156
- <textarea name="message"></textarea><br />
157
- <?php wp_nonce_field('send_support_ticket','send_support_ticket_nonce'); ?>
158
- <input type='submit' class="button-primary" value='Submit Support Ticket' />
159
- </form>
160
- <p>Disclaimer: In order to better assist you, this form will also send the system info from below with your message.</p>
161
- </div>
162
- <?php
163
- }
164
-
165
  /**
166
  * This function echoes out the system info for the user.
167
  *
@@ -184,8 +74,13 @@ function qsm_get_system_info() {
184
 
185
  $sys_info = "";
186
 
187
- $theme_data = wp_get_theme();
188
- $theme = $theme_data->Name . ' ' . $theme_data->Version;
 
 
 
 
 
189
 
190
  $sys_info .= "<h3>Site Information</h3><br />";
191
  $sys_info .= "Site URL: ".site_url()."<br />";
@@ -195,7 +90,9 @@ function qsm_get_system_info() {
195
  $sys_info .= "<h3>WordPress Information</h3><br />";
196
  $sys_info .= "Version: ".get_bloginfo( 'version' )."<br />";
197
  $sys_info .= "Language: ".( defined( 'WPLANG' ) && WPLANG ? WPLANG : 'en_US' )."<br />";
 
198
  $sys_info .= "Active Theme: ".$theme."<br />";
 
199
  $sys_info .= "Debug Mode: ".( defined( 'WP_DEBUG' ) ? WP_DEBUG ? 'Enabled' : 'Disabled' : 'Not set' )."<br />";
200
  $sys_info .= "Memory Limit: ".WP_MEMORY_LIMIT."<br />";
201
 
16
 
17
  ///Creates the widgets
18
  add_meta_box("wpss_mrts", __('Need Help?', 'quiz-master-next'), "qsm_documentation_meta_box_content", "meta_box_help");
 
19
  add_meta_box("wpss_mrts", __('System Info', 'quiz-master-next'), "qsm_system_meta_box_content", "meta_box_sys_info");
20
  ?>
21
  <div class="wrap">
23
  <?php echo mlw_qmn_show_adverts(); ?>
24
 
25
  <!--Display Widget Boxes-->
26
+ <div style="width:100%;" class="inner-sidebar1">
27
  <?php do_meta_boxes('meta_box_help','advanced',''); ?>
28
  </div>
29
 
30
+ <div style="width:100%;" class="inner-sidebar1">
 
 
 
 
31
  <?php do_meta_boxes('meta_box_sys_info','advanced',''); ?>
32
  </div>
33
 
46
  ?>
47
  <p><?php _e('Need help with the plugin? Try any of the following:', 'quiz-master-next'); ?></p>
48
  <ul>
49
+ <li>For assistance in using the plugin, read our <a href="http://quizandsurveymaster.com/documentation/?utm_source=qsm-help-page&utm_medium=plugin&utm_campaign=qsm_plugin&utm_content=documentation" target="_blank">documentation</a> or view videos in our <a href="http://quizandsurveymaster.com/online-academy/?utm_source=qsm-help-page&utm_medium=plugin&utm_campaign=qsm_plugin&utm_content=online_academy" target="_blank">video tutorials</a></li>
50
+ <li>For support, fill out the form on our <a href="http://quizandsurveymaster.com/contact-us/?utm_source=qsm-help-page&utm_medium=plugin&utm_campaign=qsm_plugin&utm_content=contact_us" target="_blank">Contact Us Page</a></li>
51
  </ul>
52
  <?php
53
  }
54
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
55
  /**
56
  * This function echoes out the system info for the user.
57
  *
74
 
75
  $sys_info = "";
76
 
77
+ $theme_data = wp_get_theme();
78
+ $theme = $theme_data->Name . ' ' . $theme_data->Version;
79
+ $parent_theme = $theme_data->Template;
80
+ if ( ! empty( $parent_theme ) ) {
81
+ $parent_theme_data = wp_get_theme( $parent_theme );
82
+ $parent_theme = $parent_theme_data->Name . ' ' . $parent_theme_data->Version;
83
+ }
84
 
85
  $sys_info .= "<h3>Site Information</h3><br />";
86
  $sys_info .= "Site URL: ".site_url()."<br />";
90
  $sys_info .= "<h3>WordPress Information</h3><br />";
91
  $sys_info .= "Version: ".get_bloginfo( 'version' )."<br />";
92
  $sys_info .= "Language: ".( defined( 'WPLANG' ) && WPLANG ? WPLANG : 'en_US' )."<br />";
93
+ $sys_info .= 'Permalink Structure: ' . ( get_option( 'permalink_structure' ) ? get_option( 'permalink_structure' ) : 'Default' ) . '<br>';
94
  $sys_info .= "Active Theme: ".$theme."<br />";
95
+ $sys_info .= "Parent Theme: {$parent_theme}<br>";
96
  $sys_info .= "Debug Mode: ".( defined( 'WP_DEBUG' ) ? WP_DEBUG ? 'Enabled' : 'Disabled' : 'Not set' )."<br />";
97
  $sys_info .= "Memory Limit: ".WP_MEMORY_LIMIT."<br />";
98
 
php/classes/class-qsm-contact-manager.php CHANGED
@@ -107,8 +107,7 @@ class QSM_Contact_Manager {
107
  $class = '';
108
  $value = '';
109
  ?>
110
- <div class="qsm_contact_div">
111
- <span class='mlw_qmn_question qsm_question'><?php echo $fields[ $i ]['label']; ?></span>
112
  <?php
113
  if ( 'name' == $fields[ $i ]['use'] ) {
114
  $value = $name;
@@ -124,6 +123,7 @@ class QSM_Contact_Manager {
124
  $class = 'mlwRequiredText qsm_required_text';
125
  }
126
  ?>
 
127
  <input type='text' class='<?php echo esc_attr( $class ); ?>' x-webkit-speech name='contact_field_<?php echo $i; ?>' value='<?php echo esc_attr( $value ); ?>' />
128
  <?php
129
  break;
@@ -133,6 +133,7 @@ class QSM_Contact_Manager {
133
  $class = 'mlwRequiredText qsm_required_text';
134
  }
135
  ?>
 
136
  <input type='text' class='mlwEmail <?php echo esc_attr( $class ); ?>' x-webkit-speech name='contact_field_<?php echo $i; ?>' value='<?php echo esc_attr( $value ); ?>' />
137
  <?php
138
  break;
@@ -142,7 +143,8 @@ class QSM_Contact_Manager {
142
  $class = 'mlwRequiredAccept qsm_required_accept';
143
  }
144
  ?>
145
- <input type='checkbox' class='<?php echo esc_attr( $class ); ?>' x-webkit-speech name='contact_field_<?php echo $i; ?>' value='checked' />
 
146
  <?php
147
  break;
148
 
107
  $class = '';
108
  $value = '';
109
  ?>
110
+ <div class="qsm_contact_div qsm-contact-type-<?php echo esc_attr( $fields[ $i ]['type'] ); ?>">
 
111
  <?php
112
  if ( 'name' == $fields[ $i ]['use'] ) {
113
  $value = $name;
123
  $class = 'mlwRequiredText qsm_required_text';
124
  }
125
  ?>
126
+ <span class='mlw_qmn_question qsm_question'><?php echo $fields[ $i ]['label']; ?></span>
127
  <input type='text' class='<?php echo esc_attr( $class ); ?>' x-webkit-speech name='contact_field_<?php echo $i; ?>' value='<?php echo esc_attr( $value ); ?>' />
128
  <?php
129
  break;
133
  $class = 'mlwRequiredText qsm_required_text';
134
  }
135
  ?>
136
+ <span class='mlw_qmn_question qsm_question'><?php echo $fields[ $i ]['label']; ?></span>
137
  <input type='text' class='mlwEmail <?php echo esc_attr( $class ); ?>' x-webkit-speech name='contact_field_<?php echo $i; ?>' value='<?php echo esc_attr( $value ); ?>' />
138
  <?php
139
  break;
143
  $class = 'mlwRequiredAccept qsm_required_accept';
144
  }
145
  ?>
146
+ <input type='checkbox' id='contact_field_<?php echo $i; ?>' class='<?php echo esc_attr( $class ); ?>' x-webkit-speech name='contact_field_<?php echo $i; ?>' value='checked' />
147
+ <label class='mlw_qmn_question qsm_question' for='contact_field_<?php echo $i; ?>'><?php echo $fields[ $i ]['label']; ?></label>
148
  <?php
149
  break;
150
 
php/gdpr.php ADDED
@@ -0,0 +1,291 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file handles elements needed for GDPR. This requires WordPress 4.9.6 or later. This includes:
4
+ *
5
+ * 1. Privacy Policy
6
+ * 2. Data Exporter
7
+ * 3. Data Eraser
8
+ *
9
+ * @since 5.3.1
10
+ * @package QSM
11
+ */
12
+
13
+ // Add our actions and filters to functions below.
14
+ add_action( 'admin_init', 'qsm_register_suggested_privacy_content', 20 );
15
+ add_filter( 'wp_privacy_personal_data_exporters', 'qsm_register_data_exporters' );
16
+ add_filter( 'wp_privacy_personal_data_erasers', 'qsm_register_data_erasers' );
17
+
18
+ /**
19
+ * 1. Privacy Policy
20
+ */
21
+
22
+ /**
23
+ * Gets the suggested privacy policy content for this plugin
24
+ *
25
+ * @since 5.3.1
26
+ * @return string The HTML contect for the policy
27
+ */
28
+ function qsm_get_our_suggested_privacy_content() {
29
+ $content = '<p>' . __( 'Many of our quizzes, surveys, and forms are created using Quiz And Survey Master.', 'quiz-master-next' ) . '</p>';
30
+ $content .= '<h2>' . __( 'The data the software collects', 'quiz-master-next' ) . '</h2>';
31
+ $content .= '<p>' . __( 'In order to distinguish individual users, IP addresses are collected and stored with the responses.', 'quiz-master-next' ) . '</p>';
32
+ $content .= '<p>' . __( 'Each individual form may have fields for a variety of other personal information, such as name and email. This data is needed to identify and possibly communicate with the user. There may be other fields asking for personal information and this data may be for different purposes for each quiz, survey, or form. If any data is to be used for purposes other than grading or survey purposes, this will be disclosed on the form itself.', 'quiz-master-next' ) . '</p>';
33
+ $content .= '<h2>' . __( 'How long we retain your data', 'quiz-master-next' ) . '</h2>';
34
+ $content .= '<p>' . __( 'The responses and data attached to the responses are stored indefinitely until an administrator of this site deletes the responses.', 'quiz-master-next' ) . '</p>';
35
+ $content .= '<p>' . __( 'Change This! If you are using an addon or custom software to sync data with a 3rd party (such as MailChimp), data is retained there which should be mentioned here.', 'quiz-master-next' ) . '</p>';
36
+ $content .= '<h2>' . __( 'Where we send your data', 'quiz-master-next' ) . '</h2>';
37
+ $content .= '<p>' . __( 'Quiz And Survey Master does not send any of your data to anywhere outside of this site by default.', 'quiz-master-next' ) . '</p>';
38
+ $content .= '<p>' . __( 'Change This! If you are sharing the responses with anyone and do not list it anywhere else in your privacy policy, enter information about that here. ', 'quiz-master-next' ) . '</p>';
39
+ return $content;
40
+ }
41
+
42
+ /**
43
+ * Registers the suggested privacy policy content
44
+ *
45
+ * @since 5.3.1
46
+ */
47
+ function qsm_register_suggested_privacy_content() {
48
+ if ( function_exists( 'wp_add_privacy_policy_content' ) ) {
49
+ $content = qsm_get_our_suggested_privacy_content();
50
+ wp_add_privacy_policy_content( 'Quiz And Survey Master', $content );
51
+ }
52
+ }
53
+
54
+ /**
55
+ * 2. Data Exporter
56
+ */
57
+
58
+ /**
59
+ * Register the plugin's data exporter
60
+ *
61
+ * @since 5.3.1
62
+ * @param array $exporters The exporters registered for WordPress.
63
+ * @return array The exporters with ours appended.
64
+ */
65
+ function qsm_register_data_exporters( $exporters ) {
66
+ $exporters['quiz-master-next'] = array(
67
+ 'exporter_friendly_name' => 'Quiz And Survey Master',
68
+ 'callback' => 'qsm_data_exporter',
69
+ );
70
+ return $exporters;
71
+ }
72
+
73
+ /**
74
+ * Creates an array of all data for the user
75
+ *
76
+ * @see https://developer.wordpress.org/plugins/privacy/adding-the-personal-data-exporter-to-your-plugin/
77
+ *
78
+ * @since 5.3.1
79
+ * @param string $email The email of the user who wants to export his or her data.
80
+ * @param int $page The page we are on in the exporting.
81
+ * @return array The data for the export
82
+ */
83
+ function qsm_data_exporter( $email, $page = 1 ) {
84
+
85
+ // Sets up variables.
86
+ global $wpdb;
87
+ $export_items = array();
88
+ $done = false;
89
+ $user = get_user_by( 'email', $email );
90
+ $group_id = 'qsm-form-response';
91
+ $group_label = __( 'Form Responses', 'quiz-master-next' );
92
+
93
+ // Prepare SQL for finding by user.
94
+ $user_sql = '';
95
+ if ( $user && isset( $user->ID ) && 0 !== $user->ID ) {
96
+ $user_sql = "user = {$user->ID} OR ";
97
+ }
98
+
99
+ // Calculate query range.
100
+ $total = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(result_id) FROM {$wpdb->prefix}mlw_results WHERE $user_sql email = '%s'", $email ) );
101
+ $per_page = 25;
102
+ $begin = $per_page * ( $page - 1 );
103
+ $remaining = $total - ( $page * $per_page );
104
+
105
+ // Get the results.
106
+ $results = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}mlw_results WHERE $user_sql email = '%s' ORDER BY result_id DESC LIMIT %d, %d", $email, $begin, $per_page ) );
107
+
108
+ // Cycle through adding to array.
109
+ foreach ( $results as $result ) {
110
+ // Set the ID.
111
+ $item_id = 'qsm-form-response-' . $result->result_id;
112
+
113
+ // Prepares our results array.
114
+ if ( is_serialized( $result->quiz_results ) ) {
115
+ $results_array = @unserialize( $result->quiz_results );
116
+ if ( is_array( $results_array ) ) {
117
+ if ( ! isset( $results['contact'] ) ) {
118
+ $results['contact'] = array();
119
+ }
120
+ }
121
+ }
122
+ if ( ! is_array( $results_array ) ) {
123
+ $results_array = array(
124
+ 0,
125
+ array(),
126
+ '',
127
+ 'contact' => array(),
128
+ );
129
+ }
130
+
131
+ // Create the data array.
132
+ $data = array(
133
+ array(
134
+ 'name' => __( 'Form Name', 'quiz-master-next' ),
135
+ 'value' => $result->quiz_name,
136
+ ),
137
+ array(
138
+ 'name' => __( 'Time Submitted', 'quiz-master-next' ),
139
+ 'value' => $result->time_taken,
140
+ ),
141
+ array(
142
+ 'name' => __( 'Points Earned', 'quiz-master-next' ),
143
+ 'value' => $result->point_score,
144
+ ),
145
+ array(
146
+ 'name' => __( 'Score Earned', 'quiz-master-next' ),
147
+ 'value' => $result->correct_score,
148
+ ),
149
+ array(
150
+ 'name' => __( 'Questions Answered Correctly', 'quiz-master-next' ),
151
+ 'value' => $result->correct,
152
+ ),
153
+ array(
154
+ 'name' => __( 'Total Questions', 'quiz-master-next' ),
155
+ 'value' => $result->total,
156
+ ),
157
+ array(
158
+ 'name' => __( 'Name Field', 'quiz-master-next' ),
159
+ 'value' => $result->name,
160
+ ),
161
+ array(
162
+ 'name' => __( 'Business Field', 'quiz-master-next' ),
163
+ 'value' => $result->business,
164
+ ),
165
+ array(
166
+ 'name' => __( 'Email Field', 'quiz-master-next' ),
167
+ 'value' => $result->email,
168
+ ),
169
+ array(
170
+ 'name' => __( 'Phone Field', 'quiz-master-next' ),
171
+ 'value' => $result->phone,
172
+ ),
173
+ array(
174
+ 'name' => __( 'User ID', 'quiz-master-next' ),
175
+ 'value' => $result->user,
176
+ ),
177
+ array(
178
+ 'name' => __( 'IP Address', 'quiz-master-next' ),
179
+ 'value' => $result->user_ip,
180
+ ),
181
+ array(
182
+ 'name' => __( 'Time to complete form', 'quiz-master-next' ),
183
+ 'value' => $results_array[0] . ' seconds',
184
+ ),
185
+ array(
186
+ 'name' => __( 'Form comments', 'quiz-master-next' ),
187
+ 'value' => $results_array[2],
188
+ ),
189
+ );
190
+
191
+ // Adds contact fields.
192
+ $contact_count = count( $results_array['contact'] );
193
+ for ( $i = 0; $i < $contact_count; $i++ ) {
194
+ $data[] = array(
195
+ 'name' => $results_array['contact'][ $i ]['label'],
196
+ 'value' => $results_array['contact'][ $i ]['value'],
197
+ );
198
+ }
199
+
200
+ // Adds all answer data.
201
+ foreach ( $results_array[1] as $question ) {
202
+ $data[] = array(
203
+ 'name' => $question[0],
204
+ 'value' => "Answer: {$question[1]}. Comments: {$question[3]}",
205
+ );
206
+ }
207
+
208
+ // Add to export array.
209
+ $export_items[] = array(
210
+ 'group_id' => $group_id,
211
+ 'group_label' => $group_label,
212
+ 'item_id' => $item_id,
213
+ 'data' => $data,
214
+ );
215
+ }
216
+
217
+ if ( 0 >= $remaining ) {
218
+ $done = true;
219
+ }
220
+
221
+ return array(
222
+ 'data' => $export_items,
223
+ 'done' => $done,
224
+ );
225
+ }
226
+
227
+ /**
228
+ * 3. Data Eraser
229
+ */
230
+
231
+ /**
232
+ * Register the plugin's data eraser
233
+ *
234
+ * @since 5.3.1
235
+ * @param array $erasers The erasers registered for WordPress.
236
+ * @return array The erasers with ours appended.
237
+ */
238
+ function qsm_register_data_erasers( $erasers ) {
239
+ $erasers['quiz-master-next'] = array(
240
+ 'eraser_friendly_name' => 'Quiz And Survey Master',
241
+ 'callback' => 'qsm_data_eraser',
242
+ );
243
+ return $erasers;
244
+ }
245
+
246
+ /**
247
+ * Erases all data for the user
248
+ *
249
+ * @see https://developer.wordpress.org/plugins/privacy/adding-the-personal-data-eraser-to-your-plugin/
250
+ *
251
+ * @since 5.3.1
252
+ * @param string $email The email of the user who wants to erase his or her data.
253
+ * @param int $page The page we are on in the erasing.
254
+ * @return array The status of erasing the data
255
+ */
256
+ function qsm_data_eraser( $email, $page = 1 ) {
257
+
258
+ // Sets up variables.
259
+ global $wpdb;
260
+ $items_removed = false;
261
+ $user = get_user_by( 'email', $email );
262
+
263
+ // Deletes all results attached to user.
264
+ $user_sql = '';
265
+ if ( $user && isset( $user->ID ) && 0 !== $user->ID ) {
266
+ $user_count = $wpdb->delete(
267
+ "{$wpdb->prefix}mlw_results",
268
+ array( 'user' => $user->ID )
269
+ );
270
+ }
271
+
272
+ // Deletes all results attached email address not attached to user.
273
+ $email_count = $wpdb->delete(
274
+ "{$wpdb->prefix}mlw_results",
275
+ array( 'email' => $email )
276
+ );
277
+
278
+ // If we deleted any, then set removed to true.
279
+ $total = intval( $user_count ) + intval( $email_count );
280
+ if ( 0 < $total ) {
281
+ $items_removed = true;
282
+ }
283
+
284
+ // Needed array to be returned.
285
+ return array(
286
+ 'items_removed' => $items_removed,
287
+ 'items_retained' => false,
288
+ 'messages' => array(),
289
+ 'done' => true,
290
+ );
291
+ }
readme.txt CHANGED
@@ -4,7 +4,7 @@ Tags: quiz, survey, lead, test, score, exam, questionnaire, question
4
  Requires at least: 4.8
5
  Tested up to: 4.9
6
  Requires PHP: 5.2
7
- Stable tag: 5.3.0
8
  License: GPLv2
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
@@ -111,6 +111,10 @@ This is usually a theme conflict. You can [checkout out our common conflict solu
111
 
112
  == Changelog ==
113
 
 
 
 
 
114
  = 5.3.0 (May 16, 2018) =
115
  * Closed Enhancement: Ability to disable IP address collection - ([Issue #670](https://github.com/fpcorso/quiz_master_next/issues/670))
116
  * Closed User Request: Ability to customize name of QSM archive name - ([Issue #666](https://github.com/fpcorso/quiz_master_next/issues/666))
@@ -122,5 +126,5 @@ This is usually a theme conflict. You can [checkout out our common conflict solu
122
 
123
  == Upgrade Notice ==
124
 
125
- = 5.3.0 =
126
- Update for new features including progress bar, the ability to disable IP collection, and more!
4
  Requires at least: 4.8
5
  Tested up to: 4.9
6
  Requires PHP: 5.2
7
+ Stable tag: 5.3.1
8
  License: GPLv2
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
111
 
112
  == Changelog ==
113
 
114
+ = 5.3.1 (May 21, 2018) =
115
+ * Closed Enhancement: Add user ID to admin results page table - ([Issue #682](https://github.com/fpcorso/quiz_master_next/issues/682))
116
+ * Closed Enhancement: Integrate with WordPress 4.9.6 GDPR features - ([Issue #681](https://github.com/fpcorso/quiz_master_next/issues/681))
117
+
118
  = 5.3.0 (May 16, 2018) =
119
  * Closed Enhancement: Ability to disable IP address collection - ([Issue #670](https://github.com/fpcorso/quiz_master_next/issues/670))
120
  * Closed User Request: Ability to customize name of QSM archive name - ([Issue #666](https://github.com/fpcorso/quiz_master_next/issues/666))
126
 
127
  == Upgrade Notice ==
128
 
129
+ = 5.3.1 =
130
+ Update for integrations with WordPress 4.9.6 GDPR features
templates/qmn_amethyst.css CHANGED
@@ -101,8 +101,17 @@
101
  margin: 0 0 5px 0;
102
  font-weight: bold;
103
  -webkit-box-sizing: border-box;
104
- -moz-box-sizing: border-box;
105
- box-sizing: border-box;
 
 
 
 
 
 
 
 
 
106
  }
107
 
108
  label.inline,
101
  margin: 0 0 5px 0;
102
  font-weight: bold;
103
  -webkit-box-sizing: border-box;
104
+ -moz-box-sizing: border-box;
105
+ box-sizing: border-box;
106
+ }
107
+
108
+ .qsm_contact_div {
109
+ margin: 10px 0;
110
+ }
111
+
112
+ .quiz_section .qsm-contact-type-checkbox label,
113
+ .quiz_section .qsm-contact-type-checkbox input {
114
+ display: inline;
115
  }
116
 
117
  label.inline,
templates/qmn_base.css CHANGED
@@ -105,6 +105,15 @@
105
  box-sizing: border-box;
106
  }
107
 
 
 
 
 
 
 
 
 
 
108
  label.inline,
109
  label.inline .mlw_qmn_question,
110
  .quiz_section.inline .mlw_horizontal_multiple {
105
  box-sizing: border-box;
106
  }
107
 
108
+ .qsm_contact_div {
109
+ margin: 10px 0;
110
+ }
111
+
112
+ .quiz_section .qsm-contact-type-checkbox label,
113
+ .quiz_section .qsm-contact-type-checkbox input {
114
+ display: inline;
115
+ }
116
+
117
  label.inline,
118
  label.inline .mlw_qmn_question,
119
  .quiz_section.inline .mlw_horizontal_multiple {
templates/qmn_emerald.css CHANGED
@@ -104,6 +104,15 @@
104
  box-sizing: border-box;
105
  }
106
 
 
 
 
 
 
 
 
 
 
107
  label.inline,
108
  label.inline .mlw_qmn_question,
109
  .quiz_section.inline .mlw_horizontal_multiple {
104
  box-sizing: border-box;
105
  }
106
 
107
+ .qsm_contact_div {
108
+ margin: 10px 0;
109
+ }
110
+
111
+ .quiz_section .qsm-contact-type-checkbox label,
112
+ .quiz_section .qsm-contact-type-checkbox input {
113
+ display: inline;
114
+ }
115
+
116
  label.inline,
117
  label.inline .mlw_qmn_question,
118
  .quiz_section.inline .mlw_horizontal_multiple {
templates/qmn_gray.css CHANGED
@@ -105,6 +105,15 @@
105
  box-sizing: border-box;
106
  }
107
 
 
 
 
 
 
 
 
 
 
108
  label.inline,
109
  label.inline .mlw_qmn_question,
110
  .quiz_section.inline .mlw_horizontal_multiple {
105
  box-sizing: border-box;
106
  }
107
 
108
+ .qsm_contact_div {
109
+ margin: 10px 0;
110
+ }
111
+
112
+ .quiz_section .qsm-contact-type-checkbox label,
113
+ .quiz_section .qsm-contact-type-checkbox input {
114
+ display: inline;
115
+ }
116
+
117
  label.inline,
118
  label.inline .mlw_qmn_question,
119
  .quiz_section.inline .mlw_horizontal_multiple {
templates/qmn_primary.css CHANGED
@@ -105,6 +105,15 @@
105
  box-sizing: border-box;
106
  }
107
 
 
 
 
 
 
 
 
 
 
108
  label.inline,
109
  label.inline .mlw_qmn_question,
110
  .quiz_section.inline .mlw_horizontal_multiple {
105
  box-sizing: border-box;
106
  }
107
 
108
+ .qsm_contact_div {
109
+ margin: 10px 0;
110
+ }
111
+
112
+ .quiz_section .qsm-contact-type-checkbox label,
113
+ .quiz_section .qsm-contact-type-checkbox input {
114
+ display: inline;
115
+ }
116
+
117
  label.inline,
118
  label.inline .mlw_qmn_question,
119
  .quiz_section.inline .mlw_horizontal_multiple {
templates/qmn_turquoise.css CHANGED
@@ -105,6 +105,15 @@
105
  box-sizing: border-box;
106
  }
107
 
 
 
 
 
 
 
 
 
 
108
  label.inline,
109
  label.inline .mlw_qmn_question,
110
  .quiz_section.inline .mlw_horizontal_multiple {
105
  box-sizing: border-box;
106
  }
107
 
108
+ .qsm_contact_div {
109
+ margin: 10px 0;
110
+ }
111
+
112
+ .quiz_section .qsm-contact-type-checkbox label,
113
+ .quiz_section .qsm-contact-type-checkbox input {
114
+ display: inline;
115
+ }
116
+
117
  label.inline,
118
  label.inline .mlw_qmn_question,
119
  .quiz_section.inline .mlw_horizontal_multiple {